両者の見分け方は非常に簡単で、公式のテストフレームワークとしてはunittestの方がテストの基本的な部分があり、二次開発にも再利用できますが、同時に利用形態が複雑になります。 pytest フレームワークはサードパーティのフレームワークであり、便利です。より柔軟に使用でき、元の Unittest スタイルのテスト ケースとの互換性が高いのがポイントです。同時に、拡張機能が豊富です。 、使用シナリオは、いくつかの同時テストなどの拡張プラグインを通じて追加できます。
pytest-install
pip install pytest
テストインストールは成功しました:
pytest --help
py.test --help
インストールされているバージョンを確認します。
pytest --version
Pytest の例
Pytest の記述ルール:
- テスト ファイルは test_ で始まります (_test で終わります)
- テストされるクラスは Test で始まります。
- テストメソッドはtest_で始まります
- 基本的なアサートを使用したアサート
test_example.py
def count_num(a: list) -> int:
return len(a)
def test_count():
assert count_num([1, 2, 3]) != 3
テストを実行します。
pytest test_example.py
結果:
C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest>pytest test_example.py -v
================================================================= test session starts =================================================================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- d:\coding\python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collected 1 item
test_example.py::test_count FAILED [100%]
====================================================================== FAILURES =======================================================================
_____________________________________________________________________ test_count ______________________________________________________________________
def test_count():
> assert count_num([1, 2, 3]) != 3
E assert 3 != 3
E + where 3 = count_num([1, 2, 3])
test_example.py:11: AssertionError
=============================================================== short test summary info ===============================================================
FAILED test_example.py::test_count - assert 3 != 3
================================================================== 1 failed in 0.16s ==================================================================
述べる:
- . はテストが合格したことを意味し、F はテストが失敗したことを意味します。
- -v は詳細なテスト情報を表示し、-h は pytest コマンドの詳細なヘルプ情報を表示します。
マーク
デフォルトでは、pytest は現在のディレクトリで test_ で始まる (_test で終わる) テスト ファイルを検索し、ファイル内の test_ で始まる (_test で終わる) 関数とメソッドをすべて実行します。
- 実行するテストケースを指定するには、:: 表示マーク (ファイル名:: クラス名:: メソッド名) (ファイル名:: 関数名) を渡すことができます。
pytest test_example3.py::test_odd
- 実行するテスト ケースをいくつか指定します。 -k ファジー マッチングを使用できます。
pytest -k example
- pytest.mark.skip() または pytest.makr.skipif() 条件式により指定されたテストケースをスキップします
import pytest
test_flag = False
@pytest.mark.skip()
def test_odd():
num = random.randint(0, 100)
assert num % 2 == 1
@pytest.mark.skipif(test_flag is False, reason="test_flag is False")
def test_even():
num = random.randint(0, 1000)
assert num % 2 == 0
- テストケースによってスローされる可能性のある例外は、pytest.raises() によってキャッチされます。
def test_zero():
num = 0
with pytest.raises(ZeroDivisionError) as e:
num = 1/0
exc_msg = e.value.args[0]
print(exc_msg)
assert num == 0
- テスト ケースが失敗することを事前に知っているが、スキップしたくない場合は、プロンプト メッセージを表示する必要があり、pytest.mark.xfail() を使用します。
@pytest.mark.xfail()
def test_sum():
random_list = [random.randint(0, 100) for x in range(10)]
num = sum(random_list)
assert num < 20
- テスト ケースでは複数のデータ テスト セットが実行され、パラメーターの各セットは独立して 1 回実行できます (テスト ケース内の 1 セットのデータ テストの実行に失敗した後にテストが停止することを回避できます)
@pytest.mark.parametrize('num,num2', [(1,2),(3,4)])
def test_many_odd(num: int, num2: int):
assert num % 2 == 1
assert num2 % 2 == 0
ファームウェア_
ファームウェアはいくつかの前処理関数です。pytest は、テスト関数の実行前 (または後) にこれらのファームウェアをロードして実行します。一般的なアプリケーション シナリオには、データベース接続とシャットダウン (デバイスの接続とシャットダウン) が含まれます
使いやすい
import pytest
@pytest.fixture()
def postcode():
return "hello"
def test_count(postcode):
assert postcode == "hello"
公式の説明によると、テスト関数を実行すると、まず実行中の関数のパラメーターを検出し、パラメーターと同じ名前のフィクスチャを検索し、pytest がそれらを見つけると、これらのフィクスチャを実行して戻り値を取得します。これらのフィクスチャ (存在する場合) を取得し、それらを返します。値は引数としてテスト関数に渡されます。
前処理と後処理
次に、公式声明をさらに検証します。
import pytest
@pytest.fixture()
def connect_db():
print("Connect Database in .......")
yield
print("Close Database out .......")
def read_database(key: str):
p_info = {
"name": "zhangsan",
"address": "China Guangzhou",
"age": 99
}
return p_info[key]
def test_count(connect_db):
assert read_database("name") == "zhangsan"
テスト関数の結果を実行します。
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 1 item
test_example.py::test_count Connect Database in .......
PASSED [100%]Close Database out .......
============================== 1 passed in 0.07s ==============================
述べる:
- まずは結果から公式の説明を検証します テスト関数を実行する前に、pytest は同じ名前のファームウェアを探してロードして実行します。
- connect_db ファームウェアには yield があり、pytest はデフォルトで yield キーワードの前のコードが前処理であると判断し、テスト前に実行されます。yield 以降のコードは後処理であり、テスト後に実行されます。
スコープは、
ファームウェアの役割を正面から大まかに理解し、一部の繰り返し作業を抽出して再利用しやすくすると同時に、pytest フレームワークでファームウェアをより細かく制御するために、スコープを使用して指定します。ファームウェアの使用範囲(たとえば、モジュール内のテスト機能は 1 回実行でき、モジュール内の機能は繰り返し実行する必要はありません) より具体的な例は、データベースへの接続です。この接続の操作には時間がかかる可能性があります。このモジュールのテスト関数は 1 回だけ実行するだけでよく、毎回実行する必要はありません。
ファームウェアの定義は、scop パラメータを通じて関数を宣言することであり、一般的に使用されるものは次のとおりです。
function: 関数レベル、各テスト関数は 1 回実行されます;
class: クラス レベル、各テスト クラスは 1 回実行され、すべてのメソッドが使用できます;
module: モジュール レベル、各モジュールは 1 回実行され、その中の関数とメソッドモジュールは使用できます Use;
session: セッション レベル、テストは 1 回だけ実行され、見つかったすべての関数とメソッドが使用可能です。
import pytest
@pytest.fixture(scope="function")
def func_scope():
print("func_scope")
@pytest.fixture(scope="module")
def mod_scope():
print("mod_scope")
@pytest.fixture(scope="session")
def sess_scope():
print("session_scope")
def test_scope(sess_scope, mod_scope, func_scope):
pass
def test_scope2(sess_scope, mod_scope, func_scope):
pass
結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
test_example2.py::test_scope session_scope
mod_scope
func_scope
PASSED [ 50%]
test_example2.py::test_scope2 func_scope
PASSED [100%]
============================== 2 passed in 0.07s ==============================
ここから、モジュールとセッションスコープのファームウェアが一度だけ実行されることがわかり、正式な使用法が導入されたことを確認できます。
自動実行
なんでそんな面倒なことを言う人もいるかもしれませんが、unittest フレームワークで setUp を直接定義することで前処理を自動実行できますし、同じ pytest フレームワークでも同様の自動実行機能があり、pytest フレームワークのファームウェアは一般的にパラメータによって自動動作を制御します。自動使用。
import pytest
@pytest.fixture(scope='session', autouse=True)
def connect_db():
print("Connect Database in .......")
yield
print("Close Database out .......")
def test1():
print("test1")
def test2():
print("test")
結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
test_example.py::test1 Connect Database in .......
PASSED [ 50%]test1
test_example.py::test2 PASSED [100%]test
Close Database out .......
============================== 2 passed in 0.07s ==============================
この結果から、テスト関数の実行前後に connect_db ファームウェアが自動的に実行されることがわかります。
パラメータ化する
@pytest.mark.parametrize がパラメーター化されたテストに合格したことは前に簡単に説明しましたが、ファームウェアに関するパラメーターを渡すときは、pytest フレームワークで組み込みファームウェア リクエストを渡し、request.param を通じてパラメーターを取得する必要があります。
import pytest
@pytest.fixture(params=[
('redis', '6379'),
('elasticsearch', '9200')
])
def param(request):
return request.param
@pytest.fixture(autouse=True)
def db(param):
print('\nSucceed to connect %s:%s' % param)
yield
print('\nSucceed to close %s:%s' % param)
def test_api():
assert 1 == 1
結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
test_example.py::test_api[param0]
Succeed to connect redis:6379
PASSED [ 50%]
Succeed to close redis:6379
test_example.py::test_api[param1]
Succeed to connect elasticsearch:9200
PASSED [100%]
Succeed to close elasticsearch:9200
============================== 2 passed in 0.07s ==============================
ここでは、redis と elasticsearch の間の接続がシミュレートされ、ファームウェアがロードされて接続が自動的に実行され、次にテスト関数が実行されて切断されます。
要約する
開発の場合、なぜ自動テストを学ぶ必要があるのですか?自動テストによって反復的な作業時間を節約することは非常に重要です。同時に、コード構造の最適化、コード カバレッジの改善、およびその後のプロジェクトのリファクタリングにとっても非常に重要です。同時に、pytest と Unittest の基本的な違いを理解すると、さまざまなビジネス シナリオに適したテスト ツールを選択するのに役立ちます。
この記事では pytest の基本的な使い方を簡単に紹介しますが、内蔵ファームウェアの使用方法や一般的なテストシナリオなどについても言及されている公式ドキュメントを参照してください。
最後に、私の記事を注意深く読んでくださった皆さんに感謝します。互恵性は常に必要です。それはそれほど価値のあるものではありませんが、必要な場合はそれを取り上げることができます。
ソフトウェアテストインタビューアプレット
ソフトウェア テストの質問バンクには、何百万人もの人が参加しました。!!誰が知っているのか!!!ネットワーク全体で最も包括的なクイズ ミニ プログラムです。携帯電話を使用して、地下鉄やバスの中でもクイズに答えることができます。
次の面接の質問セクションが取り上げられます。
1. ソフトウェアテストの基礎理論、2. Web、アプリ、インターフェース機能テスト、3. ネットワーク、4. データベース、5. Linux
6. Web、アプリ、インターフェイスの自動化、7. パフォーマンス テスト、8. プログラミングの基本、9. 時間面接の質問、10. 公開テストの質問、11. セキュリティ テスト、12. コンピューターの基本
これらの資料は、[ソフトウェア テスト] の友人にとって最も包括的で完全な準備倉庫となるはずです。この倉庫は、最も困難な旅を乗り越える何万人ものテスト エンジニアにも同行してきました。あなたにも役立つことを願っています。