杰瑞科技汇

Python自动化测试怎么学?

Python 自动化测试终极指南 (从入门到实战)

目录

  1. 为什么要学习 Python 自动化测试?
  2. 自动化测试基础
  3. Python 测试环境搭建
  4. 核心库与工具详解
    • 1 unittest - Python 内置的单元测试框架
    • 2 pytest - 功能强大且流行的测试框架
    • 3 Selenium - Web 自动化测试利器
    • 4 Requests - API 接口测试神器
    • 5 Appium - 移动应用自动化测试
  5. 实战项目:构建一个 Web UI 自动化测试框架
  6. 实战项目:构建一个 API 自动化测试框架
  7. 高级主题与最佳实践
    • 1 测试报告 (Allure, HTMLTestRunner)
    • 2 持续集成 (CI/CD)
    • 3 Page Object Model (POM) 设计模式
    • 4 参数化与数据驱动
    • 5 Mock 与 Stub (模拟依赖)
  8. 学习资源与社区
  9. 总结与学习路径建议

为什么要学习 Python 自动化测试?

在开始之前,先明确我们为什么要投入时间学习这个技能。

  • 提高效率,节省成本:自动化测试可以 7x24 小时不间断地执行测试用例,替代大量重复的人工回归测试,尤其是在版本迭代频繁的项目中,能极大地解放人力。
  • 提升测试覆盖率:可以轻松执行大量甚至边界情况的测试用例,这是人工测试难以做到的,从而发现更多潜在的 Bug。
  • 提高软件质量:通过快速反馈,开发人员可以在早期阶段就修复缺陷,降低修复成本,提升最终产品的稳定性和可靠性。
  • 回归测试的利器:每次代码更新后,运行自动化测试套件可以确保新代码没有破坏现有功能。
  • 市场需求大:掌握自动化测试技能是软件测试工程师和开发工程师的“加分项”,薪资待遇和发展前景都很好。

自动化测试基础

在敲代码之前,我们需要理解几个核心概念。

测试金字塔

这是理解自动化测试分层的关键模型。

  • 单元测试:金字塔的底层,占比最高,测试的是最小的代码单元(如一个函数、一个方法),由开发人员编写,执行速度快,隔离性强。
  • 集成测试:中间层,测试的是多个模块或服务之间的交互和接口,测试你的代码如何与数据库、API 或其他库协作。
  • 端到端测试:金字塔的顶层,占比最低,模拟真实用户的完整操作流程,从 UI 界面开始,到结束,模拟用户登录、浏览商品、下单、支付的全过程,这类测试最慢、最不稳定,但价值最高。

我们的重点:主要学习API 测试(属于集成测试)和 Web UI 自动化测试(属于端到端测试)。

自动化测试的适用场景

不是所有测试都适合自动化。

  • 适合自动化的场景
    • 回归测试:核心功能,每次迭代都需要验证。
    • 重复性高的测试:数据驱动的测试,如不同用户登录。
    • 多平台/多浏览器兼容性测试
    • 性能测试、负载测试
  • 不适合自动化的场景
    • 探索性测试:需要人的直觉、经验和创造力。
    • 一次性的测试
    • UI 频繁变动的测试(维护成本高)。
    • 用户体验测试

Python 测试环境搭建

这是所有工作的第一步,非常简单。

  1. 安装 Python:从 Python 官网 下载并安装最新稳定版,安装时记得勾选 "Add Python to PATH"。

  2. 安装虚拟环境工具 venv

    • venv 是 Python 3.3+ 自带的虚拟环境管理工具,用于隔离项目依赖,避免包冲突。

    • 在你的项目目录下,打开终端,运行:

      # 创建一个名为 'venv' 的虚拟环境
      python -m venv venv
      # 激活虚拟环境
      # Windows:
      venv\Scripts\activate
      # macOS/Linux:
      source venv/bin/activate
    • 激活后,你的终端提示符前会出现 (venv)

  3. 安装必要的库

    • 在虚拟环境中使用 pip 安装测试库。
      # 安装 pytest
      pip install pytest

    安装 selenium

    pip install selenium

    安装 requests

    pip install requests

    安装 allure-pytest (用于生成漂亮的报告)

    pip install allure-pytest


核心库与工具详解

1 unittest - Python 内置的单元测试框架

unittest 是 Python 标准库的一部分,无需额外安装,它模仿 Java 的 JUnit 框架,结构严谨。

核心概念

  • TestCase:测试用例的基类,你需要创建一个继承自 unittest.TestCase 的类。
  • setUp()tearDown():在每个测试方法执行前/后运行,用于初始化和清理资源。
  • setUpClass()tearDownClass():在所有测试方法执行前/后运行一次,通常用于耗时较长的全局设置。
  • 断言assertEqual, assertTrue, assertFalse, assertIn 等方法,用于验证测试结果是否符合预期。

示例

# test_calculator.py
import unittest
class TestCalculator(unittest.TestCase):
    def setUp(self):
        """在每个测试前运行"""
        self.calc = Calculator()
    def test_add(self):
        """测试加法"""
        result = self.calc.add(2, 3)
        self.assertEqual(result, 5, "加法计算错误")
    def test_subtract(self):
        """测试减法"""
        result = self.calc.subtract(5, 3)
        self.assertTrue(result == 2, "减法计算错误")
    def test_divide_by_zero(self):
        """测试除零异常"""
        with self.assertRaises(ZeroDivisionError):
            self.calc.divide(10, 0)
# 假设我们有一个 Calculator 类
class Calculator:
    def add(self, a, b):
        return a + b
    def subtract(self, a, b):
        return a - b
    def divide(self, a, b):
        return a / b
if __name__ == '__main__':
    unittest.main()

运行

python -m unittest test_calculator.py
2 pytest - 功能强大且流行的测试框架

pytest 是目前 Python 社区最流行的测试框架,它比 unittest 更简洁、更灵活、功能更强大。

核心优势

  • 简洁的语法:无需继承 TestCase,函数名以 test_ 开头即可。
  • 强大的 fixturesfixturespytest 的核心,可以灵活地管理测试资源(类似 setUp/tearDown,但更强大)。
  • 丰富的插件生态:可以轻松集成覆盖率报告、并行执行、Allure 报告等。
  • 内置丰富的断言:当断言失败时,会提供详细的错误信息。

示例

# test_calculator_pytest.py
import pytest
# 直接定义一个 fixture,scope="function" 表示每个测试函数运行前都执行一次
@pytest.fixture
def calculator():
    """提供一个 calculator 实例给测试函数使用"""
    print("正在初始化 Calculator...")
    return Calculator()
def test_add(calculator):
    """测试加法"""
    assert calculator.add(2, 3) == 5
def test_subtract(calculator):
    """测试减法"""
    assert calculator.subtract(5, 3) == 2
# 使用内置的 raises fixture 来测试异常
def test_divide_by_zero(calculator):
    """测试除零异常"""
    with pytest.raises(ZeroDivisionError):
        calculator.divide(10, 0)
# Calculator 类定义同上...

运行

# 自动发现并运行当前目录下所有 test_*.py 或 *_test.py 文件
pytest

建议直接学习 pytest,因为它更现代、更高效,完全能满足从单元测试到 UI/API 测试的所有需求。

3 Selenium - Web 自动化测试利器

Selenium 是一个用于 Web 应用程序测试的工具,它可以直接在浏览器中运行,就像一个真实用户一样。

工作原理:通过 WebDriver 作为浏览器和你的脚本之间的“桥梁”,你的脚本通过 WebDriver API 控制浏览器(打开网页、点击元素、输入文本等)。

安装浏览器驱动

示例

# test_baidu_search.py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 使用 pytest fixture 管理浏览器实例
@pytest.fixture
def browser():
    """初始化并返回一个浏览器实例"""
    driver = webdriver.Chrome() # 确保已安装 ChromeDriver
    driver.implicitly_wait(10) # 隐式等待,全局生效
    yield driver
    driver.quit() # 测试结束后关闭浏览器
def test_baidu_search(browser):
    """测试百度搜索"""
    browser.get("https://www.baidu.com")
    # 使用显式等待,更可靠
    search_box = WebDriverWait(browser, 10).until(
        EC.presence_of_element_located((By.ID, "kw"))
    )
    search_box.send_keys("Python 自动化测试")
    search_box.send_keys(Keys.ENTER)
    # 等待结果页面出现
    WebDriverWait(browser, 10).until(
        EC.title_contains("Python 自动化测试")
    )
    assert "Python 自动化测试" in browser.title

运行

pytest test_baidu_search.py
4 Requests - API 接口测试神器

Requests 是 Python 中最优雅、最简单的 HTTP 库,非常适合用来测试 RESTful API。

核心功能:发送 GET, POST, PUT, DELETE 等请求,并接收响应。

示例

# test_api.py
import pytest
import requests
BASE_URL = "https://jsonplaceholder.typicode.com"
def test_get_posts():
    """测试获取所有帖子"""
    response = requests.get(f"{BASE_URL}/posts")
    assert response.status_code == 200
    assert isinstance(response.json(), list)
    assert len(response.json()) > 0
def test_get_single_post():
    """测试获取单个帖子"""
    post_id = 1
    response = requests.get(f"{BASE_URL}/posts/{post_id}")
    assert response.status_code == 200
    data = response.json()
    assert data['id'] == post_id
    assert 'title' in data
def test_create_post():
    """测试创建一个新帖子"""
    payload = {
        "title": "foo",
        "body": "bar",
        "userId": 1
    }
    response = requests.post(f"{BASE_URL}/posts", json=payload)
    assert response.status_code == 201 # HTTP 201 Created
    data = response.json()
    assert data['title'] == "foo"
    assert 'id' in data # 新创建的资源通常会有一个 ID

运行

pytest test_api.py
5 Appium - 移动应用自动化测试

Appium 是一个移动端的自动化测试框架,支持 iOS 和 Android 平台,它的原理与 Selenium 类似,通过一个 Appium Server 来控制手机或模拟器。

特点

  • 跨平台:一套 API 可以同时测试 iOS 和 Android。
  • 不应用源码:基于黑盒测试,通过 Instrumentation (Android) 和 UIAutomation (iOS) 来驱动。
  • 支持多种语言:包括 Python, Java, Ruby, JS 等。

Python 使用

  • 安装:pip install Appium-Python-Client
  • 需要单独安装 Appium Server 并启动。

由于移动端测试环境搭建相对复杂,建议在学习了 Web 自动化后再进行探索。


实战项目:构建一个 Web UI 自动化测试框架

我们将使用 pytest + Selenium + Allure + POM 模式来构建一个结构清晰的框架。

项目结构:

/web_ui_framework
|-- pages/                  # 存放 Page Object 模型
|   |-- __init__.py
|   |-- base_page.py        # 封装通用操作 (find_element, click 等)
|   |-- baidu_page.py       # 百度首页的元素和操作
|-- tests/                  # 存放测试用例
|   |-- __init__.py
|   |-- test_baidu.py       # 百度搜索的测试用例
|-- conftest.py             # pytest 的配置文件,定义全局 fixtures
|-- config.py               # 配置文件 (如 URL)
|-- requirements.txt        # 项目依赖
|-- pytest.ini              # pytest 的配置文件

步骤 1: 创建 config.py

# config.py
BASE_URL = "https://www.baidu.com"

步骤 2: 创建 pages/base_page.py (封装基础操作)

# pages/base_page.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
    def __init__(self, driver):
        self.driver = driver
    def find_element(self, *locator):
        """查找单个元素"""
        return self.driver.find_element(*locator)
    def find_elements(self, *locator):
        """查找多个元素"""
        return self.driver.find_elements(*locator)
    def click(self, *locator):
        """点击元素"""
        element = WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable(locator)
        )
        element.click()
    def input_text(self, text, *locator):
        """输入文本"""
        element = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located(locator)
        )
        element.clear()
        element.send_keys(text)

步骤 3: 创建 pages/baidu_page.py (百度页面对象)

# pages/baidu_page.py
from selenium.webdriver.common.by import By
from .base_page import BasePage
class BaiduPage(BasePage):
    # 定位器
    search_input_locator = (By.ID, "kw")
    search_button_locator = (By.ID, "su")
    result_link_locator = (By.CSS_SELECTOR, "#content_left > div > h3 > a")
    def search(self, keyword):
        """执行搜索操作"""
        self.input_text(keyword, *self.search_input_locator)
        self.click(*self.search_button_locator)
    def get_first_result_title(self):
        """获取第一个搜索结果的标题"""
        first_result = self.find_element(*self.result_link_locator)
        return first_result.text

步骤 4: 创建 conftest.py (全局 fixture)

# conftest.py
import pytest
from selenium import webdriver
from config import BASE_URL
@pytest.fixture
def driver():
    """全局浏览器 fixture"""
    d = webdriver.Chrome()
    d.maximize_window()
    d.get(BASE_URL)
    yield d
    d.quit()

步骤 5: 创建 tests/test_baidu.py (测试用例)

# tests/test_baidu.py
from pages.baidu_page import BaiduPage
def test_baidu_search(driver):
    """测试百度搜索结果"""
    baidu_page = BaiduPage(driver)
    # 搜索关键词
    baidu_page.search("Python")
    # 获取并断言第一个结果
    first_title = baidu_page.get_first_result_title()
    assert "Python" in first_title

步骤 6: 运行并生成报告

  1. 安装 allure:
    # 下载 allure-commandline 并添加到 PATH
    # 或者使用 pip (不推荐,功能不全)
    pip install allure-pytest
  2. 运行测试:
    # 生成原始数据报告
    pytest --alluredir=./results
  3. 生成 HTML 报告:
    # 在项目根目录下执行
    allure generate results -o report --clean
  4. 查看报告:
    allure open report

    这会打开一个漂亮的、可交互的 HTML 报告页面。


实战项目:构建一个 API 自动化测试框架

API 测试框架更侧重于数据的校验和流程的自动化。

项目结构:

/api_framework
|-- data/                   # 测试数据
|   |-- test_data.json
|-- tests/                  # 测试用例
|   |-- __init__.py
|   |-- test_api.py
|-- utils/                  # 工具类
|   |-- __init__.py
|   |-- request_handler.py  # 封装 requests
|-- config.py               # 配置文件 (如 BASE_URL)
|-- requirements.txt
|-- pytest.ini

步骤 1: 创建 utils/request_handler.py (封装请求)

# utils/request_handler.py
import requests
import json
class RequestHandler:
    def __init__(self, base_url):
        self.base_url = base_url
        self.session = requests.Session()
    def request(self, method, url, **kwargs):
        """发送请求"""
        full_url = self.base_url + url
        response = self.session.request(method, full_url, **kwargs)
        # 可以在这里添加日志、响应断言等
        return response
    def get(self, url, **kwargs):
        return self.request('GET', url, **kwargs)
    def post(self, url, **kwargs):
        return self.request('POST', url, **kwargs)
    # ... 其他方法 PUT, DELETE 等

步骤 2: 创建 data/test_data.json

[
  {
    "name": "获取所有帖子",
    "method": "GET",
    "url": "/posts",
    "expected_status": 200,
    "expected_key": "id"
  },
  {
    "name": "创建新帖子",
    "method": "POST",
    "url": "/posts",
    "payload": {
      "title": "自动化测试框架",
      "body": "这是一个由 Python 构建的 API 测试框架",
      "userId": 1
    },
    "expected_status": 201,
    "expected_key": "title"
  }
]

步骤 3: 创建 tests/test_api.py (数据驱动测试)

# tests/test_api.py
import pytest
import json
from config import BASE_URL
from utils.request_handler import RequestHandler
@pytest.fixture(scope="session")
def api_client():
    """全局 API 客户端 fixture"""
    return RequestHandler(BASE_URL)
# 使用 pytest.mark.parametrize 进行参数化
@pytest.mark.parametrize("test_case", 
                        json.load(open('../data/test_data.json', 'r', encoding='utf-8'))
                       )
def test_api(api_client, test_case):
    """执行 API 测试用例"""
    print(f"\n正在执行测试: {test_case['name']}")
    if test_case['method'].upper() == 'GET':
        response = api_client.get(test_case['url'])
    elif test_case['method'].upper() == 'POST':
        response = api_client.post(test_case['url', json=test_case['payload']])
    # 断言状态码
    assert response.status_code == test_case['expected_status']
    # 断言响应体中包含某个 key
    assert test_case['expected_key'] in response.json()

步骤 4: 运行测试

pytest tests/test_api.py -v

高级主题与最佳实践

1 测试报告
  • Allure:目前最流行的报告生成工具,能生成交互式、内容丰富的报告,包含测试步骤、截图、日志、附件等,与 pytest-allurepytest-allure-pytest 插件配合使用。
  • HTMLTestRunner:一个老牌的生成 HTML 报告的库,简单易用,但功能相对 Allure 较弱。
2 持续集成

自动化测试的价值在于持续执行,将你的测试脚本集成到 CI/CD 流程中。

  • 工具:Jenkins, GitLab CI, GitHub Actions。
  • 流程:当代码被推送到仓库时,CI 服务器会自动拉取代码、安装依赖、运行测试套件,并生成报告和通知,如果测试失败,可以阻止代码合并。
3 Page Object Model (POM) 设计模式

这是 Web UI 自动化测试中最重要的设计模式。

  • 核心思想:将页面的元素定位和业务操作封装在一个类中(Page Object),测试用例只负责调用这些操作,不关心具体的实现细节。
  • 好处
    • 可维护性:当 UI 变化时,只需修改对应的 Page Object 类,而不需要修改所有测试用例。
    • 可读性:测试用例更像业务描述,代码更清晰。
    • 复用性:页面操作可以在不同测试用例间复用。

我们在 实战项目 5 中已经实践了 POM。

4 参数化与数据驱动

将测试数据和测试逻辑分离,让一套测试逻辑可以运行多组数据。

  • 工具pytest.mark.parametrize
  • 数据源:可以是列表、元组、字典,也可以是来自 CSV、Excel、JSON 文件或数据库的数据,这使得测试更加灵活和全面。

我们在 实战项目 6 中使用了 JSON 文件进行数据驱动。

5 Mock 与 Stub (模拟依赖)

在测试中,我们常常会遇到一些难以控制或耗时的外部依赖,如数据库、第三方 API、邮件服务等,Mock 技术可以帮助我们模拟这些依赖。

  • 工具unittest.mock (Python 内置), pytest-mock
  • 作用:用一个“假”的对象替换掉真实的对象,让测试可以独立、快速、稳定地运行,而不受外部环境影响。

学习资源与社区

  • 官方文档
  • 教程与博客
    • Real Python: 有大量高质量的 Python 教程,包括测试。
    • TesterHome: 国内非常活跃的测试技术社区,有大量关于自动化测试的分享。
    • CSDN/掘金/知乎:搜索关键词 "Python 自动化测试",可以找到很多实战文章和教程。
  • 书籍
    • 《Python 自动化测试实战》
    • 《Selenium 自动化测试——基于 Python》
  • 社区
    • Stack Overflow: 解决具体技术问题的首选。
    • GitHub: 阅读优秀的开源测试项目源码是学习的最佳途径之一。

总结与学习路径建议

学习路径建议

  1. 第一阶段:Python 基础与测试理论

    • 掌握 Python 基础语法、函数、类、模块。
    • 理解软件测试的基本概念(黑盒、白盒、回归测试等)。
    • 学习 unittest 或直接上手 pytest,掌握单元测试的编写方法。
  2. 第二阶段:Web 自动化测试入门

    • 学习 Selenium 的基本 API:find_element, click, send_keys 等。
    • 理解显式等待和隐式等待的区别,优先使用显式等待
    • 编写几个简单的 Web UI 自动化脚本,如登录、搜索。
  3. 第三阶段:构建框架与高级 Web 自动化

    • 学习并实践 POM 设计模式,重构你的脚本。
    • 封装 BasePage,提高代码复用性。
    • 集成 pytest,学习 fixture 的使用。
    • 学习 pytest 的参数化功能,实现数据驱动。
    • 集成 Allure,生成专业的测试报告。
  4. 第四阶段:API 自动化测试

    • 学习 Requests 库,熟练掌握 GET/POST/PUT/DELETE 等请求方法。
    • 编写 API 测试用例,重点校验响应状态码、响应头、响应体。
    • 使用 pytest 和 JSON/Excel 文件实现 API 的数据驱动测试。
  5. 第五阶段:持续集成与高级主题

    • 学习使用 GitHub ActionsGitLab CI 配置简单的 CI 流水线。
    • 学习使用 Mock 技术来隔离外部依赖。
    • 探索 性能测试 (如 locust) 或 移动端自动化测试 (如 Appium)。

最重要的建议

  • 多动手实践:看再多教程,不如亲手写一个项目。
  • 阅读优秀源码:去 GitHub 上找一些开源的测试框架学习别人的代码风格和设计思路。
  • 保持好奇心:技术更新很快,持续学习新的工具和最佳实践。

祝你学习顺利,早日成为自动化测试专家!

分享:
扫描分享到社交APP
上一篇
下一篇