Home  >  Article  >  Backend Development  >  Python-based interface testing framework example

Python-based interface testing framework example

高洛峰
高洛峰Original
2017-02-22 11:08:001653browse

Background

Recently, the company is doing message push, so naturally many interfaces will be generated. During the test process, the interface needs to be called. I suddenly thought if I could do it myself Write a testing framework?

Just do it. Since the existing interface testing tools Jmeter, SoupUI and other learning cycles are a bit long, you might as well write one yourself. You don’t need anyone else, and you can know all the functions clearly.

Of course, writing tools and making wheels is just a way of learning. Ready-made and mature tools are definitely easier to use than those we write ourselves.

Development environment

------------------------------------------ --------------------------

Operating system: Mac OS X EI Caption

Python version: 2.7

IDE: Pycharm

------------------------------------------------ -------------------------

analyze

The interface is based on the HTTP protocol, so to put it bluntly, just initiate an HTTP request. For Python, it is a piece of cake. You can easily complete the task by using requests directly.

Architecture

The entire framework is relatively small and involves relatively few things. You only need to clearly distinguish the functions of several modules.

Python-based interface testing framework example

#The above is a complete process of interface testing. Just take it step by step, it's not difficult.

Data source

I use JSON to save the data source. Of course, the more common way is to use Excel to save, and use JSON to save it. I saved it because JSON is more convenient to use and I am too lazy to read Excel. Python’s support for JSON is very friendly. Of course, this depends on personal preference.

{
  "TestId": "testcase004",
  "Method": "post",
  "Title": "单独推送消息",
  "Desc": "单独推送消息",
  "Url": "http://xxx.xxx.xxx.xx",
  "InputArg": {
   "action": "44803",
   "account": "1865998xxxx",
   "uniqueid": "00D7C889-06A0-426E-BAB1-5741A1192038",
   "title": "测试测试",
   "summary": "豆豆豆",
   "message": "12345",
   "msgtype": "25",
   "menuid": "203"
  },
  "Result": {
   "errorno": "0"
  }
 }

The example is shown in the code above and can be adjusted according to personal business needs.

Send a request

Sending a request is very simple, use the requests module, and then read the sent parameters from JSON, post, get or other. Since a test report needs to be generated, the data sent needs to be recorded. I chose to use txt text as the recording container.

f = file("case.json")
testData = json.load(f)
f.close()


def sendData(testData, num):
  payload = {}
  # 从json中获取发送参数
  for x in testData[num]['InputArg'].items():
    payload[x[0]] = x[1]
  with open('leftside.txt', 'a+') as f:
    f.write(testData[num]['TestId'])
    f.write('-')
    f.write(testData[num]['Title'])
    f.write('\n')

  # 发送请求
  data = requests.get(testData[num]['Url'], params=payload)
  r = data.json()

Accept return

Since we need to generate a test report, then return We need to store the data first. We can choose to use a database to store it, but I think database storage is too troublesome. Just use txt text as a storage container.

with open('rightside.txt', 'a+') as rs:
    rs.write('发送数据')
    rs.write('|')
    rs.write('标题:'+testData[num]['Title'])
    rs.write('|')
    rs.write('发送方式:'+testData[num]['Method'])
    rs.write('|')
    rs.write('案例描述:'+testData[num]['Desc'])
    rs.write('|')
    rs.write('发送地址:'+testData[num]['Url'])
    rs.write('|')
    rs.write('发送参数:'+str(payload).decode("unicode-escape").encode("utf-8").replace("u\'","\'"))
    rs.write('|')
    rs.write(testData[num]['TestId'])
    rs.write('\n')

Result Determination

The result determination I use is equal to the determination. Because our interface only needs to be processed in this way, if necessary, it can be written as a regular judgment.

with open('result.txt', 'a+') as rst:
    rst.write('返回数据')
    rst.write('|')
    for x, y in r.items():
      rst.write(' : '.join([x, y]))
      rst.write('|')
    # 写测试结果
    try:
      if cmp(r, testData[num]['Result']) == 0:
        rst.write('pass')
      else:
        rst.write('fail')
    except Exception:
      rst.write('no except result')
    rst.write('\n')

There are three types of results here, success, failure or no result. The setting of the result depends on your own definition.

Generate test report

The test report is a highlight. Since I send data, return data and results are all stored in txt text, then every time I use a+ mode, it will be new. If it increases, there will be more and more results, and it will be very painful to check.

My way of handling it is to use Python to read the data in the txt text after each test, then use Django to dynamically generate a result, and then use requests to crawl the web page and save it in the Report folder. .

Web Page Report

I won’t go into details about Django’s method, there is already a whole series of articles on the blog. We need to open the three previously recorded txt files in the views file, then do some data processing and return them to the front end. The front end uses Bootstrap to render them to generate a more beautiful test report.

def index(request):
  rightside = []
  result = []
  rst_data = []
  leftside = []
  passed = 0
  fail = 0
  noresult = 0
  with open(os.getcwd() + '/PortTest/leftside.txt') as ls:
    for x in ls.readlines():
      lf_data = {
        'code': x.strip().split('-')[0],
        'title': x.strip().split('-')[1]
      }
      leftside.append(lf_data)

  with open(os.getcwd() + '/PortTest/rightside.txt') as rs:
    for x in rs.readlines():
      row = x.strip().split('|')
      rs_data = {
        "fssj": row[0],
        "csbt": row[1],
        "fsfs": row[2],
        "alms": row[3],
        "fsdz": row[4],
        "fscs": row[5],
        'testid': row[6]
      }
      rightside.append(rs_data)

  with open(os.getcwd() + '/PortTest/result.txt') as rst:
    for x in rst.readlines():
      row = x.strip().split('|')
      if row[len(row)-1] == 'fail':
        fail += 1
      elif row[len(row)-1] == 'pass':
        passed += 1
      elif row[len(row)-1] == 'no except result':
        noresult += 1

      rs_data = []
      for y in row:
        rs_data.append(y)
      result.append(rs_data)
  for a, b in zip(rightside, result):
    data = {
      "sendData": a,
      "dealData": b,
      "result": b[len(b)-1]
    }
    rst_data.append(data)
  return render(request, 'PortTest/index.html', {"leftside": leftside,
                          "rst_data": rst_data,
                          "pass": passed,
                          "fail": fail,
                          "noresult": noresult})

Basically some very basic knowledge, string segmentation and so on. For the convenience of data processing here, when obtaining data storage, it must be stored in a certain format, and the views method is easy to process.

The front-end code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link href="http://jb51.net/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
  <script src="http://jb51.net/jquery/2.0.0/jquery.min.js"></script>
  <script src="http://jb51.net/bootstrap/3.0.3/js/bootstrap.min.js"></script>
</head>
<body>
<p class="container">
  <p class="row">
    <p class="page-header">
      <h1>接口测试报告
        <small>Design By Sven</small>
      </h1>
    </p>
  </p>
  <p class="row">
    <p class="col-md-4">
      <h3>测试通过 <span class="label label-success">{{ pass }}</span></h3>
    </p>
    <p class="col-md-4">
      <h3>测试失败 <span class="label label-danger">{{ fail }}</span></h3>
    </p>
    <p class="col-md-4">
      <h3>无结果 <span class="label label-warning">{{ noresult }}</span></h3>
    </p>
  </p>
  <p></p>
  <p class="row">
    <p class="col-md-3">
      <ul class="list-group">
        {% for ls in leftside %}
          <li class="list-group-item"><a href="#{{ ls.code }}">{{ ls.code }} - {{ ls.title }}</a></li>
        {% endfor %}
      </ul>
    </p>
    <p class="col-md-9">
      {{ x.result }}
      {% for x in rst_data %}
        <p class="panel-group" id="accordion">
        {% if x.result == &#39;pass&#39; %}
          <p class="panel panel-success">
        {% elif x.result == &#39;fail&#39; %}
          <p class="panel panel-danger">
        {% elif x.result == &#39;no except result&#39; %}
          <p class="panel panel-warning">
        {% endif %}

      <p class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" href="#{{ x.sendData.testid }}">
            {{ x.sendData.testid }} - {{ x.sendData.csbt }}
          </a>
        </h4>
      </p>
      <p id="{{ x.sendData.testid }}" class="panel-collapse collapse">
        <p class="panel-body">
          <b>{{ x.sendData.fssj }}</b><br>
          {{ x.sendData.csbt }}<br>
          {{ x.sendData.fsfs }}<br>
          {{ x.sendData.alms }}<br>
          {{ x.sendData.fsdz }}<br>
          {{ x.sendData.fscs }}
          <hr>
          {% for v in x.dealData %}
            {{ v }}<br>
          {% endfor %}
        </p>
      </p>
      </p>
      </p>
        <p></p>
      {% endfor %}
      </p>
      </p>
    </p>
    <script>
      $(function () {
        $(window).scroll(function () {
          if ($(this).scrollTop() != 0) {
            $("#toTop").fadeIn();
          } else {
            $("#toTop").fadeOut();
          }
        });
        $("body").append("<p id=\"toTop\" style=\"border:1px solid #444;background:#333;color:#fff;text-align:center;padding:10px 13px 7px 13px;position:fixed;bottom:10px;right:10px;cursor:pointer;display:none;font-family:verdana;font-size:22px;\">^</p>");
        $("#toTop").click(function () {
          $("body,html").animate({scrollTop: 0}, 800);
        });
      });
    </script>
</body>
</html>

Test report renderings

Python-based interface testing framework example

Finally

It is easy to write a tool in Python, but the main purpose is to more conveniently meet the needs of actual work. If you want to do a complete interface test, try to use mature tools.

PS: Simply making wheels is also an excellent way to learn the principles.

The above example of the interface testing framework based on Python is all the content shared by the editor. I hope it can give you a reference, and I hope you will support the PHP Chinese website.

For more articles related to Python-based interface testing framework examples, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn