查看原文
其他

Cucumber + Selenium自动化测试的优秀实践

Harshit Paul 软件质量报道 2022-03-17
众所周知,Cucumber是一个非常不错的、面向BDD的测试工具,使用Gherkin的纯文本功能描述来运行验收测试使用Cucumber BDD框架的最大收益是:
  • 在开发实现之前,测试首先就被记录下来。

  • 对于不了解功能的用户都很容易理解测试。

  • 它有效地结合了自动化测试,是一个可以执行的、有关需求的活文档。

是不是迫不及待地想开始使用Cucumber?为了帮助你,在此深入介绍一些Cucumber+Selenium自动化测试的优秀实践。通过这些实践,也会让你对行为驱动开发(BDD)有一个更清晰的认知。

1. Cucumber BDD框架的基础知识
在介绍Cucumber优秀实践之前,我们先了解一些关于Cucumber BDD框架的事情。使用Cucumber进行Selenium自动化测试,需要三种类型的文件:
  1. feature文件:作为Cucumber测试的入口点。它是用Gherkin语言编写测试方案的文件。一个feature(特性)文件可以包含单个或多个测试方案。feature文件被用作实时文件,以.feature扩展名结尾。

  2. Step Definition:包含一段代码,用你熟悉的编程语言,并附有一些注释。在看到Gherkin步骤时,Cucumber会执行包含在该步骤中的代码。注释有一个模式,将Step Definition与.feature文件中定义的匹配步骤联系起来。

  3. 其他 - 我们可能需要其他文件来执行不同级别的测试。例如,我们正在测试Web UI;那么,我们将使用像Selenium这样的工具,它可能使用自己的框架,如Page Object Model。本文的主要重点是Cucumber的优秀实践,不详细讨论这些内容。


后面我们将详细了解前两类文件,以及如何有效地使用它们。这些都是成功使用Cucumber和Selenium的一些基本实践,我们必须掌握它们。如前所述,我们将使用Gherkin来编写Cucumber BDD框架中的场景。现在让我们开始Cucumber实践之旅。

2. 创建一个feature文件

我们首先在项目目录下创建一个文件,该文件将由模仿某种功能的步骤组成。本文只关注如何编写feature文件来模拟测试场景,并在后面介绍具体的实现。作为一个例子,让我们用Gherkin来实现“登录”功能。


用例(Use Case):对使用有效证书登录应用程序的行为进行建模。
  1. 在项目文件夹中创建一个扩展名为.feature的文件,如将其命名为 "Login.feature"。

  2. 该文件中将给出一个描述该功能的标题,在这个例子中,它可以是 "Feature: Login Action"。

  3. 开始在feature文件中编写测试方案。在feature文件中编写场景的一般语法是


Feature: Login Action(登录动作

Scenario: 作为一个现有的用户,我希望能成功登录。

在这一点上,需要注意下面列出的要点:
  • 建议.feature文件独立于其他功能,这意味着尽量使每个.feature文件对应一个单一的功能。

  • 可以通过使用与需求相同的语言来使.feature文件易于理解,也就是说,总是试图按照用户所做的动作来描述它们。

接下来,在.feature文件中写下场景Scenario(场景)描述功能的不同的上下文。在测试设计中,我们可能需要写多个场景来覆盖测试范围。为了写一个场景,我们使用Gherkin定义的关键词。Gherkin句子中使用的主要关键字有:
  • Given- 定义了测试的前提条件。

  • When- 定义了将被执行的用户动作。

  • Then- 定义后置条件或测试的结果。

  • But- 用来向测试添加负面条件。

  • And- 用于添加条件到测试中。

注意:只需要在.feature文件中说明你想做什么,而不是你想怎么做。如何做的部分将在步骤定义文件中处理(见本文之后叙述)。

以下是在Cucumber中描述场景时需要记住的几点:
  • 始终记住:语句的顺序必须遵循 "Given-When-Then"。因为 "Given "意味着一个前置条件,"When"指的是一个行动,"Then"指的是行动的后置条件,所以将 "Then"写在 "When"之前会很不清楚。

  • 请永远记住,"Given-When-Then"在每个场景中只应出现一次。你可以通过使用'And'来扩展任何句子。这是因为每个场景只描述一个单独的行为。如果我们将包括多个Then-When,那么作为一个单一的行为就没有意义了。

  • 确保句子在谈及视角时是一致的。这意味着,如果场景描述是以第一人称描述的,那么句子也应该以第一人称来保持同质性。

  • 尽量将场景中的步骤写到最少,这有助于使场景变得可理解和清晰。

  • 试着写一些具有解释作用的简短句子。

  • 尽量使场景独立。如果它们是相互联系的,可能会产生错误,例如,在平行测试执行的情况下。


3. 分离特征文件

当使用实时应用程序进行测试时,你可能需要创建多个.feature文件。在不同的文件中对feature进行分解变得很关键。组织好文件,使所有与特定功能有关的feature被归入一个包或一个目录。这是为无缝BDD实施推荐的另一个基本Cucumber最佳实践之一。

例如,考虑一个电子商务应用,可以这样组织文件,在第一层可以有一个package,例如Orders,在这个package中可以有多个feature,如Pending Orders、Completed Orders、Wishlist等等。这样做将使项目有条不紊,而且你将很容易根据功能定位测试。


4. 使用正确的视角

有时,你应该用什么角度来写测试方案:第一人称还是第三人称?这一点变得非常令人困惑。Cucumber BDD框架的官方文档同时使用了两种视角。以下是这两种观点的论据。

  • 第一人称BDD是由Dan North创建的,他在《BDD介绍》一文中建议使用第一人称。使用第一人称是合理的,因为它描述了将自己置于实际执行行动的人的位置。

  • 第三人称喜欢第三人称观点的人指出,使用第一人称会使读者感到困惑。它没有澄清谁在执行这个行动,即一个个人用户、一个管理员或一些具有特定角色的用户。有人认为,第三人称的使用正确显示了信息,并最大限度地减少了对实际参与执行/测试场景的人做出任何错误假设的风险。

所以,总而言之,没有规定要使用任何一种观点;你必须记住的一个做法是保持一致性。描述应该与测试步骤产生共鸣,并从单一角度出发。

5. Cucumber 中使用的其他关键词

除了上面讨论的常用关键词,还有一些在Gherkin中使用的关键词。如果你想实施Cucumber的最佳实践,这是一个重要的初步实践。


Background

Background简化了在一个给定功能中向多个场景添加相同步骤的工作。这意味着,如果一个功能中的所有场景都要执行一些共同的步骤,可以把它们写在Background关键字下

例如,要从一个电子商务网站订购产品,必须做以下步骤:
  • 打开网站

  • 点击 "登录 "链接

  • 输入用户名和密码

  • 点击 "提交 "按钮

一旦完成上述步骤,我们就可以搜索产品,将该产品添加到购物车,并进行结账和付款。由于上述步骤对于一个功能中的许多功能来说是常见的,我们可以把它们包括在Background中。尽量保持Background的简短,因为如果保持冗长的背景,就很难理解下面的场景。Cucumber特性文件的关键是:越短越好。

Scenario Outline

Scenario Outline类似于对应于测试场景的测试数据。并不强制要求用Scenario Outline来写场景,但如果需要,可以写。

示例:

DocStrings

如果一个场景中的信息不适合在一行中出现,可以使用DocStrings。它跟在一个步骤后面,并被括在三个双引号内。虽然经常被忽视,但它是最关键的Cucumber最佳实践之一,需要遵循。


Data Table
Data Table与Scenario Outline相当相似。两者之间的主要区别是,Scenario Outline在场景层面注入数据,而数据表用于在步骤层面注入数据。
  • 数据表的作用是在单一步骤中输入数据。
  • 没有必要定义数据表的头部,但建议保持对数据的参考,以方便理解。
如上面的例子所示,可以在单个步骤中使用数据表,并注入可能需要的不同数据。

Languages

Cucumber并不局限于用英语编写方案。与英语中遵循的惯例类似,可以用多种人类语言来编写方案。Cucumber官方文档中有关于使用语言功能和各种语言的方言代码的所有信息。

例如,要使用法语作为编写方案的语言,可以在功能中使用#Languages 作为标题,就像下面这样------。

# language : fr

(注意:fr是法语的方言代码)


Tags

在某些情况下,可能不需要执行测试的所有场景。在这种情况下,可以通过使用Tags(标签)将特定场景分组并独立执行。Tags是简单的注释,用于分组场景和功能。它们用@Tags,后面是一些值得注意的文字。

示例:

注意,Tags在.feature文件中被所有组件继承,即Scenario Outline、Scenario等。同样地,如果Scenario Outline上有一个Tags,数据实例也会继承该Tags(标签)。

  • tags={"@End2End"} @End2End标签下的所有功能场景将被执行。

  • tags={"@SmokeTest"} @SmokeTest下的所有方案都将被执行。

  • tags={"@SmokeTest , @RegressionTest"} 这种类型的定义表示OR条件,因此,@SmokeTest或@RegressionTest标签下的所有方案都会被执行。

  • tags={"@SmokeTest" , "@RegressionTest"} 在这种定义中,@SmokeTest和@RegressionTest下的所有情景都将被执行。

  • tags={~"@End2End"} @End2End标签下的所有方案都将被忽略。

  • tags={"@SmokeTest , ~@RegressionTest"} @SmokeTest标签下的所有方案将被执行,但@RegressionTest标签下的方案将被忽略。

与上面的例子类似,可以根据要求对标签进行组合,并选择性地执行场景/功能。

6. Step Definition(步骤实现)

到目前为止,作为Cucumber最佳实践的一部分,我们只了解了场景会做什么。但是,使用Cucumber Selenium实现自动化的下一个重要步骤是添加 "Step Definition",它将完成 "如何 "部分,即场景如何执行。当Cucumber在Scenario中运行一个步骤时,它会引用一个匹配的Step Definition来执行。

步骤的实现可以用Ruby、C++、Javascript或任何其他语言来完成,但这里的例子将使用Java。

如果你使用的IDE已经安装了Gherkin和Cucumber,你会看到建议创建一个新的.java文件或者选择一个已经实现了步骤的文件。在选择任何一个选项时,将在类中创建一个方法。例如,我们正在恢复以下步骤的定义:


Given the user is on Home Page

一个方法将被自动生成,其注释的标题文本与步骤描述的标题文本相同。
1
2
3
4
5
6
7
@Given(“^the user ison Home Page$”)
publicvoidhomePage()throwsThrowable{
 
//Java code to check the above description
….
…..
}
为了创建从Data Table或Scenario Outline中获取数据的场景的步骤实现,数据将作为正则表达式包含在注释中,并作为参数传递给方法。
1
2
3
4
5
6
7
8
@When(“^Add the first result on the page with quantity\”([0-9]+)”\$”)
publicvoidaddQuantity(intqty)throwsThrowable{
 
//Java code to pass qty in the qty field
...
 
}
而这就是如何使用Gherkin实现在feature文件中写的步骤。在实现Step Definition时,请务必记住以下几点:
  • 尝试创建可重复使用的Step Definition。

  • 可复用的Step Definition将使测试具有可维护性,如果将来有任何变化,对框架做的改动最小。

  • 可以在Scenario Outline中使用Parameterization 来重复使用Step Definition。


总结

你现在已经熟悉了一些最重要的Cucumber最佳实践,可以在BDD策略中或在实施Cucumber和Selenium时遵循。作为最后的总结,我们建议:

  • 尝试在feature文件中以用户描述的方式编写场景。这将有助于创建简洁明了的步骤。

  • 避免耦合的步骤,也就是说,总是倾向于在每个步骤中创建一个动作,避免不必要的错误。

  • 尽可能地重复使用Step Definition,以提高代码的可维护性。

  • 尽量利用 "Background"来减少在不同场景中不必要地增加相同的步骤。


测试愉快!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存