官方 github
https://github.com/pytest-dev/pytest-bdd
官方文档
https://pytest-bdd.readthedocs.io/en/latest/
安装
pip install pytest-bdd
快速入门小栗子
quick.feature
创建一个 quick.feature
文件
Feature: Blog
A site where you can publish your articles.
Scenario: Publishing the article
Given I'm an author user
And I have an article
When I go to the article page
And I press the publish button
Then I should not see the error message
And the article should be published
test_quick.py
创建一个 test_quick.py
文件
import pytest
from pytest_bdd import scenario, given, when, then
# pytest fixture
# use for the following step
@pytest.fixture
def auth():
return dict()
@pytest.fixture
def author():
return dict(user={"name": "polo", "age": 24})
# given step
@given("I'm an author user")
def author_user(auth, author: dict):
auth['user'] = author['user']
print("=== auth is ", auth)
# second given step
@given("I have an article", target_fixture="article")
def article(author):
print("=== fixture article: author is ", author)
return author
# when
@when("I go to the article page")
def go_to_article(article):
print("=== go to article ", article)
@when("I press the publish button")
def publish_article():
print("=== opeate: press publish button")
# then
@then("I should not see the error message")
def no_error_message():
print("=== expect: should not see the error message")
assert 1 == 1
@then("the article should be published")
def article_is_published(article):
print("=== expect: the article should be published")
assert article == dict(user={"name": "polo", "age": 24})
# scenario
@scenario('quick.feature', 'Publishing the article')
def test_publish():
pass
pytest 运行
在上述两个文件所在目录下,命令行敲
pytest -sq test_quick.py
运行结果
=== auth is {'user': {'name': 'polo', 'age': 24}}
=== fixture article: author is {'user': {'name': 'polo', 'age': 24}}
=== go to article {'user': {'name': 'polo', 'age': 24}}
=== opeate: press publish button
=== expect: should not see the error message
=== expect: the article should be published
.
1 passed in 0.01s
来拆解知识点了
@scenario
这是场景装饰器,会在最后执行,扒源码
def scenario(feature_name: str, scenario_name: str, encoding: str = "utf-8", features_base_dir=None):
"""Scenario decorator.
:param str feature_name: Feature file name. Absolute or relative to the configured feature base path.
:param str scenario_name: Scenario name.
:param str encoding: Feature file encoding.
"""
前两个位置参数必传,参数解析也很明白了
- feature_name:feature 文件的名,绝对/相对于设置的 feature base path 路径
- scenario_name:在 feature 文件中的 Scenario 关键字后面跟的字符串,场景名称�
假设不写这个装饰器会怎么样
# scenario
# @scenario('quick.feature', 'Publishing the article')
# def test_publish():
# pass
再次运行 pytest 命令
pytest -sq test_quick.py
运行结果
> pytest -sq test_quick.py
no tests ran in 0.00s
没有识别到对应的测试用例
feature 文件的拆解
重要的几个基础关键字
这里用中文来描述一个具体的🌰
Feature: 需求标题,官方网址 - 登录功能
下面是对官方网址 - 登录功能进行设计多个测试场景
以下的描述,可以由非测试人员编写:Feature、Scenario、Given、When、And、Then
通过特定的关键字 + 自然语言,来描述一个用户的操作行为
Scenario: 场景1 - 正常登录
# Given 数据定义,可以只有一个;如果要有多个,需要用 And 关键字
Given 正常登录的用户,用户名:admin 密码:123456
And 这个登录用户的详细信息,性别:女,年龄:24
# When 测试具体的步骤
When 打开登录页面
And 输入用户名
And 输入密码
And 点击登录按钮
# Then 进行判断
Then 登录成功,判断页面链接是否为跳登录跳转后页面的链接
And 验证用户名是否一致
Scenario: 场景2 - 登录失败
...
- Feature:需求背景,一般第一行写一个需求标题,后面几行可以写需求具体的描述;一个 feature 只能有一个 Feature 关键字
- Scenario:测试场景,一个 feature 文件可以有多个场景 Scenario,区分名字即可
- �Given:前置操作,一般用来做预置条件/准备数据,如果有多个可以换行使用 And 关键字
- And:表示当前关键字作用域未结束
- When:具体的操作/测试步骤
- Then:后置操作,一般用来验证结果(断言),数据清理等操作
整体的流程可以简单看成
Given - When - Then
准备 - 执行 - 验证
基础讲完了,后面逐一拆解官方文档