2026/2/11 0:09:37
网站建设
项目流程
布吉企业网站建设,怎么注册logo商标,外贸公司网站建设哪家好,什么是网站的权重pytest 语法与核心概念Part 1: pytest 语法与核心概念1.1 基础语法1.2 配置文件 (pytest.ini, pyproject.toml, setup.cfg)Part 2: pytest 装饰器详解与样例2.1 pytest.fixture - 核心依赖注入与资源管理2.2 pytest.mark - 标记与控制2.3 pytest.mark.parametrize - 数据驱动测…pytest 语法与核心概念Part 1: pytest 语法与核心概念1.1 基础语法1.2 配置文件 (pytest.ini, pyproject.toml, setup.cfg)Part 2: pytest 装饰器详解与样例2.1 pytest.fixture - 核心依赖注入与资源管理2.2 pytest.mark - 标记与控制2.3 pytest.mark.parametrize - 数据驱动测试Part 3: Playwright 页面元素选择器详解与样例3.1 Locator API (推荐方式)3.2 Locator 对象的链式操作与过滤3.3 智能等待 (Implicit Waits)总结Part 1: pytest 语法与核心概念1.1 基础语法测试函数命名Pytest 会自动发现并运行以test_开头的函数或_test结尾的函数。deftest_addition():assert112deftest_string_contains():asserthelloinhello world断言直接使用 Python 的assert语句。Pytest 会捕获失败的断言并提供清晰的错误信息。deftest_list_length():my_list[1,2,3]assertlen(my_list)3assertlen(my_list)5# This will fail with a clear message1.2 配置文件 (pytest.ini, pyproject.toml, setup.cfg)可以用来配置 pytest 的默认行为、添加插件、定义标记等。pytest.ini 示例[tool:pytest] # 标记注册方便 IDE 识别 markers smoke: marks tests as part of the smoke suite ui: marks tests related to UI interactions slow: marks tests as slow # 默认命令行参数 addopts -v -x --tbshort # 指定测试路径 testpaths tests # 忽略某些路径 norecursedirs .git dist build *.eggPart 2: pytest 装饰器详解与样例2.1pytest.fixture- 核心依赖注入与资源管理作用提供测试所需的数据或对象并管理它们的创建setup和销毁teardown。基本用法importpytestpytest.fixturedefsample_data():提供一个简单的数据示例.data{key:value,number:42}returndatadeftest_use_sample_data(sample_data):使用 fixture 提供的数据.assertsample_data[key]valueassertsample_data[number]42yield与 teardownimporttempfileimportospytest.fixturedeftemp_file_path():创建临时文件并在测试后删除.temp_dirtempfile.mkdtemp()temp_fileos.path.join(temp_dir,temp.txt)withopen(temp_file,w)asf:f.write(Test content)yieldtemp_file# 返回文件路径给测试函数# Teardown: 测试函数执行完毕后清理临时文件os.remove(temp_file)os.rmdir(temp_dir)deftest_read_temp_file(temp_file_path):withopen(temp_file_path,r)asf:contentf.read()assertcontentTest contentscope参数pytest.fixture(scopesession)# 整个测试会话期间只执行一次defexpensive_resource():print(\n--- Creating expensive resource (e.g., database connection) ---)resourcecreate_expensive_resource()yieldresourceprint(\n--- Cleaning up expensive resource ---)destroy_resource(resource)pytest.fixture(scopefunction)# 每个测试函数执行一次 (默认)defper_test_setup():print(\n--- Per-test setup ---)yieldprint(\n--- Per-test teardown ---)pytest.fixture(scopeclass)# 每个测试类执行一次defper_class_data():print(\n--- Per-class setup ---)dataload_class_data()yielddataprint(\n--- Per-class teardown ---)# Test functions using fixturesdeftest_a(expensive_resource,per_test_setup):assertTruedeftest_b(expensive_resource,per_test_setup):assertTrueautouseTruepytest.fixture(scopefunction,autouseTrue)# 自动应用于所有函数级测试defauto_log():print(\n[LOG] Starting a test function)yieldprint([LOG] Finished a test function)deftest_one():# 不需要显式声明 auto_logassertTruedeftest_two():# 不需要显式声明 auto_logassert11params参数 (与parametrize类似)pytest.fixture(params[1,2,3],ids[one,two,three])# ids 提供更清晰的测试名称defnumber_fixture(request):returnrequest.paramdeftest_number_properties(number_fixture):assertnumber_fixture0# 这个测试会被执行 3 次分别传入 1, 2, 32.2pytest.mark- 标记与控制pytest.mark.skip和pytest.mark.skipifimportsyspytest.mark.skip(reasonFeature not implemented yet)deftest_incomplete_feature():passpytest.mark.skipif(sys.platformwin32,reasonDoes not run on Windows)deftest_unix_specific():# This test will be skipped on Windowspasspytest.mark.xfail- 预期失败pytest.mark.xfail(reasonKnown bug #12345)deftest_known_buggy_functionality():assertbuggy_function()expected_result# 如果返回 expected_result则标记为 XPASS# 如果返回其他值或抛出异常则标记为 XFAILpytest.mark.xfail(strictTrue,reasonMust fix this bug)# strictTrue 意味着如果 XPASS则测试失败deftest_critical_buggy_functionality():assertcritical_buggy_function()fixed_result自定义标记# 在 pytest.ini 中注册标记 (如上所示)pytest.mark.smokedeftest_smoke_login():assertlogin(user,pass)Truepytest.mark.uipytest.mark.slowdeftest_ui_heavy_scenario():# Complex UI testpass# 运行时过滤:# pytest -m smoke # 只运行 smoke 标记的测试# pytest -m ui and not slow # 运行 ui 但不运行 slow 标记的测试# pytest -m not slow # 运行所有非 slow 标记的测试2.3pytest.mark.parametrize- 数据驱动测试基本用法pytest.mark.parametrize(input_val, expected_output,[(2,4),(3,9),(4,16),(-1,1),])deftest_square(input_val,expected_output):assertsquare(input_val)expected_output# 此测试会运行 4 次defsquare(x):returnx*x多参数与idspytest.mark.parametrize(username, password, expected_success,[(admin,secret,True),(user,wrongpass,False),(,any,False),],ids[valid_admin,invalid_pass,empty_user])deftest_login(username,password,expected_success):resultattempt_login(username,password)assertresultexpected_success# 输出中会显示 test_login[valid_admin], test_login[invalid_pass], etc.defattempt_login(username,password):# Simulate login logicreturnusernameadminandpasswordsecretPart 3: Playwright 页面元素选择器详解与样例3.1 Locator API (推荐方式)这些方法基于用户可见性和语义化更稳定。方法说明样例page.get_by_role(role, name...)按 ARIA 角色定位如button,link,textbox,checkbox,radio.page.get_by_role(button, nameSubmit)page.get_by_text(text)按元素内部可见文本定位。page.get_by_text(Sign In).click()page.get_by_label(text)按关联的label标签文本定位输入框等。page.get_by_label(Email:).fill(userexample.com)page.get_by_placeholder(text)按placeholder属性定位。page.get_by_placeholder(Search...).fill(query)page.get_by_alt_text(text)按图片的alt属性定位。page.get_by_alt_text(Logo).click()page.get_by_title(text)按title属性定位。page.get_by_title(Help).click()page.get_by_test_id(test_id_value)按data-testid属性定位最推荐用于测试。page.get_by_test_id(submit-btn).click()HTML 示例formidloginFormlabelforemailEmail Address:/labelinputtypeemailidemailnameemailplaceholderEnter your emaildata-testidemail-inputlabelforpasswordPassword:/labelinputtypepasswordidpasswordnamepassworddata-testidpassword-inputinputtypecheckboxidremembernamerememberdata-testidremember-checkboxlabelforrememberRemember me/labelinputtyperadioidmalenamegendervaluemaledata-testidgender-malelabelformaleMale/labelinputtyperadioidfemalenamegendervaluefemaledata-testidgender-femalelabelforfemaleFemale/labelbuttontypesubmitdata-testidsubmit-btnLog In/button/formPlaywright 样例# conftest.py (典型 fixture 设置)importpytestfromplaywright.sync_apiimportsync_playwrightpytest.fixture(scopesession)defbrowser():withsync_playwright()asp:browserp.chromium.launch(headlessFalse)# Set headlessTrue for CIyieldbrowser browser.close()pytest.fixturedefpage(browser):contextbrowser.new_context()pagecontext.new_page()yieldpage context.close()# test_form_interactions.pydeftest_form_filling_and_submission(page):page.goto(https://your-test-site.com/login.html)# Replace with your URL# Fill inputs using various locatorspage.get_by_label(Email Address:).fill(testexample.com)# Using label textpage.get_by_test_id(password-input).fill(SecurePass123!)# Using test-id# Interact with checkboxes and radio buttonsremember_checkboxpage.get_by_test_id(remember-checkbox)gender_male_radiopage.get_by_test_id(gender-male)gender_female_radiopage.get_by_test_id(gender-female)# Check initial stateassertnotremember_checkbox.is_checked()assertnotgender_male_radio.is_checked()assertnotgender_female_radio.is_checked()# Perform actionsremember_checkbox.check()# Check the boxgender_male_radio.check()# Select male radio# Verify state after actionassertremember_checkbox.is_checked()assertgender_male_radio.is_checked()assertnotgender_female_radio.is_checked()# Female should be unchecked now# Submit the formpage.get_by_test_id(submit-btn).click()# Wait for navigation or specific element after submission# Example: expect(page).to_have_url(/dashboard)# Example: expect(page.get_by_test_id(welcome-message)).to_be_visible()deftest_element_visibility_and_interaction(page):page.goto(https://your-test-site.com/some-page.html)# Wait for an element to be visible before interactingbuttonpage.get_by_role(button,nameLoad More)button.wait_for(statevisible)# Explicit wait if needed, though often automaticbutton.click()# Use text-based locatorstatus_messagepage.get_by_text(Loading...)# Playwright waits for this element to appearassertstatus_message.is_visible()# Use CSS selector if necessary (though less preferred)loading_spinnerpage.locator(.spinner)# CSS class# Wait for it to disappearloading_spinner.wait_for(statedetached)# Verify final statenew_contentpage.get_by_test_id(loaded-content)assertnew_content.is_visible()# test_with_parametrization.pypytest.mark.parametrize(username, password, expected_message,[(valid_user,valid_pass,Welcome),(invalid_user,wrong_pass,Invalid credentials),(,any_pass,Username is required),])deftest_login_scenarios(page,username,password,expected_message):page.goto(https://your-test-site.com/login.html)page.get_by_test_id(username-input).fill(username)page.get_by_test_id(password-input).fill(password)page.get_by_test_id(submit-btn).click()# Wait for and assert error/success messagefromplaywright.sync_apiimportexpect message_elementpage.get_by_test_id(message)# Assume theres a message divexpect(message_element).to_contain_text(expected_message)3.2 Locator 对象的链式操作与过滤deftest_locating_within_containers(page):page.goto(https://your-test-site.com/products.html)# Locate a container firstproduct_listpage.locator(#product-list)# Then find elements within that containerfirst_product_nameproduct_list.locator(.product-name).firstassertfirst_product_name.text_content()Product A# Filter locators based on inner text or other conditionsdelete_buttonspage.get_by_role(button,nameDelete)# Find the delete button for a specific product nametarget_delete_buttondelete_buttons.filter(has_textProduct B).first target_delete_button.click()# Get nth elementthird_itempage.locator(.list-item).nth(2)# Gets the 3rd item (0-indexed)third_item.click()3.3 智能等待 (Implicit Waits)Playwright 的一大优点是内置了智能等待机制。大多数操作如.click(),.fill(),.is_visible()等都会自动等待元素达到所需状态。deftest_smart_waiting(page):page.goto(https://your-test-site.com/delayed-content.html)# Click a button that triggers async content loadingpage.get_by_test_id(load-data-btn).click()# No need for time.sleep()!# The following line waits automatically for the element to become visibledynamic_contentpage.get_by_test_id(dynamic-content)assertdynamic_content.is_visible()assertLoadedindynamic_content.text_content()# Using expect for assertions also waits implicitlyfromplaywright.sync_apiimportexpect expect(dynamic_content).to_contain_text(Data Loaded Successfully)总结pytest通过fixture管理资源和依赖通过mark控制测试行为通过parametrize实现数据驱动。Playwright利用get_by_*等语义化 Locator API 定位元素利用内置等待机制简化测试代码使测试更稳定、更易读。