インターフェイスの自動テスト: Python+Pytest+Requests+Allure

このプロジェクトでは、Daily Costのインターフェイス テストを実装します。

  • Python+Requests はHTTP プロトコル要求インターフェイスを送信して処理します
  • テスト実行者としてのPytest
  • YAML管理テストデータ
  • テストレポートを生成する魅力。

このプロジェクトはpytestDemoに基づいて独自の実装を行っています。

1. プロジェクトの構造とインストールと展開

プロジェクト構造

  • api : インターフェイスのカプセル化層(HTTP インターフェイスを Python インターフェイスとしてカプセル化するなど)
  • commom : ファイルからデータを読み取るためのさまざまなツール
  • core : リクエストメソッドのカプセル化、キーワード戻り結果クラスをリクエストします。
  • config : 環境、データベース接続、その他の構成
  • data : テストデータファイル管理
  • 操作: キーワード カプセル化レイヤー (複数の Python インターフェイスをキーワードとしてカプセル化するなど)
  • pytest.ini : pytest設定ファイル
  • requirements.txt : 関連する依存関係パッケージ ファイル
  • テストケース: テストケース
  • api_test : 単一インターフェースのテスト
  • scenario_test : シナリオ/ビジネス プロセス テスト

インストールと展開

  • Daily Cost アプリの導入: チュートリアル
  • このテスト プロジェクトのソース コードをダウンロードし、 pip を通じて対応する依存関係をインストールしpip3 install -r requirements.txt、実際の状況に応じて settings.ini 内の対応するコンテンツを変更します。
  • pytest実行テストを入力してください
  • Allure を使用して生成されたテスト レポートを表示する場合は、まず Allure サービスをインストールする必要があります。brew install allure

2. 環境構築

  • config-setting.ini ファイルで定義api_root_url
  • common-read_data.pyにload_ini()メソッドを実装して構成ファイルを読み取ります。
  • 対応する値を読み取るために使用する必要がapi_root_urlある場所で呼び出します。load_ini(data_file_path)

3. HTTPリクエストをカプセル化する

  1. リクエストのカプセル化 request メソッド:リクエストで送信される GET、POST、PUT、DELETE などのメソッドをRestClientクラスにカプセル化します。
  2. テスト対象の API インターフェースのリクエストを定義します。 apiフォルダー内にドメインに応じてリクエストに対応するコレクション クラスを作成しclass User(RestClient)、ログイン インターフェースなどの各インターフェース情報を定義します。
def login(self, **kwargs):         
    return self.post("/login", **kwargs)

4. キーワードのカプセル化

キーワードはビジネス上で何らかの重要性を持つものである必要があります。キーワードをカプセル化する場合、1 つのインターフェイスのみをカプセル化することも、複数のインターフェイスを呼び出して完了することもできます。

たとえば、レコードをテストする場合、インターフェイスはインターフェイスが正常に呼び出された後にのみ請求書の ID を返します。また、各フィールドが入力と一致しているかどうかを判断するためにクエリ請求書詳細インターフェイスを呼び出す必要もあります。その場合、次のようにテストできます。

  • まず、记一笔-查看明细操作をキーワードとしてカプセル化し、このキーワードでレコードを呼び出し、請求詳細の結果を順番にクエリします。キーワードの戻り結果をカスタマイズできます。
  • 次に、テスト ケースを作成するときに、キーワードを直接呼び出してテストすると、キーワードの結果を返すことができます。アサートする場合は、キーワードによって返された結果を直接アサートすることもできます。

もう 1 つの例は、毎月の請求書の統計結果をクエリすることです。1 つのインターフェイスでビジネス クエリ操作を独立して完了できます。このインターフェイスをキーワードで呼び出すだけで済みます。

このプロジェクトに戻ると、具体的なコード ロジックは次のとおりです。

  1. 操作フォルダーでは、キーワードがドメイン ファイルに従って整理されます。
  2. core のキーワードによって返されるデータ構造クラスを定義します。ResultBase
  3. キーワードを定義します。対応する API リクエストを呼び出すときは、インターフェースリクエストパラメータを明示的に渡し、戻り結果を定義する必要があります。
def bill_monthly_stat(date, token):
   header = {
       "Content-Type": "application/json",
       "Authorization": "Bearer " + token
   }
   param = {"date": date}
   res = bill_details.get_bill_monthly(params=param, headers=header)

   return ResultBase(res)

このプロジェクトのキーワードにカプセル化されたリクエストは 1 つだけです。

5. 単一インターフェースのテスト

记一笔インターフェイスを例に挙げます。

  • インターフェースとキーワードを定義する
// api -> bill.py : 定义接口
def create_new_bill(self, **kwargs):
    return self.post("/bill", **kwargs)

// operation -> bill.py : 定义关键字
def bill_create(category_id, type, amount, note, date, token):
    payload = {
        "categoryId": category_id,
        "type": type,
        "amount": amount,
        "note": note,
        "date": date
    }
    header = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + token
    }
    res = bill.create_new_bill(json=payload, headers=header)

    return ResultBase(res)
  • インターフェーステストクラス
// testcases -> api_test -> bill -> test_bill_create.py
class TestBillCreate():
    @mark.smoke
    @mark.parametrize('category_id, type, amount, note, date, status_code, message', 
                    [
        ("5442d3b8-9d4a-4654-bf0b-d2249efef190", "EXPENSE", 100.01, "note1111test", "2021-12-01", 200, "操作成功"),
        ("66c22fad-be9d-481d-a445-c57d266bf938", "INCOME", 1000.01, "note1111test", "2021-12-01", 200, "操作成功")
        ])
    def test_bill_create_success(self, category_id, type, amount, note, date, status_code, message, token):
        result = bill_create(category_id, type, amount, note, date, token)
        assert result.response.status_code == status_code
        assert result.message == message
        assert result.response.json()["data"]["id"]
  • @mark.smokepytestのマークマーキング機能を利用しており、実行時にpytest -m smokesmokeとマークされたユースケースのみを実行するコマンドを使用します。
  • @mark.parametrizeデータ駆動型テストを実現できるpytestの変数パラメータ化機能です 上記のようにパラメータ化されたデータが2つある場合、その2つのデータでユースケースが2回実行されます
  • bill_create を呼び出すときにパラメータがありtoken、実際にはconftest.pyファイル内で定義されています
  • pytest のアサートは、Python の組み込みアサーション ライブラリを使用します。

6. YAMLファイル管理テストデータ

上記の例では、@mark.parametrize使用時にユースケースの上に特定のテストデータを直接書き込みました。後の変更やメンテナンスの効率を高めるために、通常はテスト データとユースケースを分離します。つまり、yaml ファイルを使用してテスト データを個別に管理し、conftest.py を使用してデータを読み取ることができます。

  • yaml ファイルを定義します: data -> api_test_data.yml
test_bill_create_success:
  # category_id, type, amount, note, date, status_code, message
  - ["5442d3b8-9d4a-4654-bf0b-d2249efef190", "EXPENSE", 100.01, "note1111test", "2021-12-01", 200, "操作成功"]
  - ["66c22fad-be9d-481d-a445-c57d266bf938", "INCOME", 1000.01, "note1111test", "2021-12-01", 200, "操作成功"]
  • keyテストケースに対応する関数名test_bill_create_success
  • -値が配列であることを示します
  • conftest.py対応するテストデータを読み込みます
import pytest
import os
from common.read_data import data 

BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
def get_data(yaml_file_name):
    try:
        data_file_path = os.path.join(BASE_PATH, "data", yaml_file_name)
        yaml_data = data.load_yaml(data_file_path)
    except Exception as ex:
        pytest.skip(str(ex))
    else:
        return yaml_data

api_data = get_data("api_test_data.yml")
  • パラメータ化時に yaml ファイルからデータを読み取る
@mark.parametrize('category_id, type, amount, note, date, status_code, message', 
                    api_data["test_bill_create_success"])

7. APIシナリオのテスト

APIテストを行う際には、単一のインターフェースの入出力の検証だけでなく、複数のインターフェースを直列に接続したビジネスシナリオのテストも欠かせません。

簡単に言うと、ログイン後のホームページを例にすると、「ログイン」→「当月の請求書リストのクエリー」→「当月の請求書統計のクエリー」というインターフェース呼び出しとなります。

  • シナリオテストクラスを定義する
// testcases -> scenario_test -> test_get_one_month_bill.py
import allure
import pytest
from operation.user import login_user
from operation.bill import one_month_bill_list_get_by_date, bill_monthly_stat

@pytest.mark.core
class TestGetOneMonthBill:

    @allure.title("01: user[yuxiaomeng] login")
    @allure.story('story_1')
    def test_user_login(self, core_env):
        result = login_user('yuxiaomeng', '20211030.y')
        assert result.status_code == 200
        assert result.data["token"]
        core_env["token"] = result.data["token"]

    @allure.title("02: get homepage info - bill details list")
    @allure.story('story_1')
    def test_get_current_month_monthly_bill_list(self, core_env):
        result = one_month_bill_list_get_by_date(core_env["date"], core_env["token"])
        assert result.status_code == 200
        assert len(result.data) == 2
        assert result.data[0]["date"] == "2021-11-11"
        assert result.data[0]["expense"] == 510.5

    @allure.title("03: get homepage info - bill monthly statistics ")
    @allure.story('story_1')
    def test_get_current_month_bill(self, core_env):
        result = bill_monthly_stat(core_env["date"], core_env["token"])
        assert result.status_code == 200
        assert result.data["expense"]
  • core_envインターフェイス間でテストデータを渡すために使用されます
// testcases -> scenario_test -> conftest.py
import pytest

@pytest.fixture(scope='session')
def core_env():
    return {"date": "2021-11"}

8. Allure はテストレポートを生成します

allure-pytest の詳しい使用方法については、公式ドキュメントを参照してくださいここでは簡単な紹介のみを行います。

  • テストの実行時に --alluredir パラメーターを追加して、指定したフォルダーにレポートを保存します。pytest --alluredir=/tmp/my_allure_results
  • 実行後にレポートを表示します。allure serve /tmp/my_allure_results

以下はサポート情報です。[ソフトウェア テスト] を行う友人にとって、これは最も包括的で完全な準備倉庫となるはずです。この倉庫は、最も困難な旅にも同行してくれました。あなたにも役立つことを願っています。

ソフトウェアテストインタビューアプレット

ソフトウェア テストの質問バンクは、何百万人ものユーザーによって最大化されました。誰が知っているのか!ネットワーク全体で最も包括的なクイズ ミニ プログラムです。携帯電話を使用して、地下鉄やバスの中でもクイズに答えることができます。

次の面接の質問セクションが取り上げられます。

1. ソフトウェアテストの基礎理論、2. Web、アプリ、インターフェース機能テスト、3. ネットワーク、4. データベース、5. Linux

6. Web、アプリ、インターフェイスの自動化、7. パフォーマンス テスト、8. プログラミングの基本、9. 時間面接の質問、10. 公開テストの質問、11. セキュリティ テスト、12. コンピューターの基本

情報取得方法:

おすすめ

転載: blog.csdn.net/myh919/article/details/131810989