行为驱动设计(BDD)学习

Posted by Shi Hai's Blog on June 12, 2023

BDD诞生背景

行为驱动开发(BDD: Behavior Driven Development)的概念是2003年由Dan North提出来的。Dan North在给很多程序员培训TDD等敏捷实践时,发现大家都有一个共同的问题:不知道从哪里开始进行测试、测试什么,不测试什么,要测试多少次。为了解决这个问题,Dan North就引入了BDD这个概念。可以说BDD是在TDD的基础上演化而来。
在2003年,Dan North还亲自创建了一个工具JBehave用于实践BDD。

用BDD的方式思考

如何使用BDD

JBehave

TBD

cucumber

今天最流行的BDD框架。一个BDD示例:

Scenario: List todo item
  Given todo item "foo" is added
  And todo item "bar" is added
  When list todo items
  Then todo item "foo" should be contained
  And todo item "bar" should be contained

这其实是一门领域特定语言,被称为GherkinGiven 表示一个假设前提,When 表示具体的操作,Then 则对应着这个用例要验证的结果。

pytest bdd

一个来自官网的用例。 在argument.feature文件中定义测试用例。

Feature: Step arguments
    Scenario: Arguments for given, when, then
        Given there are 5 cucumbers

        When I eat 3 cucumbers
        And I eat 2 cucumbers

        Then I should have 0 cucumbers

在test_argument.py中编写测试用例实际执行过程。

from pytest_bdd import scenarios, given, when, then, parsers


scenarios("arguments.feature")


@given(parsers.parse("there are {start:d} cucumbers"), target_fixture="cucumbers")
def given_cucumbers(start):
    return {"start": start, "eat": 0}


@when(parsers.parse("I eat {eat:d} cucumbers"))
def eat_cucumbers(cucumbers, eat):
    cucumbers["eat"] += eat


@then(parsers.parse("I should have {left:d} cucumbers"))
def should_have_left_cucumbers(cucumbers, left):
    assert cucumbers["start"] - cucumbers["eat"] == left

用此命令执行测试用例并获取到执行结果如下所示:

$pytest test_arguments.py -vv

platform linux -- Python 3.9.16, pytest-7.3.2, pluggy-1.0.0 -- /home/shihai/py_venv/309/bin/python3.9
cachedir: .pytest_cache
rootdir: /home/shihai/tests/test_py
plugins: anyio-3.6.2, bdd-6.1.1
collected 1 item

test_arguments.py::test_arguments_for_given_when_then <- ../../py_venv/309/lib64/python3.9/site-packages/pytest_bdd/scenario.py PASSED [100%]

========================================================== 1 passed in 0.02s ==========================================================

features加载

在执行pytest时,pytest会启动一个fixturemanager,这个fixturemanager会遍历并加载所有的fixture 详细代码执行逻辑

steps加载

step的定义和管理是通过pytest.fixture()实现的,导入后的step可以通过request._fixturemanager._arg2fixturedefs获取到所有的fixture和step,代码详情,而执行scenrio时会通过scenario中的step.name去获取在fixturemanager中管理的fixture、step 代码执行逻辑

behave

这是Python语言领域中另一个主流的BDD测试框架,和pytest-bdd比较而言,他的优势之一就是运行的时候不需要通过scenarios()的方式将feature和测试用例一起绑定后才能执行。

vim cucumber/Gherkin插件

关键字驱动测试(keyword-driven testing/table-driven testing/action-word testing)

是一系列可以模仿用户行为,如登录、点击鼠标、输入名字等的可执行关键字的集合。

和BDD的区别

BDD是一种软件开发方法,关键字驱动测试是一种测试方法。BDD侧重于给非技术人员使用以及彼此相互交流,而关键字驱动测试侧重于测试设计和执行逻辑的抽象。

参考文献