5

我正在尝试用黄瓜进行浏览器测试,并且是第一次学习 BDD 测试——所以我是 BDD 的初学者。我遇到了一个问题,想知道解决它的最佳实践方法。

(我将它用于 node.js webapp,所以它是 cucumber.js 和 selenium WebDriverJS,但平台对于这个问题应该无关紧要)

描述:

在 Gherkin 语法的教程中,您经常会看到单击特定页面上的按钮的示例,例如:

Given (something)
When I click the submit button
Then (something)

为这一步实现步骤定义非常简单——只需让 selenium 使用任何与按钮匹配的 css-selector 来定位元素,然后让 selenium 点击它。

问题:

但是,如果您在不同的页面上有不同的按钮具有相同的“人类可读”名称(即黄瓜步骤文本中的相同名称),但必须由不同的 css 选择器定位,该怎么办?

似乎您不能拥有特征本地的步骤定义,但所有步骤定义都在所有特征之间共享。这意味着如果您创建一个步骤“我单击提交按钮”,如上所述,步骤定义必须适用于测试整个 webapp 中具有提交按钮的所有页面。我不确定这样做的正确方法是什么。

问题:

处理此问题的最佳做法是什么?


问题示例:

假设我们有 3 个页面,它们都有一个“下一步”按钮,它在每个页面上执行的操作完全不同,并且在 DOM 中的位置也完全不同。假设每个页面都有一个功能。在每个功能中,涉及“下一步”按钮的场景如下所示:

Given I am on page xyz
And ...
And I click the next button
And ...
When ...
Then ...

问题在于,在第一页上,“下一个”按钮可能位于“.next-button”,在第二页上可能是“#someContainer .btn.btn-primary”,而在第三页上则是“#assetButtons” li:nth-child(3)”。如果我们对每个特性都有一个本地的步骤定义,它们可以简单地看起来像:

this.Given(/^I click the next button$/, function(callback) {
    this.driver.findElement(this.webdriver.By.css(”.next-button”).click();
    callback();
});

this.Given(/^I click the next button$/, function(callback) {
    this.driver.findElement(this.webdriver.By.css(”#someContainer .btn.btn-primary”).click();
    callback();
});

this.Given(/^I click the next button$/, function(callback) {
    this.driver.findElement(this.webdriver.By.css(”#assetButtons li:nth-child(3)”).click();
    callback();
});

但是由于步骤定义对所有功能都是全局的,并且您自然不能为同一个正则表达式创建两个步骤定义,因此“我单击下一步按钮”的步骤定义需要知道我们在哪个页面或哪个页面场景所指的“下一步”按钮。


我自己的一些想法: 可选阅读

  • 可以使步骤名称不那么通用,并使它们还引用按钮所在的页面:“我单击首页上的下一步按钮”。这样做的问题是我们已经在我们在那个页面上的场景中写了,所以它是多余的。
  • 可以为不同页面上的“下一个”按钮组成不同的名称——例如“首页下一个”和“搜索页面下一个”。
  • 可以使步骤定义检测您当前所在的页面,并根据页面使用不同的 css 选择器。(例如,它可以查询 selenium 以获取当前 URL,并根据步骤中的按钮名称和当前页面查找要使用的 css 选择器)。
  • 可以在步骤文本本身中包含 css 选择器。但这不是人类可读的,而且看起来不像 BDD 方式。
  • 选择更高的抽象级别,在这里你不谈论按钮等,而是更高级别的操作,例如“我转到搜索结果中的下一页”。(总的来说,这似乎不是一个好方法——通常确切的步骤很重要,因为相同的操作通常可以以不同的方式完成,所有这些路径当然应该由测试来执行。例如,如果你可以也可以通过按“N”或滑动进入下一页,这只会测试其中一种情况(但当然也可以将其包含在步骤文本中)。)

但是正确的方法是什么?

4

2 回答 2

6

说你“点击提交按钮”是坏黄瓜。你想写陈述句来说明你在做什么,而不是你是怎么做的。不应在您的测试设计中找到诸如“单击此按钮”之类的命令句。我理解您指出能够以多种方式做事,在这种情况下,这是一个重要的细节,但要尽可能抽象。

你说你有三个下一步按钮可以做三件完全不同的事情,在你的小黄瓜中说明这些动作

When I advance the image carousel
When I go to the next news page
When I view the next page of search results

至于不同的路...

When I swipe to view the next page of search results
When I use the keyboard to view the next page of search results
When I click on the next link to view the next page of search results

现在我们可以把它变成一个 stepdef,其中包含三个不同的动作。

Cucumber 和 gherkin 的重点不是让你的场景变干,而是让它成为人类可读的、非程序员类型可以理解的,以及一种活文档。如果你有更多的话那不会是世界末日()

于 2015-10-05T04:27:22.443 回答
1

“陈述句”实际上并不是解决这个问题的正确方法。有时我们确实想测试特定的按钮、文本、单选按钮等。因为它们是用户体验的一部分,甚至是用户接受标准的一部分。

例如,假设有一天客户告诉您功能很好。但是,他们希望更改某些 Web 元素的措辞和/或操作它们的顺序。你如何测试它们?你必须处理细节。

实际上,我们在 Cucumber 的不同抽象级别上进行测试是正常和典型的。一些正在针对功能进行测试,而另一些正在针对详细的 UI/UX 进行测试。

Cucumber 的创建者声称我不同意“BDD Tool Cucumber 不是测试工具”。如果 Cucumber 不用于测试,那么根本就没有人会使用它。市场上有很多好的/更好的文档/通信工具。

回到问题,我认为你的第三个选项是正确的

可以使步骤定义检测您当前所在的页面,并根据页面使用不同的 css 选择器。(例如,它可以查询 selenium 以获取当前 URL,并根据步骤中的按钮名称和当前页面查找要使用的 css 选择器)。

您不需要检测当前所在的页面,因为您已经在上一步中指出了它

鉴于我在页面 xyz

您只需要在文本上下文中维护当前页面。

于 2019-03-21T21:09:48.157 回答