背景

看看 @given、@when、@when 的源码

  1. def given(name, converters=None, target_fixture=None):
  2. """Given step decorator.
  3. :param name: Step name or a parser object.
  4. :param converters: Optional `dict` of the argument or parameter converters in form
  5. {<param_name>: <converter function>}.
  6. :param target_fixture: Target fixture name to replace by steps definition function.
  7. :return: Decorator function for the step.
  8. """
  9. return _step_decorator(GIVEN, name, converters=converters, target_fixture=target_fixture)
  10. def when(name, converters=None, target_fixture=None):
  11. """When step decorator.
  12. :param name: Step name or a parser object.
  13. :param converters: Optional `dict` of the argument or parameter converters in form
  14. {<param_name>: <converter function>}.
  15. :param target_fixture: Target fixture name to replace by steps definition function.
  16. :return: Decorator function for the step.
  17. """
  18. return _step_decorator(WHEN, name, converters=converters, target_fixture=target_fixture)
  19. def then(name, converters=None, target_fixture=None):
  20. """Then step decorator.
  21. :param name: Step name or a parser object.
  22. :param converters: Optional `dict` of the argument or parameter converters in form
  23. {<param_name>: <converter function>}.
  24. :param target_fixture: Target fixture name to replace by steps definition function.
  25. :return: Decorator function for the step.
  26. """
  27. return _step_decorator(THEN, name, converters=converters, target_fixture=target_fixture)

类型

string(默认)

可以视为精确解析器,它不解析任何参数,根据提供的字符串精确匹配对应的步骤名称

parse(基于 pypi_parse)

  • 提供一个简单的解析器,用像{param:Type}可读语法替换步骤参数的正则表达式
  • 可以不提供类型 {username}
  • 也可以提供类型{username:s}
  • 这个类型和写 string.format(“%s”) 时,支持的类型一样,比如 %d、%s、%f

cfparse(基于 pypi_parse_type)

没看懂官方文档的解析,乱七八糟的描述

re

支持完整的正则表达式来解析步骤参数,必须用这个表达式(?P<name>…)

parse 的 🌰(比较常用)

parser.feature

  1. Feature: Step arguments
  2. Scenario: Arguments for given, when, then
  3. Given there are 5 cucumbers
  4. When I eat 3 cucumbers
  5. And I eat 2 cucumbers
  6. Then I should have 0 cucumbers

test_parser.py

  1. from pytest_bdd import scenario, given, when, then, parsers
  2. @scenario("parser.feature", "Arguments for given, when, then")
  3. def test_arguments():
  4. pass
  5. @given(parsers.parse("there are {start:d} cucumbers"), target_fixture="cucumbers")
  6. def given_cucumbers(start):
  7. print(start, type(start))
  8. return dict(start=start, eat=0)
  9. @when(parsers.parse("I eat {eat} cucumbers"))
  10. def eat_cucumbers(cucumbers, eat):
  11. print(eat, type("eat"))
  12. cucumbers["eat"] += int(eat)
  13. @then(parsers.parse("I should have {left:d} cucumbers"))
  14. def should_have_left_cucumbers(cucumbers, left):
  15. assert cucumbers['start'] - cucumbers['eat'] == left

命令行运行

  1. pytest -sq test_parsers.py

运行结果

  1. 5 <class 'int'>
  2. 3 <class 'str'>
  3. 2 <class 'str'>
  4. .
  5. 1 passed in 0.01s