大型场景大纲表,无需在步骤定义中明确提及所有参数
Large Scenario Outline tables without having to explicitly mention all parameters in the step definitons
在Python的behave library, I can write a feature file with a parametrised Scenario Outline like so (adapted from this tutorial中):
# feature file
Feature: Scenario Outline Example
Scenario Outline: Use Blender with <thing>
Given I put "<thing>" in a blender
When I switch the blender on
Then it should transform into "<other thing>"
Examples: Amphibians
| thing | other thing |
| Red Tree Frog | mush |
| apples | apple juice |
相应的步骤定义如下所示:
# steps file
from behave import given, when, then
from hamcrest import assert_that, equal_to
from blender import Blender
@given('I put "{thing}" in a blender')
def step_given_put_thing_into_blender(context, thing):
context.blender = Blender()
context.blender.add(thing)
@when('I switch the blender on')
def step_when_switch_blender_on(context):
context.blender.switch_on()
@then('it should transform into "{other_thing}"')
def step_then_should_transform_into(context, other_thing):
assert_that(context.blender.result, equal_to(other_thing))
可以看出,将特征文件中的参数传递到步骤函数中的方法是
- 在尖括号中的功能文件中明确提及它们
- 然后在 step 函数的装饰器中包含用大括号括起来的相同单词(为什么不用尖括号?!)
- 最后插入这些单词作为 step 函数的函数参数。
但是,给定一个更大的示例 table,其中包含很多列,这很快就会让人难以阅读:
# feature file
Feature: Large Table Example
Scenario Outline: Use Blender with a lot of things
Given I put "<first_thing>", "<second_thing>", "<third_thing>", "<fourth_thing>", "<fifth_thing>", "<sixth_thing>", "<seventh_thing>" in a blender
When I switch the blender on
Then it should transform into "<other thing>"
Examples: Things
| first thing | second thing | third thing | fourth thing | fifth thing | sixth thing | seventh thing |
| a | b | c | d | e | f | g | h |
| i | j | k | l | m | n | o | p |
# steps file
@given('I put "{first_thing}", "{second_thing}", "{third_thing}", "{fourth_thing}", "{fifth_thing}", "{sixth_thing}", "{seventh_thing}", in a blender')
def step_given_put_thing_into_blender(context, first_thing, second_thing, third_thing, fourth_thing, fifth_thing, sixth_thing, seventh_thing):
context.blender = Blender()
context.blender.add(thing)
...
我觉得意思很明确。是否有可能将示例从大型 table 转移到步骤定义中,而不必明确提及所有示例?例如,它们是否保存在上下文变量中的某处,即使没有在文本中提及它们(还无法在那里找到它们)?
意思很清楚。
问问自己为什么真的需要所有这些变量?
您是否试图在一个场景大纲中做太多事情?是否可以将您的问题一分为二?
如果您只实现其中一个,即跳过大纲,场景会是什么样子?会不会又大又笨重?
不幸的是,我不认为你的问题是有很多参数要提。您的问题是您尝试使用太多参数。从我的位置来看,你似乎想做的太多了。对不起。
除了考虑是否真的需要使用大型场景大纲 tables(参见另一个答案)之外,确实可以在不明确提及所有参数的情况下访问当前 table 行在 given/when/then 步骤中通过 context.active_outline
(which is a bit hidden in the appendix of the documentation).
context.active_outline
returns a behave.model.row object 可以通过以下方式访问:
context.active_outline.headings
returns 是 table headers 的列表,无论当前迭代的行是什么 (first_thing 、second_thing 等问题示例中的 )
context.active_outline.cells
returns 当前迭代行的单元格值列表 (a, b , c 等在问题的例子中)
- index-based 像
context.active_outline[0]
return 一样访问第一列的单元格值(无论标题如何)等
- named-based 像
context.active_outline['first_thing']
return 一样访问具有 first_thing [=56= 的列的单元格值], 不管它的索引
作为 context.active_outline.headings
和 context.active_outline.cells
return 列表,还可以做一些有用的事情,例如 for heading, cell in zip(context.active_outline.headings, context.active_outline.cells)
来遍历 heading-value 对等
在Python的behave library, I can write a feature file with a parametrised Scenario Outline like so (adapted from this tutorial中):
# feature file
Feature: Scenario Outline Example
Scenario Outline: Use Blender with <thing>
Given I put "<thing>" in a blender
When I switch the blender on
Then it should transform into "<other thing>"
Examples: Amphibians
| thing | other thing |
| Red Tree Frog | mush |
| apples | apple juice |
相应的步骤定义如下所示:
# steps file
from behave import given, when, then
from hamcrest import assert_that, equal_to
from blender import Blender
@given('I put "{thing}" in a blender')
def step_given_put_thing_into_blender(context, thing):
context.blender = Blender()
context.blender.add(thing)
@when('I switch the blender on')
def step_when_switch_blender_on(context):
context.blender.switch_on()
@then('it should transform into "{other_thing}"')
def step_then_should_transform_into(context, other_thing):
assert_that(context.blender.result, equal_to(other_thing))
可以看出,将特征文件中的参数传递到步骤函数中的方法是
- 在尖括号中的功能文件中明确提及它们
- 然后在 step 函数的装饰器中包含用大括号括起来的相同单词(为什么不用尖括号?!)
- 最后插入这些单词作为 step 函数的函数参数。
但是,给定一个更大的示例 table,其中包含很多列,这很快就会让人难以阅读:
# feature file
Feature: Large Table Example
Scenario Outline: Use Blender with a lot of things
Given I put "<first_thing>", "<second_thing>", "<third_thing>", "<fourth_thing>", "<fifth_thing>", "<sixth_thing>", "<seventh_thing>" in a blender
When I switch the blender on
Then it should transform into "<other thing>"
Examples: Things
| first thing | second thing | third thing | fourth thing | fifth thing | sixth thing | seventh thing |
| a | b | c | d | e | f | g | h |
| i | j | k | l | m | n | o | p |
# steps file
@given('I put "{first_thing}", "{second_thing}", "{third_thing}", "{fourth_thing}", "{fifth_thing}", "{sixth_thing}", "{seventh_thing}", in a blender')
def step_given_put_thing_into_blender(context, first_thing, second_thing, third_thing, fourth_thing, fifth_thing, sixth_thing, seventh_thing):
context.blender = Blender()
context.blender.add(thing)
...
我觉得意思很明确。是否有可能将示例从大型 table 转移到步骤定义中,而不必明确提及所有示例?例如,它们是否保存在上下文变量中的某处,即使没有在文本中提及它们(还无法在那里找到它们)?
意思很清楚。
问问自己为什么真的需要所有这些变量?
您是否试图在一个场景大纲中做太多事情?是否可以将您的问题一分为二?
如果您只实现其中一个,即跳过大纲,场景会是什么样子?会不会又大又笨重?
不幸的是,我不认为你的问题是有很多参数要提。您的问题是您尝试使用太多参数。从我的位置来看,你似乎想做的太多了。对不起。
除了考虑是否真的需要使用大型场景大纲 tables(参见另一个答案)之外,确实可以在不明确提及所有参数的情况下访问当前 table 行在 given/when/then 步骤中通过 context.active_outline
(which is a bit hidden in the appendix of the documentation).
context.active_outline
returns a behave.model.row object 可以通过以下方式访问:
context.active_outline.headings
returns 是 table headers 的列表,无论当前迭代的行是什么 (first_thing 、second_thing 等问题示例中的 )context.active_outline.cells
returns 当前迭代行的单元格值列表 (a, b , c 等在问题的例子中)- index-based 像
context.active_outline[0]
return 一样访问第一列的单元格值(无论标题如何)等 - named-based 像
context.active_outline['first_thing']
return 一样访问具有 first_thing [=56= 的列的单元格值], 不管它的索引
作为 context.active_outline.headings
和 context.active_outline.cells
return 列表,还可以做一些有用的事情,例如 for heading, cell in zip(context.active_outline.headings, context.active_outline.cells)
来遍历 heading-value 对等