Heim  >  Artikel  >  Backend-Entwicklung  >  Beispiel für ein Python-basiertes Schnittstellentest-Framework

Beispiel für ein Python-basiertes Schnittstellentest-Framework

高洛峰
高洛峰Original
2017-02-22 11:08:001660Durchsuche

Hintergrund

In letzter Zeit führt das Unternehmen Push-Nachrichten durch, daher wird es natürlich viele Schnittstellen geben, die ich plötzlich aufrufen muss Ich dachte, ich könnte es selbst tun. Ein Test-Framework schreiben?

Machen Sie es einfach. Da die vorhandenen Schnittstellentest-Tools wie Jmeter und SoupUI einen langen Lernzyklus haben, können Sie auch selbst eines schreiben und alle Funktionen verstehen alleine.

Natürlich sind Schreibwerkzeuge und der Bau von Rädern nur eine Möglichkeit zum Lernen. Vorgefertigte und ausgereifte Werkzeuge sind definitiv einfacher zu verwenden als unsere eigenen.

Entwicklungsumgebung

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

Betriebssystem: Mac OS X EI Caption

Python-Version: 2.7

IDE: Pycharm

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

Analyse

Die Schnittstelle basiert auf dem HTTP-Protokoll. Um es ganz klar auszudrücken: Initiieren Sie einfach eine HTTP-Anfrage. Für Python ist es ein Kinderspiel. Sie können die Aufgabe ganz einfach erledigen, indem Sie Anfragen direkt verwenden.

Architektur

Das gesamte Framework ist relativ klein und umfasst relativ wenige Dinge. Sie müssen nur die Funktionen mehrerer Module klar unterscheiden.

Beispiel für ein Python-basiertes Schnittstellentest-Framework

Das Obige ist ein vollständiger Prozess des Schnittstellentests. Gehen Sie es einfach Schritt für Schritt an, es ist nicht schwierig.

Datenquelle

Ich verwende JSON zum Speichern der Datenquelle. Natürlich ist es üblicher, Excel zum Speichern und JSON zu verwenden Ich habe es gespeichert, weil JSON bequemer zu verwenden ist und ich zu faul bin, die Unterstützung von Excel für JSON zu lesen. Dies hängt natürlich von den persönlichen Vorlieben ab.

{
  "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"
  }
 }

Das Beispiel ist im obigen Code dargestellt und kann je nach persönlichen Geschäftsanforderungen angepasst werden.

Eine Anfrage senden

Das Senden einer Anfrage ist sehr einfach: Verwenden Sie das Anfragemodul und lesen Sie dann die gesendeten Parameter aus JSON, posten, bekommen Oder etwas anderes. Da ein Testbericht erstellt werden muss, müssen die gesendeten Daten aufgezeichnet werden. Ich habe mich für die Verwendung von TXT-Text als Aufzeichnungscontainer entschieden.

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()

Rückgabe akzeptieren

Da wir einen Testbericht erstellen müssen, Dann müssen wir zuerst die zurückgegebenen Daten speichern. Wir können uns dafür entscheiden, sie in einer Datenbank zu speichern, aber ich denke, dass die Datenbankspeicherung zu mühsam ist. Verwenden Sie einfach TXT-Text als Speichercontainer.

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')

Ergebnisbestimmung

Die von mir verwendete Ergebnisbestimmung entspricht der Bestimmung. Da unsere Schnittstelle bei Bedarf nur auf diese Weise verarbeitet werden muss, kann sie als reguläres Urteil geschrieben werden.

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')

Ich habe hier drei Ergebnisse: Erfolg, Misserfolg oder kein Ergebnis. Die Einstellung des Ergebnisses hängt von Ihrer eigenen Definition ab.

Testbericht erstellen

Der Testbericht ist ein Highlight, da ich Daten sende, Rückgabedaten und Ergebnisse alle im TXT-Text gespeichert werden, und zwar jedes Mal, wenn ich a+ verwende Im Modus wird es neu sein. Wenn es zunimmt, werden immer mehr Ergebnisse angezeigt, und die Überprüfung wird sehr schmerzhaft sein.

Meine Art, damit umzugehen, besteht darin, Python zu verwenden, um die Daten im TXT-Text nach jedem Test zu lesen, dann Django zu verwenden, um dynamisch ein Ergebnis zu generieren, und dann Anfragen zu verwenden, um die Webseite zu crawlen und im zu speichern Berichtsordner.

Webseitenbericht

Ich werde nicht näher auf Djangos Methode eingehen, es gibt bereits eine ganze Reihe von Artikeln auf dem Blog. Wir müssen die drei zuvor aufgezeichneten TXT-Dateien in der Ansichtsdatei öffnen, dann eine Datenverarbeitung durchführen und sie an das Frontend zurückgeben. Das Frontend verwendet Bootstrap, um sie zu rendern und einen schöneren Testbericht zu erstellen.

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})

Grundsätzlich einige sehr grundlegende Kenntnisse, String-Segmentierung und so weiter. Um die Datenverarbeitung hier zu vereinfachen, muss die Datenspeicherung in einem bestimmten Format gespeichert werden, und die Ansichtsmethode ist einfach zu verarbeiten.

Der Front-End-Code lautet wie folgt:

<!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>

Testbericht-Renderings

Beispiel für ein Python-basiertes Schnittstellentest-Framework

Endlich

Es ist einfach, ein Tool in Python zu schreiben, aber der Hauptzweck besteht darin, die Anforderungen bequemer zu erfüllen der tatsächlichen Arbeit. Wenn Sie einen vollständigen Schnittstellentest durchführen möchten, versuchen Sie, ausgereifte Tools zu verwenden.

PS: Das einfache Herstellen von Rädern ist auch eine hervorragende Möglichkeit, die Prinzipien zu erlernen.

Das obige Beispiel des auf Python basierenden Schnittstellentest-Frameworks ist der gesamte vom Herausgeber geteilte Inhalt. Ich hoffe, dass es Ihnen eine Referenz geben kann, und ich hoffe, dass Sie die chinesische PHP-Website unterstützen.

Weitere Artikel zu Beispielen für Python-basierte Schnittstellentest-Frameworks finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn