0

次のように定義されたステップがあるとします。

 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 として) が必要なため、一致しません。

このメソッドを実装して列の名前を確認し、フィールドごとに異なる方法で処理することもできますが、新しいフィールドを追加するときに、追加する場所がもう 1 つあるため、メンテナンスが難しくなります。代わりに、ステップ データ テーブルで指定することをお勧めします。何かのようなもの:

 Then I would expect to see the following distribution for Ford
      | engine | doors:int | color |
      | 2.1L   | 4         | red   |

これを達成するために使用できる同様のものはありますか (これは機能しないため)。

同じ問題を抱えているデータテーブルから作成する必要がある場合があることに注意してください。この make は、「car」オブジェクトのタイプを使用してタイプを決定しようとしても役に立ちません。その場合は None です。

ありがとうございました、

ベア

4

1 に答える 1

1

掘り下げた後、何も見つけることができなかったので、独自のソリューションを実装することにしました。将来誰かを助けるかもしれないので、ここに投稿しています。

ヘルパー メソッドを作成しました。

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))

メソッドが呼び出されるたびに「マッチャー」を再作成する必要がないため、「マッチャー」をモジュール レベルに移動する必要があります。また、より多くの変換メソッド用に拡張することも簡単です (たとえば、標準単位に変換しながらエンジン サイズを解析するためのliter() および cc())。

于 2016-07-16T21:19:51.243 に答える