@
はじめに
インターフェースの自動化テストには多くの実装方式があり、プログラミングの基礎がないものはPostman + NewmanまたはJmeter + Antを使用して実装でき、プログラミングの基礎があるものは自動テストフレームワークと組み合わせることができます。Pythonベースのテストフレームワークは、Unittest、HttpRunner、Robot Framework、Pytestなどです。この記事では、現時点で人気があり実用的なフレームワークであるHttpRunnerについて主に説明し、自動テスト、パフォーマンステスト、オンラインモニタリング、継続的統合などのさまざまなテストを実現できます。需要。
注:
この記事はより長く、主にフレームワークの機能、プロセス、構造、使用例の整理、およびHttpRunnerのクイックスタートチュートリアルを示しています。この記事の内容を要約すれば、基本的に始めることができます。次のステップは、多くの練習を続けることです
1. HttpRunnerの紹介
HttpRunnerは、HTTP(S)プロトコルの一般的なテストフレームワークです。自動テスト、パフォーマンステスト、オンラインモニタリング、継続的インテグレーションなどのさまざまなテストニーズを達成するには、YAML / JSONスクリプトを記述して維持するだけで済みます。
第二に、HttpRunnerの設計コンセプト
1.車輪を再発明しないことを追求する
2.慣習は構成よりも大きいという規則に従う
3.入出力比を追求する
3. HttpRunnerのコア機能
1.リクエストのすべての特性を継承する
2. YAML / JSONを使用してテストシナリオを記述し、テストケースの記述の均一性と保守性を確保する
3.ヘルパー関数(debugtalk.py)を使用して、テストスクリプトに複雑なダイナミクスを簡単に実装する計算ロジック
4.テストケースの再利用を完全に実現するための完全なテストケースレイヤーメカニズムを
サポート5. テストの前後に完全なフックメカニズムをサポート
6.応答結果は豊富なチェックメカニズムをサポート
7. HARに基づくインターフェースの記録とユースケース生成の実装(Har2case)
8. Locustフレームワークと組み合わせると、追加の作業なしで分散パフォーマンステストを実現できます。9 .
実行方法は、Jenkinsなどの継続的統合ツールと完全に組み合わせることができるCLI呼び出しを使用します
。10.テスト結果の統計レポートは、詳細な統計情報とともに簡潔かつ明確ですログ記録
11.非常に拡張性が高く、二次開発とWebプラットフォーム化を簡単に実現
4番目に、HttpRunnerフレームワークプロセス
5、HttpRunnerはすぐに使い始めます
1.環境の準備
1.動作環境:Python 3.4以上を推奨
2.インストール方法:pip install httprunner
3.インストールの確認:cmdを開き、次のコマンドを入力して確認します。バージョン番号はインストールが成功したことを示します
C:\Users\luoluo>hrun -V
2.5.7
C:\Users\luoluo>har2case -V
0.3.1
2.スクリプトの記録
テストケースの記述を簡素化するために、Fiddler、Charlesなどのパケットキャプチャツールを介してインターフェイスキャプチャを実行し、標準およびユニバーサルHAR形式(HTTPアーカイブ)にエクスポートしてから、HAR形式のデータパケットをHttpRunnerを介してYAML / JSONに変換できます。テストケースファイルの形式、対応する変換ツールは
次のとおりです。har2case 次の例では、Fiddlerを使用してスクリプトの記録とエクスポートを実行します。
操作手順:
変換するインターフェイスを選択し(複数選択またはすべて選択)、メニューの[Flie]-> [Export Sessions]をクリックします。 ->選択したセッション(HTTPアーカイブv1.1タイプを選択)をローカルに保存できます
Charlesでの記録方法はほぼ同じです。操作手順は、変換するインターフェイスを選択し(複数選択またはすべて選択)、右クリックして、中断されたメニューディレクトリの[Export ...]をクリックし、フォーマットとしてHTTP Archive(.har)を選択します。 )そしてそれを保存します
3.スクリプトの生成
1. HARをデフォルトのJSONスクリプトに変換します。変換コマンドは次のとおりです:har2case filename.har
C:\Users\luoluo\Desktop>har2case test1.har
INFO:root:Start to generate testcase.
INFO:root:dump testcase to JSON format.
INFO:root:Generate JSON testcase successfully: test1.json
2. HARをYAMLスクリプトに変換します。変換コマンドは次のとおりです:har2case -2y filename.har
C:\Users\luoluo\Desktop>har2case -2y test1.har
INFO:root:Start to generate testcase.
INFO:root:dump testcase to YAML format.
INFO:root:Generate YAML testcase successfully: test1.yml
この時点で、対応する形式のファイルがローカルで生成されていることがわかります。ファイルを
開いて内容を確認してください。プライバシーの問題により、実際のドメイン名は一時的に変更されてい
ます。次のコードは.json形式です。
{
"config": {
"name": "testcase description",
"variables": {}
},
"teststeps": [
{
"name": "/api/trend/webinfo/getnavs",
"request": {
"url": "{{HOST}}/api/trend/webinfo/getnavs",
"params": {
"gender_id": "72105",
"no_cache": "1"
},
"method": "GET",
"headers": {
"Sec-Fetch-Dest": "empty",
"Authorization": "",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
"Content-Type": "application/json;charset=utf-8;",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"If-None-Match": "W/\"9b200f8fd6b4e23ffd2c77a44e50ba275fdb123c\""
}
},
"validate": [
{
"eq": [
"status_code",
200
]
},
{
"eq": [
"headers.Content-Type",
"application/json"
]
},
{
"eq": [
"content.status_code",
200
]
},
{
"eq": [
"content.message",
"ok"
]
}
]
},
{
"name": "/api/trend/search/get-recommand",
"request": {
"url": "{{HOST}}/api/trend/search/get-recommand",
"params": {
"gender_id": "72105"
},
"method": "GET",
"headers": {
"Sec-Fetch-Dest": "empty",
"Authorization": "",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
"Content-Type": "application/json;charset=utf-8;",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"If-None-Match": "W/\"c404d82a8ca9667a6e891907cc6ac7f17edc5143\""
}
},
"validate": [
{
"eq": [
"status_code",
200
]
},
{
"eq": [
"headers.Content-Type",
"application/json"
]
},
{
"eq": [
"content.status_code",
200
]
},
{
"eq": [
"content.message",
"ok"
]
}
]
},
]
}
以下は.yml形式です。
config:
name: testcase description
variables: {}
teststeps:
- name: /api/trend/webinfo/getnavs
request:
headers:
Authorization: ''
Content-Type: application/json;charset=utf-8;
If-None-Match: W/"9b200f8fd6b4e23ffd2c77a44e50ba275fdb123c"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
method: GET
params:
gender_id: '72105'
no_cache: '1'
url: ${ENV(HOST)}/api/trend/webinfo/getnavs
validate:
- eq:
- status_code
- 200
- eq:
- headers.Content-Type
- application/json
- eq:
- content.status_code
- 200
- eq:
- content.message
- ok
- name: /api/trend/search/get-recommand
request:
headers:
Authorization: ''
Content-Type: application/json;charset=utf-8;
If-None-Match: W/"c404d82a8ca9667a6e891907cc6ac7f17edc5143"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
method: GET
params:
gender_id: '72105'
url: ${ENV(HOST)}/api/trend/search/get-recommand
validate:
- eq:
- status_code
- 200
- eq:
- headers.Content-Type
- application/json
- eq:
- content.status_code
- 200
- eq:
- content.message
- ok
yaml形式がより簡潔に見えることがわかります
4.スクリプトを実行します
スクリプトを実行するコマンドは次のとおりです:hrun filename.jsonまたはhrun filename.yml
以下は実行ステータスですプライバシー問題のため、実際のドメイン名は一時的に変更されています:
C:\Users\luoluo\Desktop>hrun test1.yml
INFO HttpRunner version: 2.5.7
INFO Start to run testcase: testcase description
/api/trend/webinfo/getnavs
INFO GET https://{{HOST}}/api/trend/webinfo/getnavs
INFO status_code: 200, response_time(ms): 524.28 ms, response_length: 5357 bytes
.
/api/trend/search/get-recommand
INFO GET https://{{HOST}}//api/trend/search/get-recommand
INFO status_code: 200, response_time(ms): 62.19 ms, response_length: 232 bytes
.
----------------------------------------------------------------------
Ran 2 tests in 0.600s
OK
INFO Start to render Html report ...
INFO Generated Html report: C:\Users\luoluo\Desktop\reports\20200414T125709.244873.html
Sentry is attempting to send 0 pending error messages
Waiting up to 2 seconds
Press Ctrl-Break to quit
C:\Users\luoluo\Desktop>
5.レポートを表示する
上記のレポートアドレスを直接コピーして、テストレポートを表示できます。レポートの内容は非常に詳細です。
ログボタンをクリックして、リクエストを表示し、特定のインターフェースのデータを返します。
6.プロジェクトを作成する
この時点で、より実用的な操作のための新しいプロジェクトの作成を開始でき
ます。プロジェクトの作成コマンド:hrun --startproject new project name
C:\Users\luoluo\Desktop>hrun --startproject myobject
Start to create new project: myobject
CWD: C:\Users\luoluo\Desktop
created folder: myobject
created folder: myobject\api
created folder: myobject\testcases
created folder: myobject\testsuites
created folder: myobject\reports
created file: myobject\api\demo_api.yml
created file: myobject\testcases\demo_testcase.yml
created file: myobject\testsuites\demo_testsuite.yml
created file: myobject\debugtalk.py
created file: myobject\.env
created file: myobject\.gitignore
C:\Users\luoluo\Desktop>
プロジェクトのファイル構成構造は次のとおりです。
- これが上から下への分割線です============================================== ==============================
上記の内容は主に、記録を通じてHttpRunnerの扉をすばやく開くことを目的としています。この段階では、記録されたスクリプトを最適化および変更して、テストのニーズにより確実に対応する必要があると思います。たとえば、ログイン後にトークンが取得され、後続のすべてのインターフェースがトークンを渡す必要があるため、グローバル変数を設定する必要があります。テストステップは変更されないが、異なるリクエストパラメータを渡す必要がある場合は、リクエストパラメータを作成する必要があります。応答結果に対してアサーションの最適化を行う必要があります。また、次のことも必要です...
これらの問題をどのように解決しますか?次のコンテンツでは、HttpRunnerテストフレームワークのプロセス構造を詳しく説明し、テストケースの構成を明確にし、各ファイルのスクリプトを改良します...
HttpRunnerの探索の旅を始めましょう!
6、HttpRunnerプロジェクト構造
1.プロジェクトファイルの構造
以下は、サンプルプロジェクトファイルのディレクトリです:
MyObjectに
├──.env
├──データ
│├──acount.csv
├──API
│├──demo_api.yml
├──debugtalk.py
├──レポート
│├── 1550999327.html
├──のテストケース
│├──demo_testcase.yml
└──テストスイート
│├──demo_testsuite.yml
2.ファイルタイプの説明
-
.env:機密情報を保存するために使用されるプロジェクト環境変数
書き込み形式:key = value
参照メソッド:YAML / JSONスクリプトで、組み込み関数ENV参照、つまり$ {ENV(key)}を直接使用します -
debugtalk.py:ヘルパープロジェクト論理演算
①書き込み共通機能とトラフィックに関連する機能、参照機能試験は、タイムスタンプが得られるようないくつかの動的な計算ロジックを達成することができるように、乱数を生成し、署名処理
②準備フックテストケースの実行の前後にフック関数を呼び出して、特定の要求パラメーターの初期化、応答結果の特定の値の変更など、テストの準備とクリーンアップを実行できるようにする関数。参照方法:YAML / JSON形式のテストケースでは、$ {func()}を使用して参照されます。
注:
①ファイルが存在する場合、そのファイルが存在するディレクトリはプロジェクトプロジェクトのルートディレクトリと見なされ
ます②ファイルが存在しない場合、テストが実行されますパスはプロジェクトのルートディレクトリと見なされます -
api:インターフェース定義の説明
-
testcases:テストケースを保存する
-
testsuites:テストスイートの保存
-
data:テストデータの保存
-
reports:テストレポートの保存
セブン、HttpRunnerテストケース組織
1.インターフェースの説明を書く(api)
(1)サンプルテンプレートdemo_api.yml
name: demo api
variables:
var1: value1
var2: value2
request:
url: /api/path/${var1}
method: POST
headers:
Content-Type: "application/json"
json:
key: ${var2}
validate:
- eq: ["status_code", 200]
(2)テンプレートの説明
- name:インターフェースの名前。自由に名前を付けることができ、効果はありません
- variables:変数情報、形式はkey:value(コロンの後にスペースがあることに注意してください。これはymalファイルで指定された形式です)
- リクエスト:リクエスト情報
url:リクエストアドレス
メソッド:リクエストメソッド
ヘッダー:リクエストヘッダー
json:リクエストパラメータ、フォーマットはキー:値、値は一般に変数または関数を参照、フォーマット:$ {var}、
$ {func()} - 検証:結果のアサーション
2.テストケース(テストケース)を書く
(1)テンプレートサンプルdemo_testcase.yml
config:
name: "demo testcase"
variables:
device_sn: "ABC"
username: ${ENV(USERNAME)}
password: ${ENV(PASSWORD)}
base_url: "http://127.0.0.1:5000"
teststeps:
-
name: demo step 1
api: path/to/api1.yml
variables:
user_agent: 'iOS/10.3'
device_sn: $device_sn
extract:
- token: content.token
validate:
- eq: ["status_code", 200]
-
name: demo step 2
api: path/to/api2.yml
variables:
token: $token
(2)テンプレートの説明
- config:テストケース全体のグローバル構成
name:テストケースの名前、テストレポートにはname
変数が表示されます
。variable:グローバル変数base_url:アクセスアドレス。通常、ドメイン名ホストを記述します。 - teststeps:テストステップ、1つ以上のテストステップは以下のリストの形式で記述され、各テストステップの前には「-」が
付いていますname:テストステップ名、テストレポートには名前
api:参照インターフェース記述ファイル、ルートからの相対パスが表示されます内容は、開始
変数ここにいる場合、ローカル変数を埋めるために、グローバル変数より優先され、変数はグローバルコンフィグカバー内の変数になり、ローカル変数を:
エキス応答結果から抽出したパラメータ、および他のテスト手順のへの変数の参照に保存します。
検証:結果のアサーション
(3)テストケースの説明
①各テストケースは独立したユースケースであり、実行順序に関係なく、原則として他のテストケースには依存しません
。②抽出結果のアサーションフィールドは、status_code、content、text、json、cookies、expeded、headers、reason、enconding、okです。 、URL
結果JSON応答形式場合は、content.xxx.0.id ID(コンテンツに応じて、コンテンツ、およびXXX辞書キーのID、0最初のビット列)によって取得することができ、
その結果、応答のXML / HTMLである場合、結果パラメーターは、正規表現を介して取得できます
③バリデーターは、eq(=)、lt(<)、le(<=)、gt(>)、ge(> =)、ne(!=)、Str_eq、 len_eq、len_gt、len_ge、len_lt、len_le、contains、contained_by、type_match、regex_match、startswith、endswith
3.テストスイートを作成する
(1)テンプレートサンプルdemo_testsuite.yml
config:
name: "demo testsuite"
variables:
device_sn: "XYZ"
base_url: "http://127.0.0.1:5000"
testcases:
-
name: call demo_testcase with data 1
parameters:
phone-password: ${P(data/acount.csv)}
testcase: path/to/demo_testcase.yml
variables:
device_sn: $device_sn
-
name: call demo_testcase with data 2
testcase: path/to/demo_testcase.yml
variables:
device_sn: $device_sn
(2)テンプレートの説明
- config:グローバル構成項目
名:テストケースセットの名前 - テストケース:テストケースのコレクション
名前:テストケース名
パラメータ:パラメータ化、複数の実装があり、次のパラメータ化データドライブ(データ)への特定の参照
テストケース:参照テストケースファイル、ルートディレクトリ
変数からの相対パス:環境可変
(3)テストケースセットの説明
テストケースセットのテストケースは配列です。配列の各値は1つのテストケースです。通常、nameとtestcaseの2つのパラメーターがあります。さらに、パラメーター化されたデータ駆動型にすることもできます。
特記事項:ymlファイルは厳密なインデントに従う必要があります。同じレベルのキーが整列している限り、インデントの数は関係ありません
8. HttpRunnerのパラメーター化されたデータドライバー(データ)
1.パラメータ化
次の3つの方法があります。例としてログインを使用します。
(1)YAML / JSONでパラメーターリストを直接指定します。このメソッドは最もシンプルで使いやすく、パラメーターリストが比較的小さい場合に適しています。
config:
name: "login testsuites"
testcases:
-
name: login_with_account by raw_list
parameters:
phone-password:
- ['1342388xxxx',123456]
- ['1342388yyyy',654321]
testcase: path/to/demo_testcase.yml
(2)組み込みのパラメーター化(Pと略すこともできる)関数を介してCSVファイルを参照する:この方法では、CSVデータファイルを準備する必要があり、データ量が比較的多い場合に適しています。
config:
name: "login testsuites"
testcases:
-
name: login_with_account by csv_file
parameters:
phone-password: ${P(data/account.csv)}
testcase: path/to/demo_testcase.yml
account.csvファイルの内容は次のとおりです。
電話、パスワード
1342388xxxx、123456
1342388yyyy、654321
(3)debugtalk.pyでカスタム関数を呼び出してパラメーターリストを生成する:このメソッドは最も柔軟であり、シーンのデータ駆動型メカニズムはカスタムPython関数によって実現できます。このメソッドは、パラメーターリストを動的に生成する必要がある場合にも選択する必要があります
config:
name: "login testsuites"
testcases:
-
name: login_with_account by custom_function
parameters:
phone-password: ${get_account()}
testcase: path/to/demo_testcase.yml
debugtalk.pyファイルのカスタム関数は次のとおりです。
def get_account():
return [
{"phone":"1342388xxxx","password":"123456"},
{"phone":"1342388yyyy","password":"654321"},
]
9つのHttpRunnerテストケースレイヤー
自動テストの分野では、自動テストケースの保守性は非常に重要な要素です。テストケース階層化メカニズムの中核は、インターフェイスの定義、テストステップ、テストケース、およびテストシナリオを分離し、それらを個別に記述および保守することです。自動テストケースのメンテナンスコストを削減するための
いくつかのコアコンセプト:
①テストケース(テストケース)は完全で独立している必要があり、各テストケースは独立して実行できる必要があります
②テストケースはテストステップ(テストステップ)の順序付けられたコレクションであり、各テストステップはAPIリクエストの説明に対応しています
③テストテストスイートは、順序付けされていないテストケースのコレクションです。コレクション内のテストケースは互いに独立している必要があり、依存関係はありません。依存関係がある場合は、テストケースで依存関係の処理を完了する必要があります。
10、HttpRunnerフックメカニズム
HttpRunnerのフックメカニズムの概念は、Unittestフレームワークのフロント(setUp)およびポスト(tearDown)プロセッサと同等です。つまり、フロントのsetup_hooksおよびpost teardown_hooks関数です。
1.フック関数を書く
(1)、テストケースレベル(testcase)
setup_hooks:ユースケース全体が実行を開始する前にフック関数をトリガーします。主に準備作業に使用されます。teardown_hooks:ユースケース全体が実行を
終了した後にフック関数をトリガーします。主にテスト後のクリーンアップ作業に使用されます
(2)テストステップレベル(TestStep)
setup_hooks:主に製造のために、フック関数の前に実行するHTTPリクエストを送信するには、また、コンテンツ要求前処理の要求に応じて実施されてもよい
teardown_hooks:フック関数は、主にテストのために、HTTP要求を送信した後に行いますクリーンアップ作業後、暗号化や復号化、その他の処理など、応答の応答を変更することもできます
debugtalk.pyファイルにフック関数を記述します。
import time
def sleep(n_secs):
time.sleep(n_secs)
2.フック関数を呼び出す
フック関数の定義は、プロジェクトのdebugtalk.pyに配置されます。YAML/ JSONでフック関数を呼び出すと、$ {func(a)}という形式になります。ここで、aは関数内の変数です。
次のコードは、setup_hooksおよびteardown_hooksキーワードを使用してdebugtalk.pyファイルのスリープ関数を呼び出し、場所に応じてテストケースレベルとテストステップレベルのどちらであるかを判断し、操作の前後を実行します。
config:
name: "demo testcase"
variables:
device_sn: "ABC"
username: ${ENV(USERNAME)}
password: ${ENV(PASSWORD)}
base_url: "http://127.0.0.1:5000"
# 测试用例层面,实现测试用例执行前等待10秒,执行后等待10秒的操作
setup_hooks:
- ${sleep(10)}
teardown_hooks:
- ${sleep(10)}
teststeps:
-
name: demo step 1
api: path/to/api1.yml
variables:
user_agent: 'iOS/10.3'
device_sn: $device_sn
# 测试步骤层面,实现测试步骤执行前等待10秒,执行后等待10秒的操作
setup_hooks:
- ${sleep(5)}
teardown_hooks:
- ${sleep(5)}
extract:
- token: content.token
validate:
- eq: ["status_code", 200]
-
name: demo step 2
api: path/to/api2.yml
variables:
token: $token
11.さらなる調査
HtttpRunnerのテストフレームワークは、国内のテストDanielによって作成されたと言われており、中国語の使用法のドキュメントがあります。公式ドキュメントは、https://cn.httprunner.org/で確認できます。