假设我的步骤定义如下:
Then I would expect to see the following distribution for Ford
| engine | doors | color |
| 2.1L | 4 | red |
我有步骤实现读取表并按如下方式执行断言:
@then('I would expect to see the following distribution for {car_type}')
def step(context, car_type):
car = find_car_method(car_type)
for row in context.table:
for heading in row.headings:
assertEqual(getattr(car, heading),
row[heading],
"%s does not match. " % heading + \
"Found %s" % getattr(car, heading))
(我这样做是因为这种方法允许添加更多字段,但保持它的通用性足以用于检查汽车属性的许多用途。)
当我的汽车对象有4个门(作为int)时,它不匹配,因为数据表要求有'4'门(作为unicode str)。
我可以实现此方法来检查列的名称,并针对不同的字段以不同方式处理它,但是在添加新字段时维护会变得更难,因为还有一个地方可以添加它。我宁愿在步骤数据表中指定它。类似的东西:
Then I would expect to see the following distribution for Ford
| engine | doors:int | color |
| 2.1L | 4 | red |
是否有类似的东西可以用来实现这一点(因为这不起作用)?
请注意,我需要从数据表中创建我遇到同样问题的情况。尝试使用'car'对象的类型来确定类型是没用的,因为在这种情况下它是None。
谢谢,
Baire
答案 0 :(得分:0)
经过一番挖掘,我无法找到任何东西,所以决定实施自己的解决方案。我在这里发帖,因为它可能在将来帮助某人。
我创建了一个辅助方法:
def convert_to_type(full_field_name, value):
""" Converts the value from a behave table into its correct type based on the name
of the column (header). If it is wrapped in a convert method, then use it to
determine the value type the column should contain.
Returns: a tuple with the newly converted value and the name of the field (without the
convertion method specified). E.g. int(size) will return size as the new field
name and the value will be converted to an int and returned.
"""
field_name = full_field_name.strip()
matchers = [(re.compile('int\((.*)\)'), lambda val: int(val)),
(re.compile('float\((.*)\)'), lambda val: float(val)),
(re.compile('date\((.*)\)'), lambda val: datetime.datetime.strptime(val, '%Y-%m-%d'))]
for (matcher, func) in matchers:
matched = matcher.match(field_name)
if matched:
return (func(value), matched.group(1))
return (value, full_field_name)
然后我可以通过以下方式设置:
Then I would expect to see the following distribution for Ford
| engine | int(doors) | color |
| 2.1L | 4 | red |
然后我按步骤改变如下:
@then('I would expect to see the following distribution for {car_type}')
def step(context, car_type):
car = find_car_method(car_type)
for row in context.table:
for heading in row.headings:
(value, field_name) = convert_to_type(heading, row[heading])
assertEqual(getattr(car, field_name),
value,
"%s does not match. " % field_name + \
"Found %s" % getattr(car, field_name))
应该将每个“匹配器”移动到模块级别,因为每次调用方法时都不必重新创建它们。也可以很容易地扩展它以获得更多的转换方法(例如升()和cc()用于解析引擎大小,同时还转换为标准单位。)