色五月色开心色婷婷色丁香,五月婷婷丁香花综合网,婷婷丁香五月激情综合在线,五月婷婷六月丁香动漫,婷婷丁香五月激情综合在线,丁香花中文字幕在线观看,播五月色五月开心五月网,开心激情综合网,狠狠色丁香婷婷综合最新地址,丁香视频在线观看,狠狠做六月爱婷婷综合av,久久激情五月丁香伊人

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

基于pytest+JSON Schema的數(shù)據(jù)驅(qū)動(dòng)接口自動(dòng)化測(cè)試實(shí)戰(zhàn)

基于pytest+JSON Schema的數(shù)據(jù)驅(qū)動(dòng)接口自動(dòng)化測(cè)試實(shí)戰(zhàn) 1. 項(xiàng)目概述當(dāng)數(shù)據(jù)驅(qū)動(dòng)測(cè)試遇上契約驗(yàn)證如果你正在做接口自動(dòng)化測(cè)試或者任何需要處理大量輸入輸出數(shù)據(jù)的自動(dòng)化測(cè)試那么“數(shù)據(jù)驅(qū)動(dòng)”這個(gè)詞你一定不陌生。簡(jiǎn)單來(lái)說(shuō)就是把測(cè)試數(shù)據(jù)和測(cè)試邏輯分離讓同一個(gè)測(cè)試邏輯可以跑在不同的數(shù)據(jù)上。這聽起來(lái)很美但實(shí)際操作中我們常常會(huì)遇到兩個(gè)頭疼的問(wèn)題第一如何優(yōu)雅地管理這些海量的測(cè)試數(shù)據(jù)第二如何高效地驗(yàn)證返回的數(shù)據(jù)結(jié)構(gòu)是否符合預(yù)期而不是寫一堆冗長(zhǎng)且脆弱的斷言我最近在一個(gè)大型微服務(wù)項(xiàng)目中就深度實(shí)踐了pytestAllureJSON Schema這套組合拳完美地解決了上述痛點(diǎn)。它不僅僅是“能用”而是形成了一套從數(shù)據(jù)準(zhǔn)備、用例執(zhí)行到結(jié)果驗(yàn)證和報(bào)告生成的完整工作流。pytest提供了強(qiáng)大的參數(shù)化能力和靈活的插件生態(tài)Allure負(fù)責(zé)生成直觀、美觀的測(cè)試報(bào)告讓測(cè)試結(jié)果一目了然而JSON Schema則扮演了“數(shù)據(jù)契約”的角色用一種聲明式的方式定義數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)自動(dòng)、精準(zhǔn)的驗(yàn)證。這套方案的核心價(jià)值在于它將測(cè)試工程師從繁瑣的“數(shù)據(jù)搬運(yùn)工”和“斷言泥潭”中解放出來(lái)。你不再需要為每一個(gè)測(cè)試用例寫一堆a(bǔ)ssert response[‘data’][‘user’][‘name’] ‘xxx’只需要定義好一個(gè)JSON Schema所有符合該接口契約的響應(yīng)都會(huì)被自動(dòng)驗(yàn)證。當(dāng)業(yè)務(wù)接口字段成百上千時(shí)這種效率的提升是顛覆性的。接下來(lái)我就把這套經(jīng)過(guò)實(shí)戰(zhàn)檢驗(yàn)的方案從設(shè)計(jì)思路到踩坑細(xì)節(jié)完整地分享給你。2. 核心工具鏈選型與設(shè)計(jì)思路為什么是這三個(gè)工具的組合而不是unittestHTMLTestRunner 手動(dòng)斷言這背后是一套關(guān)于效率、可維護(hù)性和可視化程度的綜合考量。2.1 pytest不止是測(cè)試框架更是執(zhí)行引擎pytest之所以成為 Python 自動(dòng)化測(cè)試的事實(shí)標(biāo)準(zhǔn)遠(yuǎn)不止因?yàn)樗萿nittest寫起來(lái)更簡(jiǎn)潔。在數(shù)據(jù)驅(qū)動(dòng)測(cè)試的語(yǔ)境下它的兩大特性無(wú)可替代強(qiáng)大的參數(shù)化裝飾器 (pytest.mark.parametrize)這是實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)的基石。它允許你將一個(gè)測(cè)試函數(shù)與多組參數(shù)綁定每組參數(shù)都會(huì)獨(dú)立運(yùn)行一次測(cè)試。更關(guān)鍵的是它支持從文件如 JSON, YAML, CSV、甚至從自定義函數(shù)中動(dòng)態(tài)讀取參數(shù)這為我們從外部管理測(cè)試數(shù)據(jù)提供了極大的靈活性。豐富的 Fixture 機(jī)制測(cè)試前置條件如初始化數(shù)據(jù)庫(kù)連接、獲取 Token、后置清理、以及測(cè)試數(shù)據(jù)的作用域管理都可以通過(guò) Fixture 優(yōu)雅地實(shí)現(xiàn)。例如我們可以定義一個(gè)schema_validator的 Fixture在整個(gè)測(cè)試會(huì)話期間只加載一次 JSON Schema 文件避免重復(fù) IO 開銷。我的設(shè)計(jì)思路是將測(cè)試邏輯API 調(diào)用、業(yè)務(wù)斷言固化在測(cè)試函數(shù)中而將測(cè)試輸入數(shù)據(jù)和期望的 JSON Schema 定義通過(guò)parametrize以參數(shù)的形式“注入”到測(cè)試函數(shù)中。這樣測(cè)試函數(shù)本身變得非常干凈和穩(wěn)定數(shù)據(jù)的變動(dòng)完全不影響代碼。2.2 Allure測(cè)試報(bào)告的藝術(shù)品測(cè)試執(zhí)行完了結(jié)果呢如果只是控制臺(tái)輸出PASS或FAIL對(duì)于排查問(wèn)題、尤其是向非技術(shù)人員展示測(cè)試覆蓋率時(shí)是遠(yuǎn)遠(yuǎn)不夠的。Allure報(bào)告的價(jià)值體現(xiàn)在用例與數(shù)據(jù)的完美綁定在 Allure 報(bào)告中被parametrize參數(shù)化的用例每一組數(shù)據(jù)都會(huì)作為一個(gè)獨(dú)立的測(cè)試步驟展示并清晰標(biāo)明傳入的參數(shù)值。當(dāng)某個(gè)用例失敗時(shí)你能立刻看到是哪一個(gè)數(shù)據(jù)組合導(dǎo)致的失敗。豐富的附件支持我們可以在測(cè)試過(guò)程中輕松地將請(qǐng)求數(shù)據(jù)、響應(yīng)內(nèi)容、甚至是驗(yàn)證失敗的詳細(xì)差異以文本或 JSON 格式附加到 Allure 報(bào)告中。這對(duì)于調(diào)試復(fù)雜的數(shù)據(jù)結(jié)構(gòu)問(wèn)題至關(guān)重要。歷史趨勢(shì)與儀表盤Allure 可以聚合多次測(cè)試運(yùn)行的結(jié)果生成歷史趨勢(shì)圖直觀展示測(cè)試穩(wěn)定性和健康度。在我們的方案中Allure 不僅是結(jié)果展示窗口更是問(wèn)題定位的“第一現(xiàn)場(chǎng)”。我們會(huì)將每次驗(yàn)證的 Schema 和實(shí)際響應(yīng)數(shù)據(jù)都附加到報(bào)告中做到有跡可循。2.3 JSON Schema聲明式的數(shù)據(jù)契約這是本方案中最具“智慧”的部分。傳統(tǒng)斷言是命令式的“檢查 A 字段等于 1B 字段是字符串C 字段是個(gè)數(shù)組且長(zhǎng)度大于0”。而 JSON Schema 是聲明式的“我定義一份契約描述數(shù)據(jù)應(yīng)該長(zhǎng)什么樣類型、必填、格式、枚舉、嵌套結(jié)構(gòu)等你來(lái)幫我檢查數(shù)據(jù)是否符合這份契約?!笔褂胘sonschema這個(gè) Python 庫(kù)驗(yàn)證變得異常簡(jiǎn)單import jsonschema from jsonschema import validate # 定義schema schema { “type”: “object”, “properties”: { “code”: {“type”: “integer”, “const”: 0}, # code必須為整數(shù)且恒等于0 “message”: {“type”: “string”}, “data”: { “type”: “object”, “properties”: { “userId”: {“type”: “integer”, “minimum”: 1}, “userName”: {“type”: “string”, “pattern”: “^[a-zA-Z][a-zA-Z0-9_]{3,15}$”} # 正則匹配用戶名格式 }, “required”: [“userId”, “userName”] # data對(duì)象中必須包含這兩個(gè)字段 } }, “required”: [“code”, “message”, “data”] } # 驗(yàn)證數(shù)據(jù) response_data {“code”: 0, “message”: “success”, “data”: {“userId”: 123, “userName”: “test_user”}} try: validate(instanceresponse_data, schemaschema) print(“數(shù)據(jù)驗(yàn)證通過(guò)”) except jsonschema.exceptions.ValidationError as e: print(f“數(shù)據(jù)驗(yàn)證失敗: {e.message}”)設(shè)計(jì)思路的核心轉(zhuǎn)變從“如何斷言”變?yōu)椤叭绾味x契約”。我們將每個(gè)接口的響應(yīng)契約Schema單獨(dú)維護(hù)成 JSON/YAML 文件與測(cè)試數(shù)據(jù)放在一起。測(cè)試函數(shù)只需要調(diào)用通用的驗(yàn)證器而不需要關(guān)心具體字段。當(dāng)接口字段變更時(shí)我們只需更新對(duì)應(yīng)的 Schema 文件所有相關(guān)測(cè)試用例的驗(yàn)證邏輯就自動(dòng)同步更新了維護(hù)成本極低。3. 項(xiàng)目結(jié)構(gòu)設(shè)計(jì)與核心模塊解析一個(gè)清晰的項(xiàng)目結(jié)構(gòu)是保證可維護(hù)性的前提。下面是我推薦并經(jīng)過(guò)實(shí)踐的結(jié)構(gòu)project_root/ ├── tests/ # 測(cè)試用例目錄 │ ├── conftest.py # pytest 共享 fixture 定義 │ ├── test_api_user.py # 用戶相關(guān)接口測(cè)試 │ └── test_api_order.py # 訂單相關(guān)接口測(cè)試 ├── test_data/ # 測(cè)試數(shù)據(jù)與契約目錄 │ ├── schemas/ # JSON Schema 文件 │ │ ├── user_login_schema.json │ │ ├── user_info_schema.json │ │ └── order_create_schema.json │ └── cases/ # 參數(shù)化測(cè)試數(shù)據(jù)文件 │ ├── user_login_cases.yaml │ ├── user_info_cases.yaml │ └── order_create_cases.yaml ├── core/ # 核心業(yè)務(wù)封裝 │ ├── __init__.py │ ├── api_client.py # 封裝的 HTTP 請(qǐng)求客戶端 │ └── validator.py # 基于 jsonschema 的通用驗(yàn)證器 ├── utils/ # 工具函數(shù) │ ├── data_loader.py # 加載 YAML/JSON 測(cè)試數(shù)據(jù) │ └── allure_attachment.py # Allure 報(bào)告附件相關(guān)工具 ├── pytest.ini # pytest 配置文件 ├── requirements.txt # 項(xiàng)目依賴 └── README.md3.1 核心模塊通用驗(yàn)證器 (core/validator.py)這個(gè)模塊是整個(gè)自動(dòng)驗(yàn)證體系的大腦。它的職責(zé)是加載 Schema 并執(zhí)行驗(yàn)證同時(shí)提供友好的錯(cuò)誤信息和 Allure 附件。import json import jsonschema from jsonschema import Draft7Validator, ValidationError import allure from pathlib import Path class SchemaValidator: JSON Schema 驗(yàn)證器封裝了驗(yàn)證和報(bào)告邏輯 # 緩存已加載的schema避免重復(fù)讀取文件 _schema_cache {} def __init__(self, schema_dir: str “test_data/schemas”): self.schema_dir Path(schema_dir) def load_schema(self, schema_name: str) - dict: 根據(jù)名稱加載schema文件支持緩存 if schema_name not in self._schema_cache: schema_file self.schema_dir / f“{schema_name}.json” if not schema_file.exists(): raise FileNotFoundError(f“Schema 文件未找到: {schema_file}”) with open(schema_file, ‘r’, encoding‘utf-8’) as f: self._schema_cache[schema_name] json.load(f) return self._schema_cache[schema_name] def validate_response(self, response_data: dict, schema_name: str, description: str “響應(yīng)數(shù)據(jù)驗(yàn)證”) - bool: 驗(yàn)證響應(yīng)數(shù)據(jù)是否符合指定的schema并將結(jié)果附加到Allure報(bào)告。 Args: response_data: 待驗(yàn)證的響應(yīng)數(shù)據(jù)字典 schema_name: schema文件名不含擴(kuò)展名 description: 在Allure報(bào)告中顯示的描述 Returns: bool: 驗(yàn)證是否通過(guò) try: schema self.load_schema(schema_name) # 使用 Draft7Validator 可以提供更詳細(xì)的錯(cuò)誤信息 validator Draft7Validator(schema) errors list(validator.iter_errors(response_data)) if errors: # 驗(yàn)證失敗收集所有錯(cuò)誤信息 error_messages [] for error in errors: # 錯(cuò)誤路徑例如 ‘data.user.name’ path “-”.join([str(p) for p in error.path]) if error.path else “根節(jié)點(diǎn)” error_messages.append(f“路徑 [{path}]: {error.message}”) error_summary “\n”.join(error_messages) full_context ( f“ Schema 驗(yàn)證失敗 \n” f“Schema文件: {schema_name}.json\n” f“驗(yàn)證描述: {description}\n\n” f“詳細(xì)錯(cuò)誤:\n{error_summary}\n\n” f“— 實(shí)際響應(yīng)數(shù)據(jù) —\n{json.dumps(response_data, indent2, ensure_asciiFalse)}\n\n” f“— 期望的 Schema —\n{json.dumps(schema, indent2, ensure_asciiFalse)}” ) # 將詳細(xì)的錯(cuò)誤上下文附加為Allure的文本附件 allure.attach( bodyfull_context, namef“Schema驗(yàn)證失敗-{schema_name}”, attachment_typeallure.attachment_type.TEXT ) # 也可以附加純凈的JSON方便查看 allure.attach( bodyjson.dumps(response_data, indent2, ensure_asciiFalse), name“實(shí)際響應(yīng)JSON”, attachment_typeallure.attachment_type.JSON ) raise AssertionError(f“響應(yīng)數(shù)據(jù)不符合 Schema ‘{schema_name}’ 規(guī)范。詳情請(qǐng)查看Allure報(bào)告附件?!? else: # 驗(yàn)證成功也可以在報(bào)告中附加成功信息可選 allure.attach( bodyjson.dumps(response_data, indent2, ensure_asciiFalse), name“已驗(yàn)證的響應(yīng)JSON”, attachment_typeallure.attachment_type.JSON ) return True except FileNotFoundError as e: allure.attach(bodystr(e), name“Schema文件缺失”, attachment_typeallure.attachment_type.TEXT) raise except json.JSONDecodeError as e: allure.attach(bodystr(e), name“JSON解析錯(cuò)誤”, attachment_typeallure.attachment_type.TEXT) raise關(guān)鍵設(shè)計(jì)點(diǎn)緩存機(jī)制_schema_cache避免了在大量測(cè)試用例中重復(fù)讀取磁盤上的 Schema 文件顯著提升測(cè)試速度。詳盡的錯(cuò)誤報(bào)告使用Draft7Validator.iter_errors()可以收集所有驗(yàn)證錯(cuò)誤而不是在第一個(gè)錯(cuò)誤處就停止。這能讓我們?cè)谝淮螠y(cè)試運(yùn)行中看到所有不符合契約的地方。Allure 集成無(wú)論是成功還是失敗都將關(guān)鍵數(shù)據(jù)Schema、實(shí)際響應(yīng)、錯(cuò)誤詳情附加到報(bào)告中。這相當(dāng)于為每個(gè)驗(yàn)證點(diǎn)自動(dòng)生成了“排查日志”定位問(wèn)題效率極高。3.2 核心模塊測(cè)試數(shù)據(jù)加載器 (utils/data_loader.py)為了靈活支持 YAML 和 JSON 格式的測(cè)試數(shù)據(jù)我們需要一個(gè)通用的加載器。import yaml import json import os from pathlib import Path from typing import Any, Union def load_test_cases(file_path: Union[str, Path]) - list: 根據(jù)文件擴(kuò)展名自動(dòng)加載 YAML 或 JSON 格式的測(cè)試用例數(shù)據(jù)。 Args: file_path: 測(cè)試數(shù)據(jù)文件的路徑 Returns: list: 測(cè)試用例列表每個(gè)元素通常是一個(gè)字典代表一組參數(shù)。 Raises: ValueError: 文件格式不支持或文件內(nèi)容不是列表。 file_path Path(file_path) if not file_path.exists(): raise FileNotFoundError(f“測(cè)試數(shù)據(jù)文件不存在: {file_path}”) with open(file_path, ‘r’, encoding‘utf-8’) as f: if file_path.suffix.lower() in [‘.yaml’, ‘.yml’]: data yaml.safe_load(f) elif file_path.suffix.lower() ‘.json’: data json.load(f) else: raise ValueError(f“不支持的測(cè)試數(shù)據(jù)文件格式: {file_path.suffix}。請(qǐng)使用 .yaml, .yml 或 .json。”) # 確保加載的數(shù)據(jù)是一個(gè)列表便于參數(shù)化 if not isinstance(data, list): raise ValueError(f“測(cè)試數(shù)據(jù)文件 {file_path} 的根元素必須是列表 (list)但實(shí)際是 {type(data)}。”) return data為什么用 YAML對(duì)于編寫測(cè)試數(shù)據(jù)來(lái)說(shuō)YAML 格式往往比 JSON 更友好。它支持注釋字符串不需要引號(hào)結(jié)構(gòu)通過(guò)縮進(jìn)表示寫起來(lái)更簡(jiǎn)潔直觀。例如# test_data/cases/user_login_cases.yaml - case_id: “l(fā)ogin_success” description: “使用正確的用戶名和密碼登錄” request_data: username: “test_user” password: “123456” expected_schema: “user_login_success_schema” # 對(duì)應(yīng) test_data/schemas/ 下的文件名 extra_assertions: # 除了Schema驗(yàn)證外可能還有額外的業(yè)務(wù)斷言 - field: “data.token” expected_type: “string” min_length: 32 - case_id: “l(fā)ogin_fail_wrong_password” description: “使用錯(cuò)誤密碼登錄” request_data: username: “test_user” password: “wrong” expected_schema: “user_login_fail_schema” expected_status_code: 4013.3 核心 Fixture 定義 (tests/conftest.py)conftest.py是 pytest 的“魔法”文件其中定義的 Fixture 可以被該目錄及其子目錄下的所有測(cè)試文件共享。import pytest from core.validator import SchemaValidator from core.api_client import ApiClient import allure pytest.fixture(scope“session”) def validator(): 返回一個(gè)全局的 Schema 驗(yàn)證器實(shí)例整個(gè)測(cè)試會(huì)話只初始化一次。 return SchemaValidator(schema_dir“test_data/schemas”) pytest.fixture(scope“function”) # 默認(rèn)就是function級(jí)別每個(gè)測(cè)試函數(shù)運(yùn)行一次 def api_client(): 返回一個(gè)配置好的 API 請(qǐng)求客戶端實(shí)例。 client ApiClient(base_url“https://api.your-service.com”) # 這里可以添加全局的請(qǐng)求頭如認(rèn)證信息 client.set_common_headers({“Content-Type”: “application/json”}) yield client # 使用yield實(shí)現(xiàn)測(cè)試后的清理工作如果需要 # 測(cè)試結(jié)束后可以在這里關(guān)閉會(huì)話或清理資源 client.close() pytest.hookimpl(tryfirstTrue, hookwrapperTrue) def pytest_runtest_makereport(item, call): pytest鉤子用于在測(cè)試執(zhí)行的不同階段獲取結(jié)果并動(dòng)態(tài)附加信息到Allure。 例如可以在測(cè)試失敗時(shí)額外附加一些自定義的診斷信息。 outcome yield report outcome.get_result() # 如果測(cè)試失敗了并且我們有額外的失敗信息存儲(chǔ)在item中可以附加到Allure if report.when “call” and report.failed: # 這里只是一個(gè)示例你可以根據(jù)實(shí)際需要存儲(chǔ)和附加任何信息 if hasattr(item, “_test_failure_context”): allure.attach( bodyitem._test_failure_context, name“自定義失敗上下文”, attachment_typeallure.attachment_type.TEXT )4. 測(cè)試用例編寫實(shí)戰(zhàn)參數(shù)化與驗(yàn)證的融合有了前面的基礎(chǔ)建設(shè)編寫實(shí)際的測(cè)試用例就變得非常清晰和高效了。我們以用戶登錄接口為例。首先定義登錄成功和失敗的 Schematest_data/schemas/user_login_success_schema.json{ “$schema”: “http://json-schema.org/draft-07/schema#”, “title”: “用戶登錄成功響應(yīng)”, “type”: “object”, “properties”: { “code”: { “type”: “integer”, “const”: 0, “description”: “狀態(tài)碼0表示成功” }, “message”: { “type”: “string”, “pattern”: “^success|成功$”, “description”: “成功消息” }, “data”: { “type”: “object”, “properties”: { “userId”: { “type”: “integer”, “minimum”: 1, “description”: “用戶ID” }, “username”: { “type”: “string”, “minLength”: 1, “description”: “用戶名” }, “token”: { “type”: “string”, “minLength”: 32, “description”: “認(rèn)證令牌” }, “expiresIn”: { “type”: “integer”, “minimum”: 3600, “description”: “令牌過(guò)期時(shí)間秒” } }, “required”: [“userId”, “username”, “token”, “expiresIn”], “additionalProperties”: false, // 禁止出現(xiàn)未在properties中定義的字段 “description”: “響應(yīng)數(shù)據(jù)體” } }, “required”: [“code”, “message”, “data”], “additionalProperties”: false }test_data/schemas/user_login_fail_schema.json{ “$schema”: “http://json-schema.org/draft-07/schema#”, “title”: “用戶登錄失敗響應(yīng)”, “type”: “object”, “properties”: { “code”: { “type”: “integer”, “enum”: [401, 400], “description”: “錯(cuò)誤狀態(tài)碼” }, “message”: { “type”: “string”, “minLength”: 1, “description”: “錯(cuò)誤信息” }, “data”: { “type”: “null”, “description”: “失敗時(shí)數(shù)據(jù)通常為null” } }, “required”: [“code”, “message”, “data”], “additionalProperties”: false }接著編寫測(cè)試用例文件tests/test_api_user.pyimport pytest import allure from utils.data_loader import load_test_cases # 加載YAML格式的測(cè)試用例數(shù)據(jù) LOGIN_TEST_CASES load_test_cases(“test_data/cases/user_login_cases.yaml”) allure.epic(“用戶服務(wù)”) allure.feature(“用戶登錄”) class TestUserLogin: allure.story(“登錄功能驗(yàn)證”) allure.title(“登錄測(cè)試 - {case[‘description’]}”) # 使用參數(shù)動(dòng)態(tài)生成標(biāo)題 pytest.mark.parametrize(“case”, LOGIN_TEST_CASES, idslambda c: c[“case_id”]) def test_user_login(self, case, api_client, validator): 用戶登錄接口測(cè)試。 通過(guò) pytest.mark.parametrize 實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)。 每組數(shù)據(jù)都會(huì)獨(dú)立運(yùn)行一次該測(cè)試函數(shù)。 # 1. 打印當(dāng)前運(yùn)行的用例信息可選便于調(diào)試 allure.dynamic.description(case.get(“description”, “”)) print(f“正在執(zhí)行用例: {case[‘case_id’]}”) # 2. 準(zhǔn)備請(qǐng)求數(shù)據(jù) request_data case[“request_data”] expected_schema_name case[“expected_schema”] # 3. 發(fā)送請(qǐng)求 with allure.step(“發(fā)送登錄請(qǐng)求”): # 使用封裝的api_client發(fā)送請(qǐng)求它會(huì)自動(dòng)處理日志和基礎(chǔ)異常 response api_client.post(“/v1/user/login”, jsonrequest_data) # 將請(qǐng)求和響應(yīng)詳情附加到Allure報(bào)告 allure.attach( bodystr(request_data), name“請(qǐng)求數(shù)據(jù)”, attachment_typeallure.attachment_type.JSON ) allure.attach( bodyresponse.text, name“響應(yīng)原始數(shù)據(jù)”, attachment_typeallure.attachment_type.TEXT ) # 4. 驗(yàn)證HTTP狀態(tài)碼如果用例中指定了 expected_status case.get(“expected_status_code”) if expected_status is not None: with allure.step(f“驗(yàn)證HTTP狀態(tài)碼是否為{expected_status}”): assert response.status_code expected_status, \ f“狀態(tài)碼不符。期望: {expected_status}, 實(shí)際: {response.status_code}” # 5. 解析響應(yīng)JSON try: response_json response.json() except ValueError as e: allure.attach(bodyresponse.text, name“無(wú)效JSON響應(yīng)”, attachment_typeallure.attachment_type.TEXT) pytest.fail(f“響應(yīng)不是有效的JSON格式: {e}”) # 6. 使用Validator進(jìn)行JSON Schema驗(yàn)證核心步驟 with allure.step(f“使用Schema ‘{expected_schema_name}’ 驗(yàn)證響應(yīng)數(shù)據(jù)結(jié)構(gòu)”): # 這里會(huì)觸發(fā)我們之前定義的validate_response方法自動(dòng)處理驗(yàn)證和報(bào)告 is_valid validator.validate_response( response_dataresponse_json, schema_nameexpected_schema_name, descriptionf“登錄用例 ‘{case[‘case_id’]}’ 響應(yīng)驗(yàn)證” ) # validate_response在失敗時(shí)會(huì)拋出AssertionError所以如果執(zhí)行到這里說(shuō)明驗(yàn)證通過(guò)。 # 但為了邏輯清晰我們依然可以斷言一下。 assert is_valid, “響應(yīng)數(shù)據(jù)Schema驗(yàn)證失敗詳情見Allure報(bào)告” # 7. 額外的業(yè)務(wù)邏輯斷言可選 # 有時(shí)Schema驗(yàn)證了結(jié)構(gòu)但還需要驗(yàn)證具體的業(yè)務(wù)值。 extra_assertions case.get(“extra_assertions”, []) for assertion in extra_assertions: field_path assertion[“field”] expected_type assertion.get(“expected_type”) # 這里可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的字段提取和斷言邏輯 # 例如驗(yàn)證 data.token 的長(zhǎng)度 # 這部分可以根據(jù)項(xiàng)目需要擴(kuò)展 # 8. 如果測(cè)試成功可以附加一些成功信息可選 allure.attach( bodyf“用例 ‘{case[‘case_id’]}’ 所有驗(yàn)證均已通過(guò)?!? name“測(cè)試通過(guò)摘要”, attachment_typeallure.attachment_type.TEXT )這段代碼的精華解讀pytest.mark.parametrize(“case”, LOGIN_TEST_CASES, idslambda c: c[“case_id”])“case”參數(shù)名稱在測(cè)試函數(shù)中可以直接使用。LOGIN_TEST_CASES一個(gè)列表里面每個(gè)元素字典就是一組測(cè)試數(shù)據(jù)。idslambda c: c[“case_id”]為每一組參數(shù)化測(cè)試設(shè)置一個(gè)唯一的標(biāo)識(shí)符這個(gè)標(biāo)識(shí)符會(huì)顯示在 pytest 的輸出和 Allure 報(bào)告中讓你一眼就知道是哪個(gè)數(shù)據(jù)組合在運(yùn)行或失敗。allure.dynamic裝飾器Allure 提供了動(dòng)態(tài)設(shè)置測(cè)試特征的方法比如allure.title可以根據(jù)用例數(shù)據(jù)動(dòng)態(tài)生成易讀的測(cè)試標(biāo)題allure.description可以添加詳細(xì)描述讓報(bào)告更具可讀性。with allure.step()這是一個(gè)上下文管理器用于在 Allure 報(bào)告中創(chuàng)建一個(gè)步驟。它將測(cè)試邏輯塊包裹起來(lái)在報(bào)告中會(huì)呈現(xiàn)為可折疊的步驟樹使得測(cè)試執(zhí)行過(guò)程一目了然非常利于排查是哪個(gè)步驟出了問(wèn)題。驗(yàn)證流程清晰的步驟分離——發(fā)送請(qǐng)求、檢查狀態(tài)碼、解析 JSON、Schema 驗(yàn)證、額外斷言。每一步的失敗都有明確的錯(cuò)誤信息和 Allure 附件形成了強(qiáng)大的問(wèn)題定位能力。5. 運(yùn)行測(cè)試與生成報(bào)告編寫完測(cè)試用例后如何運(yùn)行并看到漂亮的報(bào)告呢5.1 運(yùn)行測(cè)試在項(xiàng)目根目錄下使用 pytest 命令運(yùn)行測(cè)試。這里有一些常用的參數(shù)# 運(yùn)行所有測(cè)試 pytest # 運(yùn)行特定文件或目錄 pytest tests/test_api_user.py # 運(yùn)行帶有特定標(biāo)記的測(cè)試?yán)鐦?biāo)記為‘smoke’的冒煙測(cè)試 pytest -m smoke # 運(yùn)行并輸出詳細(xì)日志 pytest -v # 在失敗時(shí)立即停止并進(jìn)入PDB調(diào)試如果需要 pytest -x --pdb為了與 Allure 配合我們需要在運(yùn)行測(cè)試時(shí)生成 Allure 所需的原始結(jié)果數(shù)據(jù)通常是一個(gè)allure-results目錄。# 運(yùn)行測(cè)試并生成Allure結(jié)果數(shù)據(jù) pytest --alluredir./allure-results5.2 生成與查看 Allure 報(bào)告Allure 報(bào)告是一個(gè)獨(dú)立的服務(wù)。首先你需要安裝 Allure 命令行工具具體安裝方法請(qǐng)參考其官網(wǎng)。生成報(bào)告分為兩步從結(jié)果數(shù)據(jù)生成 HTML 報(bào)告allure generate ./allure-results -o ./allure-report --clean./allure-results上一步 pytest 生成的結(jié)果目錄。-o ./allure-report指定生成的 HTML 報(bào)告輸出目錄。--clean清空輸出目錄如果已存在。打開報(bào)告allure open ./allure-report這條命令會(huì)在你的默認(rèn)瀏覽器中打開生成的 HTML 報(bào)告。報(bào)告亮點(diǎn)概覽頁(yè)可以看到測(cè)試套件的總體通過(guò)率、持續(xù)時(shí)間、趨勢(shì)圖。套件頁(yè)以樹形結(jié)構(gòu)展示所有測(cè)試類和方法被參數(shù)化的用例會(huì)展開顯示每個(gè)參數(shù)組合的結(jié)果。用例詳情頁(yè)點(diǎn)擊單個(gè)用例可以看到我們通過(guò)allure.step定義的步驟、通過(guò)allure.attach附加的請(qǐng)求/響應(yīng)數(shù)據(jù)、Schema 驗(yàn)證詳情以及任何斷言失敗的信息。當(dāng) Schema 驗(yàn)證失敗時(shí)我們附加的詳細(xì)錯(cuò)誤上下文會(huì)直接顯示在這里你無(wú)需再去翻看日志文件。6. 高級(jí)技巧與避坑指南在實(shí)際項(xiàng)目中摸爬滾打總會(huì)遇到一些坑。這里分享幾個(gè)關(guān)鍵的經(jīng)驗(yàn)和技巧。6.1 Schema 的設(shè)計(jì)與管理技巧使用$ref引用實(shí)現(xiàn)復(fù)用當(dāng)多個(gè)接口有相同的子結(jié)構(gòu)時(shí)比如分頁(yè)信息pageInfo不要重復(fù)定義??梢詣?chuàng)建一個(gè)common_schemas.json文件然后在其他 Schema 中引用。// common_schemas.json { “definitions”: { “pagination”: { “type”: “object”, “properties”: { “page”: {“type”: “integer”, “minimum”: 1}, “size”: {“type”: “integer”, “minimum”: 1, “maximum”: 100}, “total”: {“type”: “integer”, “minimum”: 0} }, “required”: [“page”, “size”, “total”] } } } // user_list_schema.json { “$schema”: “http://json-schema.org/draft-07/schema#”, “type”: “object”, “properties”: { “code”: {“type”: “integer”, “const”: 0}, “data”: { “type”: “array”, “items”: {“$ref”: “#/definitions/user”} }, “pageInfo”: {“$ref”: “./common_schemas.json#/definitions/pagination”} }, “required”: [“code”, “data”, “pageInfo”] }使用jsonschema.RefResolver或在驗(yàn)證時(shí)指定base_uri來(lái)解析這些引用。合理使用additionalProperties: false這是一個(gè)雙刃劍。設(shè)置為false可以嚴(yán)格限制響應(yīng)中不能出現(xiàn)未定義的字段有助于發(fā)現(xiàn)后端無(wú)意中返回的多余字段。但在接口演進(jìn)初期或字段頻繁變動(dòng)時(shí)可能會(huì)造成測(cè)試用例不必要的失敗。建議在穩(wěn)定期或?qū)涌谄跫s要求嚴(yán)格的場(chǎng)景下使用。為字段添加description在 Schema 中為每個(gè)屬性添加description字段。這不僅是良好的文檔一些工具如生成的 API 文檔也能利用它。當(dāng)驗(yàn)證失敗時(shí)清晰的描述能幫你更快理解這個(gè)字段是干什么的。6.2 參數(shù)化數(shù)據(jù)的靈活運(yùn)用動(dòng)態(tài)生成測(cè)試數(shù)據(jù)有時(shí)測(cè)試數(shù)據(jù)不能完全寫死在文件里。例如注冊(cè)用戶需要一個(gè)唯一的用戶名。你可以在conftest.py中定義一個(gè) Fixture 來(lái)動(dòng)態(tài)生成數(shù)據(jù)然后在pytest.mark.parametrize中引用這個(gè) Fixture。import pytest import uuid pytest.fixture def unique_username(): return f“test_user_{uuid.uuid4().hex[:8]}” # 在參數(shù)化中可以通過(guò)間接參數(shù)化(indirect)來(lái)使用fixture pytest.mark.parametrize(“username”, [“user1”, “user2”], indirectTrue) def test_something(username): print(username) # 這里會(huì)得到fixture生成的值更常見的做法是在加載 YAML 數(shù)據(jù)后用一個(gè)函數(shù)遍歷數(shù)據(jù)動(dòng)態(tài)替換其中的占位符如{{timestamp}},{{random_string}}。處理依賴用例用例 B 需要用例 A 產(chǎn)生的數(shù)據(jù)如 Token。不要嘗試在參數(shù)化數(shù)據(jù)中硬編碼。應(yīng)該將獲取 Token 的邏輯封裝成一個(gè) Fixture如user_token并設(shè)置適當(dāng)?shù)?scope如session或module。在測(cè)試類或測(cè)試函數(shù)中直接使用這個(gè) Fixture。如果必須參數(shù)化可以考慮使用pytest的indirect參數(shù)化或者將依賴數(shù)據(jù)作為 Fixture 的返回值然后在測(cè)試函數(shù)中與其他參數(shù)化數(shù)據(jù)組合使用。但通常依賴關(guān)系強(qiáng)的測(cè)試更適合用 Fixture 管理前置狀態(tài)而不是純粹的數(shù)據(jù)驅(qū)動(dòng)。6.3 Allure 報(bào)告的優(yōu)化定制報(bào)告外觀你可以創(chuàng)建一個(gè)categories.json文件對(duì)測(cè)試失敗的原因進(jìn)行分類如產(chǎn)品缺陷、自動(dòng)化腳本問(wèn)題、環(huán)境問(wèn)題等讓報(bào)告更有分析價(jià)值。環(huán)境信息在運(yùn)行測(cè)試時(shí)通過(guò)環(huán)境變量或配置文件記錄測(cè)試環(huán)境如測(cè)試服務(wù)器地址、數(shù)據(jù)庫(kù)版本、測(cè)試執(zhí)行時(shí)間等并使用 Allure 的environment.properties文件或相關(guān)插件將其展示在報(bào)告首頁(yè)。歷史趨勢(shì)將每次運(yùn)行的allure-results目錄歸檔并使用 Allure 的聚合功能生成歷史趨勢(shì)報(bào)告這對(duì)于監(jiān)控測(cè)試穩(wěn)定性和項(xiàng)目健康度非常有幫助。6.4 常見問(wèn)題排查Schema 驗(yàn)證錯(cuò)誤信息不直觀jsonschema的默認(rèn)錯(cuò)誤信息有時(shí)比較技術(shù)化??梢跃帉懸粋€(gè)自定義的錯(cuò)誤格式化函數(shù)將ValidationError對(duì)象轉(zhuǎn)換成更業(yè)務(wù)友好的中文描述再附加到 Allure 報(bào)告中。測(cè)試數(shù)據(jù)文件路徑錯(cuò)誤在conftest.py或數(shù)據(jù)加載函數(shù)中使用Path(__file__).parent.parent等方式來(lái)構(gòu)建相對(duì)于項(xiàng)目根目錄的絕對(duì)路徑避免因執(zhí)行目錄不同導(dǎo)致的文件找不到問(wèn)題。響應(yīng)時(shí)間過(guò)長(zhǎng)導(dǎo)致測(cè)試不穩(wěn)定在api_client中設(shè)置合理的超時(shí)時(shí)間如timeout10并對(duì)慢請(qǐng)求進(jìn)行記錄或告警??梢栽?Allure 步驟中記錄請(qǐng)求耗時(shí)。大量用例運(yùn)行時(shí)內(nèi)存占用高如果測(cè)試數(shù)據(jù)量極大避免一次性將所有數(shù)據(jù)加載到內(nèi)存??梢钥紤]使用pytest的pytest.mark.parametrize結(jié)合生成器 (yield)或者分模塊、分文件執(zhí)行測(cè)試。這套pytest Allure JSON Schema的自動(dòng)化測(cè)試方案通過(guò)將數(shù)據(jù)、邏輯、契約、報(bào)告解耦構(gòu)建了一個(gè)高度可維護(hù)、可擴(kuò)展且極具洞察力的測(cè)試體系。它尤其適合接口數(shù)量多、數(shù)據(jù)結(jié)構(gòu)復(fù)雜、迭代速度快的項(xiàng)目。一開始搭建框架可能需要投入一些時(shí)間但一旦建成后續(xù)新增用例和維護(hù)契約的成本將大大降低測(cè)試的可靠性和價(jià)值也會(huì)顯著提升。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
日韩精品.久久精品.AV女优.天美传媒 | 天美av在线观看| 国内伊人久久久久久网站视频| 红桃视频高潮| 911av网站免费观看| 日本道人妻久久久在线不卡色视频| 最新欧美色网| 口爆吞精在线观看| 91无遮挡| 色欧美在线| 亚洲欲色9532548967一区| 91老熟女视频| 丝袜视频网国产90| 亚洲欧洲日产国产综合网| 国产大陆天天艹| 日本Suv精品一区二区| 国产乱弄免费在线视频。| 五月丁香激情综合网| 日本性爰一道本| 91日产桃蜜| 亚洲人精品午夜不卡| 中日韩熟女| 国产日韩在线播放av| 国产蜜臀精品一区二区尤物| 中文字幕第95页| 啊啊啊好大好湿| 91精品黄在线观看| 国产乱色国产精品免费视| 搡老女人老91二区| 抽插亚洲无码| 亚洲美女AV无码| 天天超级碰碰碰| 嗯嗯啊好大| 亚洲综合九九| 久久久艹艹艹| 五月丁香亭亭| 伊人97超碰| www…国产操逼| av网站在线看| 亚洲成人激情小说视频| 精品国产Av无码久久久伦古装| 91天美免费| 久久久av爱| 91天天日| 丁香五月性| 91精品无码人妻系列| 久久精品毛片免费不卡| 乱伦AVxx| 亚洲色图91欧美日韩| 人妻激情偷乱视三区频一区二区| 国产亚洲精品玖玖玖在线观看| 日本天天干天天操一区| 无码不卡亚洲成?人片| 老熟女阿 国产91| 国产白丝网站| 一区二区三区国产在线播放 | 亚洲久草AV色图| 91色噜噜狠狠| 色吧综合网| 床上啊啊啊一区二区三区| 久操精品网| 人人考人人摸人人干| 成人五级久久| 美日韩成人| 国产四虎在线| 欧美日韩高潮喷水91| 把腿张开老子CAO烂你| 中文字幕精品一区二| 97人人射| 国模久久在线| 日韩免费三级黄片电影| 五月丁香亭亭| 亚洲狼狼干综合1| 黄色av播放免不| 91欧美美女日韩国产婷婷| 97 色综合| www四虎| 色婷婷亚洲婷婷| 亚洲欧美高清| 亚洲国产欧美一区二区潘金莲| 热99这里有精品综合久久 | 69视频入口| 国产亚洲精品第一最新| 国产日韩区| 亚欧毛片基地国产毛片基地| 亚洲欧美日韩精品久| 男人亚洲91首页在线| 天天综合-91入口| 超碰人人妻| 天天影视之亚洲综合网| 欧美日韩性感| 任我爽视频在线观看| 婷婷久久五月| 亚洲日韩精品在线播放| 97在线播放 | 九九九九欧美| 欧美色999| 国产午夜激片Av毛片不卡| 第二页中文字幕| 日本操逼视频免费| 伊人一区二区三区| 麻豆啪啪啪视频| 天堂亚洲精品| 夜夜综合| 黄色欧美性爱视频| 亚洲欧美不卡线| 欧美成人色| 超碰国产精品久| 校园春色美腿丝袜| 精品一区二区三区四区外站 | 91美女视频电影| 天堂网亚洲区手机版| 国产亚洲禁久一区二区| 99re视频在线播放青草| 精品人人| 五月丁香婷婷啪啪| 国产91会所女技师在线观看| 久草男人天堂| 久久理论字幕视频| 国产超碰| 国产理论视频在线播放| 亚洲色电影在线| 国产精品久久久久久久久久久久久久久久久久 | 三男一女不戴套的A片| 丝袜视频网国产90| 永久免费av无码网站国产app| 人妻在线中出视频| 5252色欧美在线男人的天堂| 强奸乱伦免费网站| 国产黄a三级三级三级av在线看| 强免费黄色网址| 青青草色插素人| 91搡老女人老妇女老熟女歌词翻译| av中亚| 人人妻天天做天天爽| 国产AV天美传媒一区二区三区 | 99久久久99久久91熟女| 啊啊啊在线看| 亚洲综合图文| 欧美在线 亚洲| 呻吟 欧美 日本 中出| 日韩丝袜二区| 丰满人妻一区二区三区免费,| 九九久久综合| 日韩性爱啪啪视频| 中文字幕在线免费观看视频| 全免费a敌肛交毛片免费| 中国操逼无码| 91足交| 岛国视频一二三区| 亚洲AV无码黄色强奸| 被男人吃奶很爽的毛片| 国产亚洲精品美女久久久久久2021| 国产亚洲深夜激情| 欧美综合娱乐久久| 90后性网国产欧美| 天天淫人人妻日日色| 四月丁香婷婷| 午夜无码熟妇丰满人妻| 97亚洲精品超碰| 色色九区| 欧美成人一级麻豆| 不卡中文字幕aⅴ在线| 日韩人妻一区二区| 国产一区二区成人av在线播放| 亚洲人妻精品一区二区| 国内精品a| 亚乱色| 九九九九九九九九九九九免费国产| 欧美黑人精品一区二区| 男女一级A片大黄,一进一出| 久久超碰免费的| 亚洲玖玖爱| www国产无码| 亚洲第一无码播放立川理惠| 91美女视屏| 99精品无码| 国产久久久久久| 日本精品第一视频在'| 97操97色| 丝袜AV一区二区三区| 一级@啪啪视频| 九九色婷婷| 欧美变态激情网| 国产97在线 | 亚洲| 浪人综合网| 日韩精品大香蕉伊人在线| 黑人综合网| 亚洲春色欧美| 丝袜 亚洲 偷拍| 国产精品一区二区麻豆| 人人插人人摸人人| 丰满熟女人妻一区二区三五十一路| 一本色道久久天天射天天干| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 日韩成人高清一区二区| 人妻少妇久久中文字幕一区二区 麻豆 | 欧亚 另类 久| 激情啪啪拍91| 色色色日本| 日本乱人伦片中文三区| 试看日韩黄片| 大香蕉视频啪啪啪啪| 俺也射| 干美女人妻| 欧美91网| 麻豆久久一区二区三区| 欧美亚洲综合高清在线| 欧洲特黄毛片免费看欧洲毛片| 日韩久射综合| 26UUU欧美日本| 岛国黄片网站| 手机看片日韩人妻| 欧美精品自慰系列寂寞少妇| 欧美精品99久久久**| 日逼国产| 久久久久久中文字幕中文字幕最新| 精品网站9999| 色牛牛AV| 97欧美精品综合| 国产青青美女玩逼视频| 日韩精品免费高清视频在线| 208天天久久九九九| 操碰97| 久久久蜜桃一区二区三区| 欧美,日韩,中文,另类| J?P?NESEHD熟女熟妇伦| 欧美黑人猛交春色影视大全| 国产女大学生AV| 欧美日不卡| 91夜色| 国产天天骚| 女人的天堂大香蕉网| 久久久久久99AV无码免费网站| 麻豆亚洲AV成人无码久久精品| 天天性射网| 国产精品一区二区麻豆| 亚洲天堂2020| 欧美日韩黄片精品在线| 91三级理论片播放器| 五月婷婷基地| 国产精品。| 日本天堂在线播放| 男人久久天堂| 日韩精品碰碰| 久久精品国产亚洲AV嘿嘿| 97综合在线| 大香蕉十区| 国桃视频产巨乳精品一区二区在线| 婷婷九月国产| 五月亭亭六月丁香| 99热啪啪| 91啦人妻| 无毛精品| 日本 欧美 国产一区| 日日夜夜狠狠| 夜夜操夜夜高潮夜夜爽国产精品区| 亚洲欧美综合| 日韩欧美视频青青| 97人人色| 亚洲在线网站| a片偷拍视频| 色播五月丁香| 一区二区三区四区久久视1| 黄呦呦在线| 97超碰影音| 人人性爱视频免费| 亚洲高清无码在线桃色| 欧美成人9797| 亚洲精品蜜桃久久久| 日本色婷婷| 9久超碰| 九月丁香婷婷色| 国产精品一区二区密臀| 五月天色电影| 18禁止看精品中文字幕| 97精品国产手机| 日本日皮视频逼| 亚洲精品九九九| 超碰 av 女人天堂| 嗯啊不要在线观看嗯啊| 亚洲αv一区二区三区| 国产高清精品一区二区三区毛片| 久久久久9999妇女| 日少妇视频| 97国产|免费| 日本一区视频在线观看| 99re9在线| 国产精品三级视频网站| 久久久久九九九九| 日韩 欧美 国产 麻豆| 在线观看国产黄色| 亚洲色综合| 日韩精品人妻中文字幕有码午| 一二区在线观看视频| 人人妻人人澡人人爽久久av| 亚州乱码中文字幕综合久久久| 亚洲中文字幕久久无码精品| 国产女性无套 免费观看| 久久亚洲人妻| 亚洲AV成人无码一二三久久 | 91粉嫩萝控精品福利网站_精品影音先锋国 | 啊啊啊好多水| www.夜夜| 91中文字幕制服丝袜免费视频| 国产综合永久精品日韩鬼片| 国产欧洲精品亚洲午夜拍精品| 天天干天天燥| 激情五月天校园春色网| 乱伦3P视频| 欧美韩日精品资源| 色婷亚洲五月在线观看| 亚洲精品国语在线播放| 偷拍色图| 久久久三区二区一区| 热久久九九热| 婷婷色网| 操逼日韩无码| 精爱久久| 国产熟女完整版中字| 欧美97日韩| 在线综合 亚洲 欧美中文字幕| 久久九九一区二区三区成人| 亚洲欧美日韩免费电影| 中文熟女五十乱码在线| 中文字幕一区日韩精| 97鸡把在线视频| 中文字幕 一区二区 亚洲无码| 亚洲综合伊人| 97就爱干| 青青草好吊色| 免费无码婬片AAAA片直播色戒| 欧美A片中文字幕| 影音先锋乱伦资源| 欧美色综合影院| 伊人网在线点播| 99操| 99久久国产精品免费高潮| 久久av网| 99久久精品国产高潮| 啊啊啊轻点在线观看| 野狼激情网| 人妻献身系列第54部| 啊啊啊啊好大好硬啊啊啊啊啊| 亚欧Av| 欧美 精品国产制服第一页| 日日夜夜噜| 人成午夜免费大片| 97视频在线免费观看| 老熟妇一区二区三区啪啪| 日韩AV熟女乱伦| 九九视频黄色片| 99热18这里只有精品| 能看的av| AV免费在线播放一区| 97亚洲色图| 中文字幕老熟妇黄色视频| 久久精品日韩| 视频国产欧美在线播放| 亚洲欧美97√| 亚洲啪啪啪啪视香蕉| 欧美性性性| 狠综合网| 俺去久久| 色色色欧美| 亚洲精品乱码线路中文字幕| 黄页| 九九九九9999| 亚春色色| 快灬快灬 一下爽蜜桃在线观看| wwwss在线观看| 人人操肉肉| 亚洲九九视频| 亚洲最大黄网| 自拍偷拍 高清无码| 三久久久四久久久久| 五月天啪啪| 久久久久成人亚洲国产| 在线观看色视频| 激情熟女12P| 成年无码动漫av片无尽在线| 91亚洲人| 国产激情视频一区区三区| 国语精品av| 日日躁天天躁狠狠躁| 蜜桃精品一区二区三区久在线| 伊人久久大香线综合无码| 亚洲日韩AV视色| 激情综合五月| 久久婷婷伊人| 香蕉国产精品麻豆亚洲欧美日韩| 亚洲综合20p| 人妻久久| 日本不卡二区| yiqicaoav| 天天射天天操天天干天天吃2018| 日日摸天天爽夜夜欢| 丝袜 中出 制服 人妻 美腿 中文字幕| 91丝袜美腿片| 色九九久九九| 国产精品白丝www| 大香蕉中文在线| 久久啊啊| 很很操在线| 都市久久精品激情亚洲| 国内毛片婷婷六月色| 成人三一级一片aaa| 成全动漫视频观看免费下载| 视频国产精品未满十八禁止在线观看| 乱伦1色页| 午夜国产成人福利视频| 男人的天堂啪啪啪啪啪蜜桃不卡| 男女91| 美女大乳久久久久久久女人18| 精品国产国产AV| 国产精品久久久九九九| 一区二区三区四区久久视1| 伊人久久久日韩一区| 黄色av播放免不| 欧美BT 亚洲色图| 精品人妻一区二区三区日产乱码| 国产精品久久久久久亚洲色欲| 狼狼色丁香久久婷婷综合五月 | 久久久免费高清中文视频| 97露脸精品丝袜| 人人操人人射人人干| 国产精品视频在线播放| 精品69网| 吖在线不卡一区二区国产剧情| 日本日皮视频逼| 五月天婷婷欧美三区| 麻豆一区在线| 成人国产二区三区在线,男女精品。| 日韩精品中文字幕人妻| 天天色播亚洲综合网站| 少妇被玩视频二三区| 天天插夜夜爽| 亚洲第一页第二页激情| 国产一级αv免费看片| 九九无码久久精品视频| 精品人妻一区二区三区日产乱码| 色操逼网| 日韩久久三区| 密臀国产在线| 一级AV性爱| 99热综合| 国产乱不卡| 中文字幕中文字幕一区二区| 国产精品成人无码a v毛片| 日本精品第一视频在'| 久九九九九九九热| 精品人妻一区二区三区免费视频| 一级AV性爱| 午夜理论片在线观看免费| 91老熟女逼| 蜜桃视频精品一区二区三区| 怡红院久久老司机| 亚洲一区在线观看欧洲| 99热91| 天天综合网91入口| 啊啊啊啊操死我| 人人插人人搞人人操| 黄色不卡视频| 精品九九| 天天综合色电影| 久久嫩草| 亚洲欧美精品福利在线| 好吊爽好吊爽在线视频,中文字幕精品一区二区日本,国产良妇出轨视频在线观看, | 黄片免费久久久久久久| 久草婷婷| 久久性爱视频99| 爱我干综合| 啊啊啊好疼| 国产亚洲女v在线观看| 蜜臀在线免费观看在线免费观看| 三级色影综合网| 天天干天天干天天干| 精品综合久久久久久97| 日欧操屄视频| 老司机午夜福利视频一区二区| 人人艹亚洲| 天天综合欧美综合| 激情抓乳插进去啪啪啪日韩 | 国产农村一一级特黄毛片| 超碰天天久久79| 国产午夜福利专区综合| 嗯啊不要啊啊在线观看视频| 中文字幕在线免费观看2| 91爽啪| 91无遮挡| 国产精品久久久久久久久久久久久久久久 | 网友自拍第一页| 欧美性猛交美女自慰91| 久久久久久网址| 日韩懂色网| 1级午夜影院费免区| 日韩精品第3页| 国产精品久久99日日| 久久九操在线观看| 九九热九九| 人人妻人人澡人人爽人人精品浪潮| 婷婷五月天社区| 天天综合91入口| 99在线精品视频| 久热最新在线杭州| 97超碰无码网| 日本午夜精品理论片A级APP发布| 精品对白久久不卡| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师 | 极品美女福利在线观看| 日本免费二区三区| 99热97| 久久久精品无码亚免费| 日韩15p| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 亚洲 无码 偷拍| 久久超碰98| 亚洲av无码成人精品国产| 一区二区三区视频| 亚洲欧美日韩电影网站一区| 久久五月视频| 亚洲 欧美 制服 另类 自拍| 欧美综合第一页| 亚洲成人色情五月天丁香花| 日本三级黄页| 福利社区午夜一区二区| 操一操摸一摸| 亚洲综人网| 人妻美腿丝袜制服诱惑综合天堂-| 综合欧美激情网| 日韩亚洲欧美中文字幕| 五十路人妻在线| 久久久久久久少妇| 成人网站 免费观看| 午夜爽爽爽| 无码人妻精品一区二区三区九九 | 久久人妻视频网| 岛国在线一区二区三区| 久久精品国产精品一区| 日韩精品一区二区人人人| 成人久久无码www| 亚洲有码 欧美精品| 91强热人妻| 日韩人妻有码免费视频| 久久久无码精品人妻二区| 美女诱惑在线一区| 丝袜制服字幕在线| 亚洲黑丝在线| 女人被添高潮免费视频| 人妻中文字幕日韩电影| 为用户提供免费看黄网址在线观看| 亚洲日韩精品一区二区| 91精品国产91久久久久久久久久久久| 欧美91久久久久| 中文字幕一区 二 区 三 四 五 区日 日 骚| 国产亚洲性生活视频播放| 试看60秒 爽| 91人妻久久久久久久久久久久久| 少妇极品熟妇人妻无码| 中国一级特黄大片护士| 免费久久一级毛片大黄| 97ai亚洲| 夜夜性| 亚洲开心网| 青青青青青手机视频| 另类欧美色| 狠狠爱夜夜| 91成人无码| 97超碰9| 国产精品久久| 亚洲无码超碰免费| 不卡av在线中文字幕| 亚洲av无码成电影在线播放| 成人无遮挡毛片免费看| 国产欧美精选自拍一区| 国人欧美精品一区二区| 插日本熟女视频| 福利在线黄片| 亚洲福利中文字幕在线| 亚洲成人综合在线| 超碰久热| 宗合情欲网| 日本999精品| 亚洲AV在线资源| 密臀成人视频久久久| 久久在肏| 在线看污网站| 男人午夜天堂| 蜜臀久久99精品久久久久久婷婷 | 日韩情色视频| 欧美 日韩 另类 亚洲| 欧美人妻色| 青操影院| 少妇久久久免费| 2025亚洲男人天堂| 欧美激情精品久久久| 少妇500双飞99| 人人操人人射人人干| 4tube欧美女厕所| 欧美综合另类| 国产精品999zyz| 五月天色色网站| 后入 亚洲 美女 射| 躁躁日曰躁2020| 亚洲丨在线| 小说区 图片区色 综合区| 国产性爱乱伦AV| 久久综合99| 精品999日本| av2014 日韩在线中文字幕| 欧美高清无码免费视频高清版| 久操凹凸视频| 不卡超碰护士AV在线免费播放| 性老妇一区二区三区| 97K超碰在线| 91精品久久久久五月天精品| 长长久久曰曰夜夜成人网| 国产极品久久久| 日本欧美不卡| 国产美女口爆吞精视频| 开心五月激情网| 免费亚洲国产精品久久一区| 久久免费少妇| 久久99网站| 欧美乱妇狂野欧美在线视频| 啊啊啊啊啊啊啊啊视频| 黄色小视频日本txt| 一区二区精品更新提醒| 97日韩超碰超碰中文字幕| 黄色区免费观看中文字幕| 久热久一区二区三区| 91视频女生| 性久久久| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 韩日色费| 91人人爽人人爽人人人,gav福利视频导航,日韩欧美亚洲国产字幕四区 | 蜜桃臀一区二区aV| 日本孕妇一区二区视频操逼免费看 | 亚洲天堂AV在线播放| 狠狠激情综合狠狠操中文字幕| 亚洲国产剧情少妇激情| 亚洲天堂久久| 日韩不卡毛片Av免费高清| 亚洲永久永久永久永久一级一级一级精品| 亚洲a色| 色色婷| 死我十八禁| 成人a大片在线观看| 精品国产污一区二区三区| 清纯唯美激情| 色色色欧美| 狠狠躁伊人中文字幕| 国产精品久久久久综合| 人妻无码视频一区二区三区久久| 成人小说视频在线精品欧美| 青青草吊丝| 欧美欧美啪啪视频| 精品一区96| 欧洲特黄毛片免费看欧洲毛片| 亚洲色图欧美色图日韩色图| 69超碰综合| 2017天天操| 久久精品视-一级做a爰片性色毛片16美国-中国女与老外在线精品 | 九一综合精品视品av| 久久超碰97| 黄色污污污污污污网站| 蜜臀久久99精品久久久久久-DVD| 久久久久久久久久8888| 五月天婷婷社区| 亚洲人成网www| 大香蕉综合网| 日本淫色网| 五月丁香六月综合缴清无码| 男插女青青影院| 嗯啊抽插大香蕉网页| 亚洲清纯唯美| 日本日逼视频网| 91美女片在线| 男人的天堂在线有码| 一起草三级AV电影在线观看 | 久久久久亚洲Aⅴ无码| 五月天九九日国产精品一区二区三区| 五月丁香成人网| 国产精品白丝AV| 99精品网| 国产精品午夜福利亚洲综合网| 1二区9| 五月天色色网站| 亚洲无 码A片在线观看麻豆| 久久久久久久久久久久黄色| 国产精品一二三在线看| 欧美姓爱综合网| 色综合加勒比四四季| 日本三级一区二区 在线| 少妇激情AV| 思思热在线| 久久精品欧美一区二区三区不卡| 人妻激情在线视频| 色婷婷综合久久久久中文国产精品一区中文字幕,国产福利电影一区二区三区 | 超碰97欧美日韩| 亚洲成av人片色午夜乱码| 91美女在线观看| 91精品国久久久久久无码| 熟女视频久久| 天天色黄色影院天天操| 久久久久久人| 五月天伊人| 探花激情视频| 豆花视频操逼网址| 亚洲熟妇图片| 亚欧国产无码精品在线| yw尤物av无码点击进入麻豆| 人人澡人人澡人人| 色九月综合| 天天流夜夜操| 黄色视频特级毛片| 亚洲青色欧美| 无码聚合| 五月丁香激情四射| 欧美在线干| 精品一区二区三区免费古装毛片香港三级日本三级人妇 | 免费男人的天堂| 亚洲欧美校园| 日韩中文字幕国产| 中文字幕一二三区| 久久最新免费视频23| 中文字幕一区电影在线观看| 内射中出日韩在线观看视频| 人妻精品一区二区| 9超碰免费| 亚洲本色精品一区二区久久| 亚洲精品一区二区三区新线路| jizz啪啪| 97Ai亚洲| 俞拍久久国应视频| 性爱AV天堂| 操我啊啊啊啊啊| 麻豆人妻精品一区二区| 欧亚成人| 顶级丝袜熟女一区二区三区| wwwxxx日本爽| 亚洲国产成人7777| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师黑人潮喷一 | 成人a大片在线观看| 中文字幕蜜乳av| 78m啪啪啪| 91艹逼精品| 亚洲熟妇丝袜在线观看| 一本一道人妻久久一区二区三区| 99免费在线视频| 日韩无码专区| 99操碰| 免费综合亚洲中文| 黄网色一区二区三区四区精品| 国产成人bd在线观看| 久思思热视频在线观看| 懂色中文一区二区三区| 日韩无码视频黄色| 日韩在线欧美精品一区二区| 精品视频一区二区| av三级电影在线播放| 91夜色| 久草精品国产99| 欧美亚洲国产91在线| 欧美激情一区| yw尤物av无码点击进入麻豆| www久久国产精品| 国产无码高清操逼视频| 可以在线观看的黄色网址| 久久亚州精品成人Av无| 亚洲阿v天堂无码z2018| 国产精品直播在线观看直播| 人妻素股| 亚洲国产中文字幕| 久久曰曰| 激情四射婷婷六月天| 99久久免费看精品国产一区| 久久91| 老熟女阿 国产91| 天天躁日日躁狠狠躁| 日韩欧美午夜一区二区| 99色热国产视频精品| 一块操欧美性爱| 不卡在线一区,精品一区二区三区中| 久久一二区四| 青木玲在线不卡| 骚日日av| 乱伦熟女论坛| jizzjizz欧美| 国模不卡| 欧美日韩国产精品久久色婷婷| 亚洲成人妻日韩在线| 五月天婷婷社区| 69av一区二区三区| 免费操逼视频下载| 夜夜夜夜夜夜夜夜夜狠狠狠狠狠狠狠| 日韩少妇无吗| 久久久久久久唑| 少妇一级婬片免费放一级a性色.| 人人插人人搞人人操| 天天色悠悠激情| 九九九九九九免费视频| 久久久久96| 国产精品视频91久久| 激情五月天丁香社区| 久久9 9 9精品| 国产美女高潮视频| 色y情视频免费看| 99操碰| 亚州色图欧美| yiqicaoav| av强奸乱轮| 毛片视频白嫩| 国产一线二线三线av| 免费观看国产小粉嫩喷水精品午| 久久香蕉网| 天天日美女的B| 国产狂喷潮在线精品| 亚洲天堂 视频你懂的| 麻豆一区二区三区精品| 国产97亚洲| 操逼无码一区| 久久伊人在线五区| 精品国产乱码久久久久久久久久毛片 | 色五月天AV| 一区二区影视| 午夜久久无码1000合集| 天天摸夜夜操视频| 精品无码欧美三级| 美日韩成人| 我想要啊 啊 啊| JuliaAnn丝袜熟女系列| 国产亚洲精品玖玖玖在线观看| 欧美天天谢综合网| 91天天综合日韩欧美| 青青草天天亲夜夜操网| 精吧天堂| 日韩亚洲欧美中文字幕| 99热91| 狠久久| 色综合色欲色综合色综合色综合| 五月天亚洲网| 亚洲第一狼人丝袜美女另类| 日本999精品| 日韩成人在线性爱视频| 精品国产一区二区三区久久久蜜臀| 日本熟妇人妻一区二区三区| 国产精品久久久久无码A√| 精品乱子一区二区三区99| 久久久久久久97| 蜜桃久久综合视频| 九九九九精品视频| 成人在线日韩| 亚洲自拍小说| av天堂影视中文在字幕在线中文| 欧美+日产+中文| 青青草视频这里只有精品| av东京热男人的天堂| 乱伦图av| 欧美日韩系列| 欧美在线视频99| 日韩十八禁| 日韩精品一区二区三区四虎影视| 抽查国产福利主播| 亚洲欧美激情在线视频| 超碰av在线| 国产最新小视频在线播放下载| 欧美日韩国产另类综合| AA丁香综合激情| 手机在线人成免费视频| 碰碰97| 久久人妻视频| 920日本午夜免费| 九九九精品美女| av天天在线观看| 可免费观看的av毛片中日美韩| 麻豆天美国美国产| 国产9 9在线 | 亚洲| 欧州色图区| 国产精品999zyz| 亚洲做性| 国产怡红院| 91老女人| 蜜桃久久久久久久久久久久| 亚州AV无码国产精品| 东北女人性交| 久久久久ab| 亚洲中文字幕三级在线| 精品91日日夜夜超清资源| 中文字幕88av在线| 国产aⅴ无码片毛片一级网站| 亚洲性猛交| 中文字幕第页| 思思热在线cao| 怡红院亚洲怡春院av| 日韩一区二区三区四区五区| 久久东京热久久| 金典av| 五月大香蕉| 新亚洲无码| 乱操9999| 久色网| 欧美爱三级日韩久久| 怡红院成人视频| 国产精品 午夜福利| 色综合色欲色综合色综合色综合| 夜夜嗨TV| 97色色,97综合| 亚洲一区二区麻豆影院| jk白丝没脱就开始啪啪| AV天堂因数| 亚洲在高跟鞋自慰久久在色线| 99久久99九九99九九九| 日小BB小视频| 麻豆综合一区av| 亚洲欧美另类图片| 道久久五香丁月婷婷激情综合| 国产精品久久久久综合| 国产9 9在线 | 亚洲| 国产精品农村妇女精品| 精品9区| www.99色| 男女真人网18| 亚洲图片婷婷五月天| 超碰97护士| 亚洲天天更新| 熟妇女伦乱视频视频| 欧美日韩国产男人| 欧美日韩m| 97色冈| 欧美日韩国产在线| 5278欧美一区二区三区| 国产精品久久久久中文字幕| 超碰97人妻免费在线| 黑丝制服中文字幕| 蘋果手機免費看成人Av| 91高跟美女在线播放| 江都AV在线| 成人婷婷丁香| 久久久久久午夜男人的天堂| 午夜.DJ高清在线观看免费7| 夜色91| 蜜桃传媒视频第一区入口在线看| 国产和美国毛片| 欧美青青视频| 91爱做| 欧美熟女妇同| 综合网~91综合网| 区一在线观看| 欧美97日韩| 色欲人妻一区二区在线| 91精品人妻一区二区三区蜜桃臀| 大香蕉伊人网WWWn0n| 国产高清1234区| 91爱综合| 欧洲乱码一区二区| 婷婷另类小说| 亚洲91大片| 欧美第二页午夜| 久久精品国产97欧美精品亚洲 | 亚洲精品蜜桃久久久| 久久久久深夜无码| 蜜臀Av一区二区三区| 60秒不遮不挡| 呦呦一区| 欧美AAAA黄片| 乱伦av麻豆| 久久99午夜精品一区人妻| 亚洲制服欧美另类内射| 91强热人妻| 亚洲中文字幕三级在线| 久操精品网| 男插女青青影院| 国产精品视频白浆免费| 久久午夜鲁丝片| 日韩综合97p| 91综合中文字幕| 国产91丝袜 在线播放| 免费久久9999| 欧美成人综合| 国产又大又粗又长视频在线| 中文字幕55555| 国模精品一区二区三区苹果色戒 | 色狠狠一区二区三区香蕉| 亚洲aV无码成人在线观看| 国产精品麻豆视频网站| 狠狠狠狠狠狠| 午夜福利免费精品视频| 97se亚洲综合自| 国产av色网| 91精品国产综合久久久蜜臀| 另类专区加勒比| 一块操欧美性爱| 青青草乱入乱欲视频在线观看| 日本道日本道中文字幕日本道最新日本道在线观看 | 久久久久久久人妻| 嗯嗯啊啊啊好舒服| 少妇特黄一区二区三区| 欲色啪| 亚洲在线A| 国产精品久久久久久久AV大片| 特级丰满少妇一级AAAA爱毛片| 99色热| 欧美色五月| 精品96久久| 韩国国产欧美情侣视频在线| 日本媚薬中文字幕在线| 国产精品成人无码a v毛片| 99精品网| 2019午夜福利视频| 91天天| av国产无码| 久久中日麻豆| 日韩小电影| 国产久久成人| 麻豆 欧美 日韩| 男人天堂免费| 美国日韩黄片| 婷婷五月成人| 老女人91| 夜夜嗨视频| 日本性交操一区二区不卡系列| 激情第四色| 97超碰中文字幕| 国产一区自拍欧美日韩| 亚洲色图加勒比| 97伊人| 欧美性爱精品一区二区| 精品二区三四区五电影 | 欧美成va视频网站| ai欧美亚洲小说| 亚洲天堂精品日韩电影| 920日本午夜免费| 208天天久久九九九| 综合久久久久久久综合网| 久久男人网| 91搡老女人老妇女老熟女歌词翻译| 五月天黄色激情视频| 91美女视频电影| 精品毛片av一区二区| 九久9热| 成 人 A V免费视频在线观看| 五月丁香婷婷色| 久9久9久9久9久9久9| 午夜国产成人福利视频| 91激情综合| 中文字幕一区二区三区字幕| 五月天婷婷基地| 久久精品成人| 国产精品熟女乱伦| 亚洲综合在线91| 久久久国产三级黄色片| 91 国产丝袜在线放观看| 欧美亚洲激情| 91久精品| 欧美精品三级黄片| 亚洲色图加勒比| 黄色香蕉视频网站一区| 欧美性色综合网| 国产美女在线精品免费看| 香蕉一区二区三区在线视频| 91人妻少妇| 91在线视频免费中出| 在线a亚洲视频播放在线| 日韩精品在线观看网站| 91精品在线播放| 国产亚洲在线| 天天日夜干| 热天堂一区二区| 秋霞操逼片| 中文字幕超碰CAO| 日va操| 超碰 欧美| 久久久影院| 欧美成人A√在线一区二区| 欧美日韩亚洲高清不卡一区二区三区| av天堂精品久久| 国产一区二区成人av在线播放| 天天香香欲综合| 后入国产| 欧美激情欧美精品| 99性爱在线观看| 精品欧美乱码久| 国产精品色色| 亚洲本色精品一区二区久久| 欧美 日韩 国产传媒| 亚洲欧美在线观看免费| 国产精品禁久久久精品| 黄色二级片网站| www.99中文字幕| 久久久久9999妇女| 亚洲性爱无码乱伦av| 欧美日韩久久精品爱爱| 亚av顶级裸体一区二区三区四区五区| 欧洲一级性爱视频在线观看| 啊啊啊啊好多水| 91日产欧美| 99热精品在线在线| 亲子敌伦对白在线播放| 91精品婷婷国产综合久久竹菊| 欧洲熟妇xxXx欧美老妇裸体| 后入国产| 久久久久ab| 黄页视频网站野外| 欧美成人性爱视频在线播放| 亚州高清av| 在线观看十八禁| 国产尹人在线视频免费| 国产吹潮女在线观看| 天天摸天天插天天日| 黄色一级视| 天天干人人看综合| 美女丝袜激情小说| 99色视频| 免费人成在线观看网站品爱网| 综合五月天| 中文字幕AV片| 俺去久久| 一区二区偷拍拍视频| 人人澡人人干| 欧美亚洲厕所精品偷拍91| 日韩有码免费视频| 无码免费精品高清| 国产美女在线精品免费看| 欧洲综合色| 亚洲欧美综合网站| 亚洲色图久久精品蜜| 一级A片女人高潮叫床| 夜夜操青青草| 伊人国产成人av网站| 欧美成不卡网| 中文字幕永久在线| 亚洲国产午夜真人一级片中文字幕精品黄网站 | 四虎午夜影院| 久草精品国产蜜臀| 午夜男人一级A片7777| 熟妇的味道HD中文字幕| 亚欧美综合| 亚洲伊人久久精品狠狠在线| 国产吞精a级片激情电影| 在线A日本| aaa亚无码专区| 91操熟女| 一区二区影视| 天天色综合影视网| 999九九九九国产动| 韩日精品福利视频一区不卡在线免| 色婷婷综合久久久久中文一区二区 | 丝袜六区| 五月丁香婷婷综合| 男人高清无码一区二区| 无码直播久久久| 国产午夜在线观看| 国产欧美在线观看免费观看| 好爽视频在线观看视频 | 天天爽夜夜爽夜夜爽精| 一区二区偷拍拍视频| 欧美高清18A片| 色999人与兽| 清纯唯美第一页|