【问题标题】:Cucumber load data tables dynamicallyCucumber 动态加载数据表
【发布时间】:2012-01-16 09:30:27
【问题描述】:

我目前正在尝试将 cucumber 和 capybara 一起用于 web-app 的一些集成测试。

有一个测试,我只想点击 Web 应用程序的所有(或大部分)页面,看看是否没有返回错误。我希望之后能够查看哪些页面无法正常工作。

我认为场景大纲是最好的方法,所以我就这样开始了:

Scenario Outline: Checking all pages pages

   When I go on the page <page>
   Then the page has no HTTP error response

    Examples:
      | page                        |
      | "/resource1"                |
      | "/resource2"                |
      ...

我目前有 82 页,效果很好。

但是我发现这种方法不可维护,因为可能会有新资源和将被删除的资源。

更好的方法是从某处加载表中的数据(解析索引页面的 HTML、数据库等...)。

但我不知道该怎么做。

我遇到了article about table transformation,但我不知道如何在场景大纲中使用此转换。

有什么建议吗?

好的,因为有些混乱。如果你看看上面的例子。我要做的就是改变它,使表格几乎是空的:

Scenario Outline: Checking all pages pages

  When I go on the page <page>
  Then the page has no HTTP error response

  Examples:
    | page                        |
    | "will be generated"         |

然后我想添加一个看起来像这样的转换:

Transform /^table:page$/ do
  all_my_pages.each do |page|
    table.hashes << {:page => page}
  end 
  table.hashes
end

我在同一个文件中指定了转换,但它没有被执行,所以我假设转换不适用于场景大纲。

【问题讨论】:

  • 是的,Transform 只对步骤参数表而不是大纲表进行操作。

标签: ruby cucumber integration-testing


【解决方案1】:

Cucumber 对于该任务来说确实是错误的工具,您应该根据特性来描述功能。如果你想以编程方式描述行为,你应该使用 rspec 或 test-unit 之类的东西。

此外,您的场景步骤应该像书面文本那样具有描述性和专业性,而不是像在编程语言中使用的抽象短语。它们不应包含“附带的详细信息”,例如资源的确切 url 或其 ID。

请阅读http://blog.carbonfive.com/2011/11/07/modern-cucumber-and-rails-no-more-training-wheels/并观看http://skillsmatter.com/podcast/home/refuctoring-your-cukes

关于您关于“插入表格”的问题,是的,如果您 意味着向它添加额外的行,事实上你可以用它做任何你喜欢的事情。 Transform 块的结果完全替换了原表。

Transform /^table:Name,Posts$/ do
  # transform the table into a list of hashes
  results = table.hashes.map do |row|
    user = User.create! :name => row["Name"]
    posts = (1..row["Posts"]).map { |i| Post.create! :title => "Nr #{i}" }
    { :user => user, :posts => posts }
  end
  # append another hash to the results (e.g. a User "Tim" with 2 Posts)
  tim = User.create! :name => "Tim"
  tims_posts = [Post.create! :title => "First", Post.create! :title => "Second"]
  results << { :user => tim, :posts => tims_posts }
  results
end

Given /^I have Posts of the following Users:$/ do |transformation_results|
  transformation_results.each do |row|
    # assing Posts to the corresponding User
    row[:user].posts = row[:posts]
  end
end

您可以将它与这样的场景大纲结合起来:

Scenario Outline: Paginate the post list of an user at 10
  Given I have Posts of the following Users:
    | Name | Posts |
    | Max  | 7     |
    | Tom  | 11    |
  When I visit the post list of <name>
  Then I should see <count> posts
Examples:
  | name | count |
  | Max  |     7 |
  | Tom  |    10 |
  | Tim  |     2 |

这应该说明为什么向表中“添加”行可能不是最佳做法。

请注意,无法在表格内扩展示例标签:

Scenario Outline: Paginate the post list of an user at 10
  Given I have Posts of the following Users:
    | Name   | Posts      |
    | <name> | <existing> | # won't work
  When I visit the post list of <name>
  Then I should see <displayed> posts
Examples:
  | name | existing | displayed |
  | Max  |     7    |         7 |
  | Tom  |    11    |        10 |
  | Tim  |     2    |         2 |

【讨论】:

  • 使用我提供的示例,即使一条路径失败,测试也会继续。之后我可以看到测试失败的参数。所以我的代码看起来不像那样。我现在唯一需要的是生成表格的转换。
  • 请详细说明“生成表的位置”。你想生成小黄瓜源代码吗?或者您想在接受表格的步骤中使用大纲标签(如 )?第一个不应该做,第二个是不可能的。
  • 我喜欢做的与那个例子类似(在我的情况下,将数据添加到表中,或者无法插入?):claytonlz.com/index.php/2010/01/cucumber-table-transformations 但我想在场景大纲中使用它。
  • 仍然不完全确定你想做什么。如果我编辑的答案对您没有帮助,请在您的问题中包含一个示例场景。只需编写您希望如何指定您的行为的场景。不要将其视为一系列说明,而是将其视为书面文本,例如向孩子解释行为。
  • 添加了评论,希望对您有所帮助
【解决方案2】:

对于动态加载数据的具体情况,给个建议:

  1. 一个类,比如说PageSets,带有方法,例如all_pages_in_the_sitemap_errorcountdeveloping_countries_errorcount

  2. 一个类似于

    的步骤
    Given I am on the "Check Stuff" page
    Then there are 0 errors in the "developing countries" pages
    

    Then there are 0 errors in "all pages in the sitemap"

Then 步骤将字符串"developing countries" 转换为方法名称developing_countries_errorcount 并尝试在类PageSets 上调用它。在这种情况下,该步骤要求所有 _errorcount 方法返回一个整数。返回地图之类的数据结构为您编写简洁的动态步骤提供了许多可能性。

对于更多静态数据,我们发现 YAML 非常有用,可以让我们的测试自我记录和自我验证,并帮助我们删除难以维护的文字,例如“5382739”,我们都忘记了三个的含义几周后。

YAML 格式易于阅读,必要时可以进行注释(通常不需要。)

而不是写:

Given I am logged in as "jackrobinson@gmail.com"
And I select the "History" tab
Then I can see 5 or more "rows of history"

我们可以改为:

Given I am logged in as "a user with at least 5 items of history"
When I select the "History" tab
Then I can see 5 or more "rows of history"

在文件 logins.yaml....

a member with at least 5 items of history:
     username: jackrobinson@gmail.com
     password: WalRus

我们使用 YAML 来保存与各种实体(如成员、提供者、策略等)相关的数据集......该列表一直在增长:

在文件 test_data.yaml...

a member who has direct debit set up:
    username: jackrobinson@gmail.com
    password: WalRus
    policyId: 5382739
    first name: Jack
    last name: Robinson
    partner's first name: Sally
    partner's last name: Fredericks

如果您需要验证文本,也值得查看 YAML 的 multi-line text facilities。虽然这对于自动化测试来说并不常见,但它有时会很有用。

【讨论】:

    【解决方案3】:

    我认为更好的方法是使用不同的工具,仅用于抓取您的网站并检查是否没有返回错误。假设你正在使用 Rails

    您可以考虑的工具是:Tarantula

    https://github.com/relevance/tarantula

    希望对你有帮助:)

    【讨论】:

    • 感谢您的建议,但是我不能使用 Tarantula 有几个原因(集成测试与应用程序分开,应用程序不是 Rails3 应用程序)。除此之外,在我不想只抓取网站的其他场景中,生成数据表可能很有用。
    【解决方案4】:

    一个快速的技巧是更改示例收集器代码,并使用 ruby​​ 的 eval 运行您自定义的 ruby​​ 函数以覆盖默认收集的示例数据,代码如下: generate-dynamic-examples-for-cucumber

    缺点:需要修改scenario_outline.rb文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      相关资源
      最近更新 更多