一步一步教你打造接口測試平臺(2)

這一節咱們實現下面兩個功能html

  • 自動判斷服務器響應的狀態碼,若是狀態碼是4xx,5xx的話則認爲請求失敗
  • 增長斷言功能,能夠判斷響應的json字符串裏是否包含預期的字段

爲了測試方便,咱們先在main.py文件中增長2個測試的接口前端

@app.route('/api')
def api():
    return jsonify({'name': 'etf', 'version': '0.01'})

@app.route('/error')
def error():
    codes = [404, 401, 403, 500]
    random.shuffle(codes)
    abort(codes[0])
  • /api接口返回json字符串{"name": "etf", "version": "0.01"}
  • /error接口隨機拋出401, 403, 404, 500錯誤中的1個

實現狀態碼自動判斷

再修改handle_get()方法python

def handle_get():
    url = request.form['url']
    try:
        r = requests.get(url)
    except Exception as e:
        print(e)
        r = None

    resp = build_resp(r)

    return render_template('home.html', resp=resp)

def build_resp(r):
    resp = {'success': False}
    if r is None:
        return resp

    if r.status_code < 400:
        resp['success'] = True

    resp['url'] = r.url
    resp['text'] = r.text
    resp['headers'] = r.headers
    resp['status_code'] = r.status_code

    return resp

這裏咱們新增了build_resp(r)方法,該方法的主要做用是判斷請求響應的狀態碼,若是小於400就將請求成功狀態設置爲True。git

下面修改前端頁面home.htmlgithub

<div class="container">
  <h3 class="text text-center main-title">ETF接口測試平臺</h3>
  <form action="/handle_get" method="post">
    <div class="form-group">
      {% if resp and resp['url'] %}
      <input type="text" name="url" id="url" placeholder="請輸入URL" class="form-control" autofocus value="{{resp['url']}}">
      {% else %}
        <input type="text" name="url" id="url" placeholder="請輸入URL" class="form-control" autofocus>
      {% endif %}
    </div>
    <div class="form-group">
      <input type="submit" name="submit" value="肯定" class="btn btn-primary">
    </div>
  </form>
  <hr>

  {% if resp['success'] %}
    <p>接口地址: {{resp['url']}}</p>
    <p>狀態碼: {{resp['status_code']}}</p>
    <hr>
    <p>Headers</p>
    {% for key, value in resp['headers'].items() %}
      <p> <pre><code>{{key}}: {{value}}</code></pre> </p>
    {% endfor %}

    <hr>
    <p>Body</p>
    <pre>
      <code>
        {{resp['text']}}
      </code>
    </pre>
  {% else %}
    <p class="text text-danger">執行失敗</p>
    <p class="text text-danger">狀態碼: {{resp['status_code']}}</p>
    <p class="text text-danger">響應: {{resp['text']}}</p>
  {% endif%}
</div>

上面主要的修改是回顯get請求的url,另外若是請求是失敗狀態,就展現失敗的信息。json

修改完成後,使用/error接口進行測試,效果以下api

實現斷言

咱們使用最偷懶最不安全的方式去實現斷言,使用python的eval()方法,你們有興趣能夠自行了解一下。該方法主要的做用就是動態去執行一段python代碼,是黑魔法,不安全,僅僅做爲演示使用,你們不要在生產環境使用。安全

咱們的設計是讓用戶在頁面上輸入一個斷言表達式,也就是純python代碼。默認狀況下咱們將服務器返回的json字符串轉換成python字典,並賦值給obj變量。簡單理解的話就是服務器的返回會自動轉成名爲obj的字典對象,咱們可使用下面的語法來進行斷言服務器

  • obj['name'] == 'tfl'
  • obj['key'] == 'value'
  • obj['key1']['key2'] == 'value1'

也就是提供1個python表達式,只要表達式返回的是boolean值就行了。app

實現後效果以下,咱們使用/api接口進行測試

上面咱們測試了斷言經過和失敗的狀況,一切如預期。

main.py中實現的核心代碼其實很簡單。

def handle_get():
    url = request.form['url']
    assertion = request.form['assert']
    assertion_success = None
    try:
        r = requests.get(url)
        if assertion is not None and assertion != '':
            obj = r.json()
            if assertion:
                assertion_success = eval(assertion)
    except Exception as e:
        print(e)
        r = None

    resp = build_resp(r)
    resp['assertion'] = assertion
    resp['assertion_success'] = assertion_success

    return render_template('home.html', resp=resp)

上面的代碼裏咱們將用戶輸入的python表達式直接使用eval方法執行,若是表達式爲真,則斷言經過,不然失敗。該方法很危險,你們能夠去搜索一下爲何。

前端頁面的核心修改以下

{% if resp['assertion_success'] is not none %}
  {% if resp['assertion_success'] %}
    <p><strong class="text text-success">斷言成功</strong></p>
  {% else %}
    <p><strong class="text text-danger">斷言失敗</strong></p>
  {% endif %}
  <p><code>{{resp['assertion']}}</code></p>
  <hr>
{% endif %}

判斷斷言執行的狀態並給予相應的顯示。

完整代碼請點擊這裏

總結

  • 狀態碼只要大於等於400咱們就能夠認爲請求失敗,你們能夠去搜索一下爲何這樣子?
  • 使用eval()動態執行代碼很是危險,由於用戶能夠輸入任意代碼,嚴重狀況下這些代碼可能致使你的服務器被黑客攻陷,因此在生產環境必定不要使用該方法。
  • 永遠不要相信用戶輸入,上面的代碼只是演示,並無什麼實用價值。
相關文章
相關標籤/搜索