Python自动化测试框架实战后端转 Rust 的萌新ID 第一程序员——名字大人很菜暂时。正在跟所有权和生命周期死磕日常记录 Rust 学习路上的踩坑经验和啊哈时刻代码片段保证能跑。保持学习保持输出。欢迎大佬们轻喷也欢迎同好一起进步。前言最近在学习 Python 的过程中我深刻认识到自动化测试的重要性。良好的测试可以帮助我们发现代码中的错误提高代码质量减少回归 bug同时也可以让我们更自信地进行代码重构。Python 拥有丰富的自动化测试框架如 unittest、pytest、selenium 等这些框架各有特点适用于不同的测试场景。今天就来分享一下我的 Python 自动化测试框架实战经验希望能帮到和我一样的萌新们。常见的 Python 自动化测试框架1. unittestunittest 是 Python 标准库中的测试框架它提供了完整的测试工具集包括测试发现、测试套件、测试运行器等。优点是 Python 标准库的一部分不需要额外安装提供了完整的测试框架功能支持测试发现和测试套件支持 setUp 和 tearDown 方法缺点语法相对繁琐需要编写较多的 boilerplate 代码断言方法有限不支持参数化测试适用场景简单的单元测试对测试框架依赖要求较低的项目学习测试基础概念示例import unittest class TestStringMethods(unittest.TestCase): def setUp(self): # 测试前的准备工作 self.test_string hello world def tearDown(self): # 测试后的清理工作 pass def test_upper(self): self.assertEqual(self.test_string.upper(), HELLO WORLD) def test_isupper(self): self.assertFalse(self.test_string.isupper()) self.assertTrue(HELLO.isupper()) def test_split(self): s hello world self.assertEqual(s.split(), [hello, world]) # 检查分割后的结果是否符合预期 with self.assertRaises(TypeError): s.split(2) if __name__ __main__: unittest.main()2. pytestpytest 是一个功能强大的第三方测试框架它提供了简洁的语法、丰富的插件生态和强大的测试功能。优点语法简洁不需要继承特定的测试类支持参数化测试支持 fixtures 进行测试准备和清理丰富的插件生态强大的断言能力支持测试发现和测试过滤缺点需要额外安装对于初学者来说插件体系可能有些复杂适用场景单元测试集成测试功能测试需要复杂测试场景的项目示例import pytest def test_upper(): assert hello world.upper() HELLO WORLD def test_isupper(): assert not hello world.isupper() assert HELLO.isupper() def test_split(): s hello world assert s.split() [hello, world] with pytest.raises(TypeError): s.split(2) # 参数化测试 pytest.mark.parametrize(input, expected, [ (hello, HELLO), (world, WORLD), (test, TEST), ]) def test_parametrized_upper(input, expected): assert input.upper() expected # fixtures def pytest.fixture def setup_test_string(): return hello world def test_with_fixture(setup_test_string): assert setup_test_string.upper() HELLO WORLD3. SeleniumSelenium 是一个用于 Web 应用自动化测试的工具它可以模拟用户在浏览器中的操作。优点支持多种浏览器可以模拟真实用户操作支持多种编程语言强大的元素定位能力缺点运行速度较慢依赖浏览器和 WebDriver容易受到页面结构变化的影响适用场景Web 应用的功能测试端到端测试用户界面测试示例from selenium import webdriver from selenium.webdriver.common.by import By import time def test_google_search(): # 初始化浏览器 driver webdriver.Chrome() try: # 打开 Google driver.get(https://www.google.com) # 定位搜索框并输入搜索内容 search_box driver.find_element(By.NAME, q) search_box.send_keys(Python automation testing) search_box.submit() # 等待搜索结果加载 time.sleep(2) # 验证搜索结果 assert Python automation testing in driver.title # 定位搜索结果链接 search_results driver.find_elements(By.CSS_SELECTOR, h3) assert len(search_results) 0 finally: # 关闭浏览器 driver.quit()4. RequestsRequests 是一个用于 HTTP 请求的库它可以用于 API 测试。优点语法简洁使用方便支持各种 HTTP 方法支持会话管理支持文件上传和下载缺点只适用于 API 测试不支持浏览器操作适用场景RESTful API 测试HTTP 服务测试接口测试示例import requests def test_get_request(): response requests.get(https://httpbin.org/get) assert response.status_code 200 assert args in response.json() def test_post_request(): data {name: test, value: 123} response requests.post(https://httpbin.org/post, jsondata) assert response.status_code 200 assert response.json()[json] data def test_put_request(): data {name: updated, value: 456} response requests.put(https://httpbin.org/put, jsondata) assert response.status_code 200 assert response.json()[json] data def test_delete_request(): response requests.delete(https://httpbin.org/delete) assert response.status_code 2005. Pytest-BDDPytest-BDD 是基于行为驱动开发BDD的测试框架它使用 Gherkin 语言编写测试场景。优点测试场景使用自然语言描述易于理解支持 Given-When-Then 语法与 pytest 集成支持 pytest 的所有功能缺点需要学习 Gherkin 语法对于简单测试来说可能有些繁琐适用场景行为驱动开发需求驱动的测试团队协作测试示例# features/example.feature Feature: Example feature Scenario: Example scenario Given I have a string hello When I uppercase the string Then the result should be HELLO # tests/test_example.py from pytest_bdd import scenario, given, when, then scenario(features/example.feature, Example scenario) def test_example(): pass given(I have a string hello) def have_string(): return hello when(I uppercase the string) def uppercase_string(have_string): return have_string.upper() then(the result should be HELLO) def check_result(uppercase_string): assert uppercase_string HELLO实战案例使用 pytest 进行单元测试需求分析我们将创建一个简单的计算器类并使用 pytest 对其进行单元测试。实现步骤创建计算器类实现基本的算术操作编写测试用例测试计算器的各种功能运行测试使用 pytest 运行测试并查看结果分析测试结果根据测试结果调整代码代码实现计算器类# calculator.py class Calculator: def add(self, a, b): 加法操作 return a b def subtract(self, a, b): 减法操作 return a - b def multiply(self, a, b): 乘法操作 return a * b def divide(self, a, b): 除法操作 if b 0: raise ValueError(除数不能为零) return a / b测试用例# test_calculator.py import pytest from calculator import Calculator pytest.fixture def calculator(): return Calculator() def test_add(calculator): assert calculator.add(1, 2) 3 assert calculator.add(-1, 1) 0 assert calculator.add(0, 0) 0 assert calculator.add(1.5, 2.5) 4.0 def test_subtract(calculator): assert calculator.subtract(5, 3) 2 assert calculator.subtract(1, 5) -4 assert calculator.subtract(0, 0) 0 assert calculator.subtract(4.5, 2.5) 2.0 def test_multiply(calculator): assert calculator.multiply(2, 3) 6 assert calculator.multiply(-1, 5) -5 assert calculator.multiply(0, 100) 0 assert calculator.multiply(2.5, 4) 10.0 def test_divide(calculator): assert calculator.divide(10, 2) 5 assert calculator.divide(5, 2) 2.5 assert calculator.divide(-10, 2) -5 with pytest.raises(ValueError, match除数不能为零): calculator.divide(10, 0) # 参数化测试 pytest.mark.parametrize(a, b, expected, [ (1, 2, 3), (-1, 1, 0), (0, 0, 0), (1.5, 2.5, 4.0), ]) def test_parametrized_add(calculator, a, b, expected): assert calculator.add(a, b) expected运行测试# 安装 pytest pip install pytest # 运行测试 pytest test_calculator.py -v # 运行特定测试 pytest test_calculator.py::test_add -v # 运行带有特定标记的测试 pytest test_calculator.py -m slow -v # 生成测试报告 pytest test_calculator.py --htmlreport.html实战案例使用 Selenium 进行 Web 自动化测试需求分析我们将使用 Selenium 测试一个简单的登录功能包括输入用户名和密码点击登录按钮验证登录是否成功。实现步骤安装 Selenium安装 Selenium 和 WebDriver编写测试用例测试登录功能运行测试使用 pytest 运行测试并查看结果分析测试结果根据测试结果调整测试用例代码实现测试用例# test_login.py from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import pytest pytest.fixture def driver(): # 初始化浏览器 driver webdriver.Chrome() driver.implicitly_wait(10) yield driver # 测试结束后关闭浏览器 driver.quit() def test_login_success(driver): # 打开登录页面 driver.get(https://example.com/login) # 输入用户名和密码 username_input driver.find_element(By.ID, username) password_input driver.find_element(By.ID, password) username_input.send_keys(testuser) password_input.send_keys(testpassword) # 点击登录按钮 login_button driver.find_element(By.ID, login-button) login_button.click() # 等待登录成功页面加载 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, welcome-message)) ) # 验证登录成功 welcome_message driver.find_element(By.ID, welcome-message) assert Welcome in welcome_message.text def test_login_failure(driver): # 打开登录页面 driver.get(https://example.com/login) # 输入错误的用户名和密码 username_input driver.find_element(By.ID, username) password_input driver.find_element(By.ID, password) username_input.send_keys(testuser) password_input.send_keys(wrongpassword) # 点击登录按钮 login_button driver.find_element(By.ID, login-button) login_button.click() # 等待错误消息显示 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, error-message)) ) # 验证错误消息 error_message driver.find_element(By.ID, error-message) assert Invalid username or password in error_message.text运行测试# 安装 Selenium pip install selenium # 下载 WebDriverChromeDriver并添加到 PATH # 运行测试 pytest test_login.py -v实战案例使用 Requests 进行 API 测试需求分析我们将使用 Requests 测试一个简单的 RESTful API包括 GET、POST、PUT 和 DELETE 请求。实现步骤安装 Requests安装 Requests 库编写测试用例测试 API 的各种功能运行测试使用 pytest 运行测试并查看结果分析测试结果根据测试结果调整测试用例代码实现测试用例# test_api.py import requests import pytest BASE_URL https://jsonplaceholder.typicode.com def test_get_posts(): 测试获取帖子列表 response requests.get(f{BASE_URL}/posts) assert response.status_code 200 posts response.json() assert isinstance(posts, list) assert len(posts) 0 def test_get_post(): 测试获取单个帖子 post_id 1 response requests.get(f{BASE_URL}/posts/{post_id}) assert response.status_code 200 post response.json() assert post[id] post_id def test_create_post(): 测试创建帖子 data { title: Test Post, body: This is a test post, userId: 1 } response requests.post(f{BASE_URL}/posts, jsondata) assert response.status_code 201 post response.json() assert post[title] data[title] assert post[body] data[body] assert post[userId] data[userId] def test_update_post(): 测试更新帖子 post_id 1 data { title: Updated Test Post, body: This is an updated test post, userId: 1 } response requests.put(f{BASE_URL}/posts/{post_id}, jsondata) assert response.status_code 200 post response.json() assert post[id] post_id assert post[title] data[title] assert post[body] data[body] def test_delete_post(): 测试删除帖子 post_id 1 response requests.delete(f{BASE_URL}/posts/{post_id}) assert response.status_code 200运行测试# 安装 Requests pip install requests # 运行测试 pytest test_api.py -v测试最佳实践测试隔离每个测试应该独立运行不依赖于其他测试的状态测试覆盖确保测试覆盖主要的功能和边界情况测试命名使用清晰、描述性的测试名称测试数据使用合适的测试数据包括正常情况和边界情况测试速度保持测试运行速度快便于频繁运行测试维护定期更新测试确保测试与代码同步测试报告生成详细的测试报告便于分析测试结果持续集成在持续集成系统中运行测试确保代码质量常见问题与解决方案1. 测试运行慢问题测试运行速度慢影响开发效率。解决方案减少测试中的网络请求和数据库操作使用 mock 模拟外部依赖并行运行测试只运行相关的测试2. 测试不稳定问题测试有时通过有时失败不稳定。解决方案确保测试环境一致避免测试之间的依赖处理测试中的异步操作增加适当的等待时间3. 测试代码维护困难问题测试代码难以维护随着代码的变化需要频繁更新。解决方案使用 fixtures 减少重复代码采用页面对象模式Page Object Pattern管理 UI 测试保持测试代码简洁明了定期重构测试代码4. 测试覆盖不足问题测试覆盖不足无法发现所有的 bug。解决方案使用测试覆盖工具如 coverage.py分析覆盖情况针对边界情况和异常情况编写测试定期审查测试覆盖报告总结Python 拥有丰富的自动化测试框架每个框架都有其特点和适用场景。unittest 是 Python 标准库的一部分适合简单的单元测试pytest 提供了简洁的语法和丰富的功能适合各种测试场景Selenium 用于 Web 应用的自动化测试Requests 用于 API 测试Pytest-BDD 用于行为驱动开发。通过使用这些测试框架我们可以编写高质量的测试代码提高代码质量减少回归 bug同时也可以让我们更自信地进行代码重构。作为一个从后端转 Rust 的萌新我在学习 Python 自动化测试的过程中遇到了一些挑战也学到了很多东西。通过不断学习和实践我相信我能够编写更加有效的测试代码。保持学习保持输出今天的 Python 自动化测试框架实战文章就到这里希望对大家有所帮助。欢迎在评论区分享你的经验和问题我们一起进步参考资料unittest 官方文档pytest 官方文档Selenium 官方文档Requests 官方文档Pytest-BDD 官方文档后端转 Rust 的萌新ID 第一程序员——名字大人很菜暂时。正在跟所有权和生命周期死磕日常记录 Rust 学习路上的踩坑经验和啊哈时刻代码片段保证能跑。保持学习保持输出。欢迎大佬们轻喷也欢迎同好一起进步。