0から1のフレームワーク構築、Python+Pytest+Allure+Git+Jenkinsインターフェース自動化フレームワーク(超微細仕上げ)


序文

インターフェイス テストは、システムとコンポーネント間のインターフェイスをテストすることです。主に、データの交換、転送と制御の管理プロセス、および相互の論理依存関係を検証します。その中で、インターフェースプロトコルはHTTP、RPC、Webservice、Dubbo、RESTfulなどの種類に分けられます。

インターフェーステストのプロセス
1. ビジネスと要件に精通した要件レビュー
2. インターフェースドキュメントの開発と提供
3. インターフェーステストケースの作成
4. ユースケースレビュー
5. テスト後のテスト開始
6. テストレポートの提出

2 つの一般的な HTTP リクエスト メソッド: GET と POST

このフレームワークは、Python+Pytest+Requests+Allure+Jenkins に基づいて設計されたデータ駆動型インターフェイス自動テスト フレームワークのセットです。

テクノロジースタック:
Python、Pytest、Requests、Pactverity、Excel、Json、Mysql、Allure、Logbook、Git、Jenkins

フレームワーク構造図:

B1

プロジェクト機能:
Python+Pytest+Allure+Jenkins インターフェイス自動化フレームワーク、Excel または Json メンテナンス テスト ケースの実装、データベース操作のサポート、カプセル化された要求基本クラスを使用して対応するテスト ケース インターフェイスを呼び出し、環境アドレスと環境変数を取得します。設定ファイル、

Pytest を組み合わせて単体テストを行い、LogBook を使用してログを記録し、アリュール テスト レポートを生成し、最後に Jenkins 統合プロジェクトを実装して統合デプロイメントを実装し、テスト レポートの電子メールを送信します。

ツールパッケージ

1. ログモジュール
プロジェクト内のログはログブックに記録され、テスト、開発、デバッグ時のデバッグ、修正または修復、最適化に便利です。ログは画面に出力するかどうか、つまり実行時に端末出力に出力するかどうかを選択できます。ログ形式の出力を調整できます。

handle_log.py 部分のソース コード

 def log_type(record, handler):
     log = "[{date}] [{level}] [{filename}] [{func_name}] [{lineno}] {msg}".format(
         date=record.time,  # 日志时间
         level=record.level_name,  # 日志等级
         filename=os.path.split(record.filename)[-1],  # 文件名
         func_name=record.func_name,  # 函数名
         lineno=record.lineno,  # 行号
         msg=record.message  # 日志内容
     )
     return log
 # 日志存放路径
 LOG_DIR = BasePath + '/log'
 print(LOG_DIR)
 if not os.path.exists(LOG_DIR):
     os.makedirs(LOG_DIR)
 # 日志打印到屏幕
 log_std = ColorizedStderrHandler(bubble=True)
 log_std.formatter = log_type
 # 日志打印到文件
 log_file = TimedRotatingFileHandler(
     os.path.join(LOG_DIR, '%s.log' % 'log'), date_format='%Y-%m-%d', bubble=True, encoding='utf-8')
 log_file.formatter = log_type
 
 # 脚本日志
 run_log = Logger("global_log")
 def init_logger():
     logbook.set_datetime_format("local")
     run_log.handlers = []
     run_log.handlers.append(log_file)
     run_log.handlers.append(log_std)
     return ""

端末に出力されるログは下図のとおりです。

B2

プロジェクトを同時に実行すると、その日の日付に基づいた名前のログ ファイルがプロジェクト ファイル ログに自動的に生成されます。ログ ファイルをクリックすると、ログの詳細、つまりプロジェクトの実行時に記録されたログまたはエラー ログが表示されます。以下に示すように。

B3

2. 設定ファイルモジュール
ユーザー名、パスワード、環境変数などのいくつかの設定ファイルがプロジェクトに関係する場合、設定ファイルを通じて設定値を取得できます。構成ファイルの値は、構成ファイル内のキーと値の定義によって決まります。

handle_init.py 部分のソース コード

 class HandleInit:
     # 读取配置文件
     def load_ini(self):
         file_path = BasePath + "/config/config.ini"
         cf = configparser.ConfigParser()
         cf.read(file_path, encoding='UTF-8')
         return cf
 
     # 获取ini里面对应key的value
     def get_value(self, key, node=None):
         if node == None:
             node = 'Test'
         cf = self.load_ini()
         try:
             data = cf.get(node, key)
             logger.info('获取配置文件的值,node:{},key:{}, data:{}'.format(node, key, data))
         except Exception:
             logger.exception('没有获取到对应的值,node:{},key:{}'.format(node, key))
             data = None
         return data

以下の図に示すように、設定ファイル内の値のログを取得します。

B3

3. インターフェイス リクエストのカプセル化
関連するテスト ケースとインターフェイス ユース ケースの構成を取得し、リクエスト関連パラメーターのログを記録し、Allure テスト レポートの手順を定義します。

コードの handle_apirequest.py 部分

class ApiRequest:
     def api_request(self, base_url, test_case_data, case_data):
         get_name = None
         get_url = None
         get_method = None
         get_headers = None
         get_cookies = None
         get_case_name = None
         get_case_params = None
         response_data = None
         try:
             get_name = test_case_data['config']['name']
             get_url = base_url + test_case_data['config']['url']
             get_method = test_case_data['config']['method']
             get_headers = test_case_data['config']['headers']
             get_cookies = test_case_data['config']['cookies']
         except Exception as e:
             logger.exception('获取用例基本信息失败,{}'.format(e))
         try:
             get_case_name = case_data['name']
             get_case_params = case_data['params']
         except Exception as e:
             logger.exception('获取测试用例信息失败,{}'.format(e))
         with allure.step("请求接口:%s,请求地址:%s,请求方法:%s,请求头:%s,请求Cookies:%s" % (
                 get_name, get_url, get_method, get_headers, get_cookies)):
             allure.attach("接口用例描述:", "{0}".format(get_case_name))
             allure.attach("接口用例请求参数:", "{0}".format(get_case_params))
         logger.info(
             '请求接口名:%r,请求地址:%r,请求方法:%r,请求头:%r,请求Cookies:%r' %\ 

(get_name, get_url, get_method, get_headers, get_cookies))
         logger.info('请求接口名:%r,请求接口用例名:%r,接口用例请求参数:%r' %\

 (get_name, get_case_name, get_case_params))
         try:
             response_data = baseRequest.run_main(get_method, get_url, get_case_params, get_headers)
         except Exception as e:
             logger.exception('用例请求返回失败,{}'.format(e))
         logger.info('请求接口名:%r,请求接口用例名:%r,返回参数:%r' % (get_name, get_case_name, response_data.json()))
         return response_data

4. Excel データ処理 - テスト ケース

B4

テスト ケースは Excel ファイルで保持され、クラスは Excel で関連データを取得する方法 (セルの内容の取得、セルの行数の取得、Excel へのデータの書き込みなど) を定義します。

ソースコードの handle_exceldata.py 部分

class OperationExcel:
    def __init__(self, file_name=None, sheet_id=None):
        if file_name:
            self.file_name = file_name
            self.sheet_id = sheet_id
        else:
            self.file_name = ''
            self.sheet_id = 0
        self.data = self.get_data()

    # 获取sheets的内容
    def get_data(self):
        data = xlrd.open_workbook(self.file_name)
        tables = data.sheets()[self.sheet_id]
        return tables

    # 获取单元格的行数
    def get_lines(self):
        tables = self.data
        return tables.nrows

    # 获取某一个单元格的内容
    def get_cell_value(self, row, col):
        return self.data.cell_value(row, col)

5. JSON データ処理 - テスト ケース

{
    
    
    "config":{
    
    
        "name":"post接口名",
        "url":"/langdetect",
        "method":"POST",
        "headers":{
    
    
            "Content-Type":"application/json"
        },
        "cookies":{
    
    

        }
    },
    "testcase":[
        {
    
    
            "name":"测试用例1",
            "params":{
    
    
                "query":"测试"
            },
            "validate":[
                {
    
    
                    "check":"status_code",
                    "comparator":"eq",
                    "expect":"200"
                }
            ]
        },
        {
    
    
            "name":"测试用例2",
            "params":{
    
    
                "query":"python"
            },
            "validate":[
                {
    
    
                    "check":"msg",
                    "comparator":"eq",
                    "expect":"success"
                }
            ]
        }
    ]
}

Json ファイル内の特定のフィールドの値を取得します。
handle.json.py 部分のソース コード

class HandleJson:
    # 读取json文件
    def load_json(self, file_name):
        if file_name == None:
            file_path = ""
        else:
            file_path = file_name
        try:
            with open(file_path, encoding='UTF-8') as f:
                data = json.load(f)
            return data
        except Exception:
            print("未找到json文件")
            return {
    
    }

    # 读取json文件里具体的字段值
    def getJson_value(self, key, file_name):
        if file_name == None:
            return ""
        jsonData = self.load_json(file_name)
        if key == None:
            getJsonValue = ""
        else:
            getJsonValue = jsonData.get(key)
        return getJsonValue

基本クラスのカプセル化

このインターフェイスは Get リクエストと Post リクエストをサポートし、リクエストを呼び出してインターフェイスの呼び出しと戻りを実現します。インターフェイス パラメーターには、インターフェイス アドレス、インターフェイス リクエスト パラメーター、Cookie パラメーター、およびヘッダー パラメーターが含まれます。

class BaseRequest:

    def send_get(self, url, data, header=None, cookie=None):
        """
        Requests发送Get请求
        :param url:请求地址
        :param data:Get请求参数
        :param cookie:cookie参数
        :param header:header参数
        """
        response = requests.get(url=url, params=data, cookies=cookie, headers=header)
        return response

    def send_post(self, url, data, header=None, cookie=None):
        """
        Requests发送Post请求
        :param url:请求地址
        :param data:Post请求参数
        :param data:Post请求参数
        :param cookie:cookie参数
        :param header:header参数
        """
        response = requests.post(url=url, json=data, cookies=cookie, headers=header)
        return response

    # 主函数调用

    def run_main(self, method, url, data, header, cookie=None):
        try:
            result = ''
            if method.upper() == 'GET':
                result = self.send_get(url, data, header, cookie)
            elif method.upper() == 'POST':
                result = self.send_post(url, data, header, cookie)
            return result
        except Exception as e:
            logger.exception('请求主函数调用失败:{}'.format(e))

テストケースの作成

Pytest を参照してインターフェイスを単体テストし、パラメータ化されたデータ ドライバーとして JSON 内の複数のテスト ケースを使用します。Allure と組み合わせて、対応するインターフェイスのテスト レポートを作成します。インターフェイスがアサーションを返す前に、まずインターフェイスのコントラクト テストを実行します。

当社では Pactverity の完全な契約検証テストを使用しています。契約テストに合格すると、返されたパラメータの関連する検証テストを実行します。

test_getRequestJson.py のソースコードの一部

@allure.feature('测试GET请求模块')
class TestRequestOne():
    @allure.title('测试标题')
    @allure.testcase('测试地址:https://www.imooc.com')
    @pytest.mark.parametrize('case_data', testCaseData['testcase'])
    def test_requestOne(self, case_data):
        try:
            api_response = apiRequest.api_request(baseurl, testCaseData, case_data)
            api_response_data = api_response.json()
            # pactverity——全量契约校验
            config_contract_format = Like({
    
    
                "msg": "成功",
                "result": 0,
                "data": EachLike({
    
    
                    "word": Like("testng")
                })
            })
            mPactVerify = PactVerify(config_contract_format)
            try:
                mPactVerify.verify(api_response_data)
                logger.info(
                    'verify_result:{},verify_info:{}'.format(mPactVerify.verify_result, mPactVerify.verify_info))
                assert mPactVerify.verify_result == True
            except Exception:
                err_msg = '契约校验错误'
                logger.exception('测试用例契约校验失败,verify_result:{},verify_info:{}'.format(mPactVerify.verify_result,
                                                                                     mPactVerify.verify_info))
            try:
                for case_validate in case_data['validate']:
                    logger.info('断言期望相关参数:check:{},comparator:{},expect:{}'.format(case_validate['check'],
                                                                                   case_validate['comparator'],
                                                                                   case_validate['expect']))
                    comparatorsTest.comparators_Assert(api_response, case_validate['check'],
                                                       case_validate['comparator'], case_validate['expect'])
                    logger.info('测试用例断言成功')
            except Exception as e:
                logger.exception('测试用例断言失败')
        except Exception as e:
            logger.exception('测试用例请求失败,原因:{}'.format(e))

メイン実行:

Pytest と Allure の機能を使用して、コマンド ラインでテスト ケース フォルダーを実行し、対応する Allure テスト レポートを生成します。

if __name__ == "__main__":
	pytest.main(['-s', '-v', 'test_case/testRequest/', '-q', '--alluredir', 'reports'])

Alluer2 テストレポート

main 関数を実行して対応するテスト ケース レポートを生成すると、対応する json ファイルのテスト レポートがこのフォルダーに生成されることがわかります。

reports は、json 形式のテスト レポートが保存されるディレクトリの場所であり、allure_reports は、html テスト レポート ファイルが生成されるディレクトリの場所です。アリュールコマンドは以下の通りです。

allure generate reports -o allure_result/

プロジェクトのルート ディレクトリにある allure_reports ファイルには、allure によって生成されたテスト レポートが保存されます。ファイルの下に HTML ファイルがあることがわかります。HTML ファイル (テスト レポート) は Python エディター Pycharm で開くことができ、HTML は allure コマンドで開くことができます。

以下は、私がまとめた 2023 年の最も完全なソフトウェア テスト エンジニア学習知識アーキテクチャ システム図です。

1. Pythonプログラミングの入門から習得まで

画像の説明を追加してください

2.インターフェース自動化プロジェクトの実戦

画像の説明を追加してください

3. Web自動化プロジェクトの実戦

画像の説明を追加してください

4. アプリ自動化プロジェクトの実戦

画像の説明を追加してください

5. 一流メーカーの再開

画像の説明を追加してください

6. DevOps システムのテストと開発

画像の説明を追加してください

7. 一般的に使用される自動テストツール

画像の説明を追加してください

8、JMeterのパフォーマンステスト

画像の説明を追加してください

9. まとめ(最後にちょっとしたサプライズ)

勇敢に頂上に登る、決して諦めない、その闘いの旅は花が咲くようなもの、旅の向こう、限界を越えて、努力の力が輝かしい人生を生み出す。自分の可能性を信じ、内なる炎を解放し、汗と努力で輝かしい道を切り開いてください。

棘と波を乗り越え、努力は人生で最も壮大な交響曲であり、限界を超えて勇敢に前進する夢は最も美しい魂の翼である。粘り強さを信じて、光を追い、未来の星空を照らすために努力し、あなた自身の輝かしい章を書きましょう。

苦難を恐れず、もがき、胸の星と海を追い求め、挑戦を受け入れ、限界を超え、あらゆる努力が成長の足跡となる。自分の力を信じ、情熱を燃やして、輝く人生を自分で切り開いてください。

おすすめ

転載: blog.csdn.net/m0_70102063/article/details/132043356