如何在行为测试中多次调用场景而没有表格化项目?

时间:2016-07-06 10:46:49

标签: bdd gherkin python-behave

我想在没有分项目的情况下在Gherkin测试中调用场景 - 让我们说500次。原因是我想使用随机变量而不是自己写的。 我知道如何为测试实现随机功能,但只调用一次。

例如:

Scenario Outline: I want to test speed with different values
    When I set the speed to <speed>
    And I wait for 5 seconds
    Then it plays at <speed>

    Examples:
    | speed       |
    | 10   |
    | 20   |
    | 30   |
    | 40   |
    | 50   |

导入随机

速度= [&#39; 10&#39;,&#39; 20&#39;,&#39; 30&#39;,&#39; 40&#39;,&#39; 50&#39; ]

def next_speed():     return random.choice(速度)

如果我使用这样的随机功能,我该如何调用此场景500次?

提前致谢。

5 个答案:

答案 0 :(得分:0)

在过去的两年中,我一直在不断地思考这个问题,而我一直在使用Behave。我用它来驱动关键通信无线电的功能测试环境,以及它们所处的环境(播放/录制音频,对WAV文件进行一些深度学习以确认内容,使用其UI并四处导航以创建消息,诸如此类)。

我需要尝试在提供数据表的单行之外循环执行操作。

当我在研究Content对象的某些凹口时,我钻研了解释器,我想知道是否可以设法实现它:

    When I loop i 5 times
      And I perform this action
      And I perform another action
    Then I should see this result
      And loop back to i

这不会破坏gherkin语法,并且只要我可以在循环步骤中实现一些可以以某种方式倒回解析器的方式,它就应该再次运行它们。我怀疑,最困难的部分是确保保留所有步骤的结果:我需要深入研究用于存储结果的结构,以便输出显示所有迭代。

还有没有其他人考虑通过已定义的步骤将其实现为“行为”?

答案 1 :(得分:0)

from __future__ import print_function
import functools
from behave.model import ScenarioOutline


def patch_scenario_with_autoretry(scenario, max_attempts=3):
    """Monkey-patches :func:`~behave.model.Scenario.run()` to auto-retry a
    scenario that fails. The scenario is retried a number of times
    before its failure is accepted.
    This is helpful when the test infrastructure (server/network environment)
    is unreliable (which should be a rare case).
    :param scenario:        Scenario or ScenarioOutline to patch.
    :param max_attempts:    How many times the scenario can be run.
    """
    def scenario_run_with_retries(scenario_run, *args, **kwargs):
        for attempt in range(1, max_attempts+1):
            if not scenario_run(*args, **kwargs):
                if attempt > 1:
                    message = u"AUTO-RETRY SCENARIO PASSED (after {0} attempts)"
                    print(message.format(attempt))
                return False    # -- NOT-FAILED = PASSED
            # -- SCENARIO FAILED:
            if attempt < max_attempts:
                print(u"AUTO-RETRY SCENARIO (attempt {0})".format(attempt))
        message = u"AUTO-RETRY SCENARIO FAILED (after {0} attempts)"
        print(message.format(max_attempts))
        return True

    if isinstance(scenario, ScenarioOutline):
        scenario_outline = scenario
        for scenario in scenario_outline.scenarios:
            scenario_run = scenario.run
            scenario.run = functools.partial(scenario_run_with_retries, scenario_run)
    else:
        scenario_run = scenario.run
        scenario.run = functools.partial(scenario_run_with_retries, scenario_run)

参考:https://github.com/behave/behave/blob/master/behave/contrib/scenario_autoretry.py

答案 2 :(得分:-1)

如果您尝试使用小黄瓜作为脚本工具,那么您将度过一段美好时光。有更好的工具,如python本身或机器人框架。问问自己,您对小黄瓜测试的期望是什么。你的小黄瓜应该回答'你为什么'做某事,它应该有足够的例子来解释不同的情况 - 最好只有有趣的情况。

答案 3 :(得分:-1)

每次测试时都需要添加动态行。它永远不会显示在要素文件中,但需要添加行。

以下链接的功能很少,可以在步骤定义中为您创建动态行

http://www.programcreek.com/java-api-examples/index.php?api=gherkin.formatter.model.DataTableRow

或从步骤定义中调用步骤定义

http://www.specflow.org/documentation/Calling-Steps-from-Step-Definitions/

答案 4 :(得分:-1)

希望我理解你的问题:)

这个怎么样:

更改步骤:“当我将速度设置为速度”到

当我将速度设置为{speed}时,它需要参数。

在你的功能中:当我测试速度500次时 在那一步:当我测试速度500次时:

==&gt;创建500次for循环:

=====&gt;选择随机速度

=====&gt;执行context.execute_steps和格式化(速度)

的其他步骤

你需要解决这个问题,因为它需要unicodes,而不是整数。

==&GT;然而,有人可能同意Szabo Peter认为使用gherkin / python-behave这有点尴尬:)。这有点弄乱了目的。而且,即使按照我的想法,也可以更优雅地完成。

你可以在这里找到一些不错的东西:https://jenisys.github.io/behave.example/tutorials/tutorial08.html Cheerz

所以在评论之后进行编辑:(在编辑和编写这个例子后,它看起来更加愚蠢,然后我认为它会,所以是的:不要使用表现的行为。 示例:

功能:测试功能  场景:测试场景    鉴于我打开了应用程序    当我以随机速度测试应用程序500次时    然后控制台说完成了

步骤进行:

@given(你打开应用程序')

=&gt; def I_open_the_app(context):

==&gt; #code打开应用

@when(你以随机速度测试app 500次)

=&gt; def I_test_the_app_500_times_at_random_speed(context):

==&gt;范围内的次数(1,500):

===&gt; random_speed = random.randint(min_speed,max_speed)

===&gt; context.execute_steps(当我以{speed}'''播放时你是'。'格式(speed = str(random_speed))

@when(你在{speed}'玩)

=&gt; def I_play_at(上下文,速度)

==&GT; play_at_speed(INT(速度))

@then(你说控制台说完了')

=&gt; def the_console_says_it_is_done ==&gt;打印('完成')