Gerkin+Pytest(python)实现自动化(BDD)

将 ​​BDD(行为驱动开发)​ ​ 思想与 ​​pytest + Python​​ 框架结合来实现自动化测试,是一个非常强大和现代的方法。可以让我们在享有 pytest 所有强大功能(如 fixture、参数化、丰富插件)的同时,编写出业务方也能看懂的、活文档式的测试用例。

相较于unitttes+Gerkin 只需要一个插件便可以实现

目录

一、核心工具选择

二、项目目录结构

三、实现步骤

[步骤 1: 编写 Gherkin 特性文件 (.feature)](#步骤 1: 编写 Gherkin 特性文件 (.feature))

[步骤 2: 实现步骤定义 (Step Definitions)](#步骤 2: 实现步骤定义 (Step Definitions))

[步骤 3: (可选但推荐) 使用 Page Object 模式](#步骤 3: (可选但推荐) 使用 Page Object 模式)

[步骤 4: 配置 Fixture (如初始化浏览器)](#步骤 4: 配置 Fixture (如初始化浏览器))

四、运行测试与生成报告

运行测试

生成丰富的报告

[五、BDD + pytest 的优势](#五、BDD + pytest 的优势)


一、核心工具选择

要实现这个组合,核心是使用 ​​pytest-bdd​ ​ 插件。它是 pytest 的一个插件,允许你使用 Gherkin 语法编写特性文件(.feature),并用 pytest 来执行它们。

​安装所需库:​

bash 复制代码
pip install pytest pytest-bdd
# 如果需要Web自动化,再安装
pip install selenium

二、项目目录结构

一个清晰的结构是成功的一半。推荐的组织方式如下:

bash 复制代码
project_root/
│
├── features/               # 存放所有的Gherkin特性文件
│   ├── login.feature
│   └── shopping_cart.feature
│
├── tests/                  # 存放所有的测试代码
│   ├── __init__.py
│   ├── conftest.py        # pytest的全局 fixture 配置
│   └── test_features/     # 按功能模块组织步骤定义和测试
│       ├── __init__.py
│       ├── test_login.py  # 登录功能的步骤定义
│       └── test_cart.py   # 购物车功能的步骤定义
│
└── pages/                 # (可选)Page Object模型目录
    ├── __init__.py
    ├── base_page.py
    ├── login_page.py
    └── cart_page.py

三、实现步骤

步骤 1: 编写 Gherkin 特性文件 (.feature)

features/login.feature中,用业务语言描述行为。

python 复制代码
# features/login.feature
Feature: User Login
    As a user of the website
    I want to log into my account
    So that I can access my personal dashboard

    Scenario: Successful login with valid credentials
        Given the user is on the login page
        When the user enters a valid username and password
        And clicks the login button
        Then the user is redirected to the dashboard
        And a welcome message containing "Welcome" is displayed

    Scenario Outline: Failed login attempts
        Given the user is on the login page
        When the user enters username "<username>" and password "<password>"
        And clicks the login button
        Then an error message "<error_message>" should be displayed

        Examples:
            | username      | password | error_message          |
            | invalid_user  | Pass123  | Invalid username       |
            | testuser      | wrong    | Invalid password       |
            | ""            | Pass123  | Username is required   |
步骤 2: 实现步骤定义 (Step Definitions)

tests/test_features/test_login.py中,编写 Python 代码来实现每个 Gherkin 步骤。

​关键点:​

  • 使用 @given, @when, @then装饰器将函数映射到 Gherkin 步骤。

  • pytest-bdd支持从步骤中​​提取参数​​(使用正则表达式或解析器)。

  • 使用 pytestassert进行断言。

python 复制代码
# tests/test_features/test_login.py
import pytest
from pytest_bdd import scenarios, given, when, then, parsers
from pages.login_page import LoginPage # 导入Page Object

# 让pytest-bdd发现并加载login.feature文件
scenarios("../../features/login.feature")

# 共享 fixture:在 conftest.py 中定义 browser fixture
@pytest.fixture
def login_page(browser): # 'browser' 是另一个fixture,例如初始化Selenium WebDriver
    return LoginPage(browser)

# 实现 "Given the user is on the login page" 步骤
@given("the user is on the login page")
def go_to_login_page(login_page):
    login_page.load()

# 实现 "When the user enters a valid username and password"
@when("the user enters a valid username and password")
def enter_valid_credentials(login_page):
    login_page.enter_username("standard_user")
    login_page.enter_password("secret_sauce")

# 实现带参数的步骤(用于Scenario Outline)
@when(parsers.cfparse('the user enters username "{username}" and password "{password}"'))
def enter_credentials(login_page, username, password):
    login_page.enter_username(username)
    login_page.enter_password(password)

# 实现点击登录按钮的步骤(可以被多个场景复用)
@when("clicks the login button")
def click_login(login_page):
    login_page.click_login()

# 实现结果验证步骤,并提取欢迎消息中的部分文本
@then(parsers.cfparse('a welcome message containing "{message_text}" is displayed'))
def verify_welcome_message(login_page, message_text):
    actual_message = login_page.get_welcome_message()
    assert message_text in actual_message, f"Expected '{message_text}' in message, but got '{actual_message}'"

# 实现结果验证步骤,验证错误消息
@then(parsers.cfparse('an error message "{expected_message}" should be displayed'))
def verify_error_message(login_page, expected_message):
    actual_message = login_page.get_error_message()
    assert actual_message == expected_message, f"Expected '{expected_message}', but got '{actual_message}'"
步骤 3: (可选但推荐) 使用 Page Object 模式

pages/login_page.py中封装页面逻辑,使步骤定义文件更清晰、更易维护。

python 复制代码
# pages/login_page.py
class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.url = "https://www.saucedemo.com/"

    def load(self):
        self.driver.get(self.url)

    def enter_username(self, username):
        self.driver.find_element("id", "user-name").send_keys(username)

    def enter_password(self, password):
        self.driver.find_element("id", "password").send_keys(password)

    def click_login(self):
        self.driver.find_element("id", "login-button").click()

    def get_welcome_message(self):
        # 假设登录成功后跳转到dashboard,这里有欢迎信息
        return self.driver.find_element("css selector", ".title").text

    def get_error_message(self):
        # 定位错误信息元素
        return self.driver.find_element("css selector", "[data-test='error']").text
步骤 4: 配置 Fixture (如初始化浏览器)

tests/conftest.py中定义全局的 fixture。

python 复制代码
# tests/conftest.py
import pytest
from selenium import webdriver

@pytest.fixture(scope="session")
def browser():
    # 初始化浏览器,这里以Chrome为例
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    yield driver
    # 测试结束后退出浏览器
    driver.quit()

# 可以在这里定义其他全局fixture

四、运行测试与生成报告

运行测试

你可以像运行普通 pytest 测试一样运行 BDD 测试:

python 复制代码
# 运行所有测试
pytest

# 运行特定feature的测试
pytest tests/test_features/test_login.py -v

# 使用pytest-bdd的特定选项,例如显示场景名称
pytest --cucumberjson=results.json  # 生成Cucumber风格的JSON报告
生成丰富的报告

​1. 生成 HTML 报告(推荐):​

bash 复制代码
pip install pytest-html
pytest --html=report.html

​2. 生成 Allure 报告(非常强大美观):​

bash 复制代码
pip install allure-pytest
pytest --alluredir=allure_results
allure serve allure_results  # 在本地查看报告

五、BDD + pytest 的优势

  1. ​业务可读性​ ​:.feature文件可以作为活文档,方便产品、测试、开发三方沟通。

  2. ​强大的 pytest 生态​​:你可以使用所有 pytest 的特性:fixture、参数化、标记(mark)、丰富的插件等。

  3. ​灵活的目录结构​ ​:不像 behave那样强制要求固定的目录结构。

  4. ​优秀的报告​​:可以生成多种格式的详细测试报告。

  5. ​易于集成CI/CD​​:可以轻松地与 Jenkins、GitLab CI 等工具集成。

相关推荐
大佐不会说日语~2 小时前
若依框架 (Spring Boot 3) 集成 knife4j 实现 OpenAPI 文档增强
spring boot·后端·python
MATLAB代码顾问2 小时前
Python实现手榴弹爆炸算法(Grenade Explosion Method, GEM)(附完整代码)
开发语言·python·算法
困鲲鲲2 小时前
NumPy 系列(六):numpy 数组函数
python·numpy
人工干智能2 小时前
Python的大杀器:Jupyter Notebook处理.ipynb文件
开发语言·python·jupyter
跳跳的向阳花3 小时前
02、Python从入门到癫狂:函数与数据容器
开发语言·python
这里有鱼汤3 小时前
如何用Python找到股票的支撑位和压力位?——均线簇
后端·python
啃啃大瓜3 小时前
字符串
python
啊森要自信3 小时前
【 GUI自动化测试】GUI自动化测试(一) 环境安装与测试
开发语言·python·ui·单元测试·pytest
love530love4 小时前
EPGF架构:Python开发的长效稳定之道
开发语言·ide·人工智能·windows·python·架构·pycharm