Cucumber + Selenium自动化测试的优秀实践
在开发实现之前,测试首先就被记录下来。
对于不了解功能的用户都很容易理解测试。
它有效地结合了自动化测试,是一个可以执行的、有关需求的活文档。
feature文件:作为Cucumber测试的入口点。它是用Gherkin语言编写测试方案的文件。一个feature(特性)文件可以包含单个或多个测试方案。feature文件被用作实时文件,以.feature扩展名结尾。
Step Definition:包含一段代码,用你熟悉的编程语言,并附有一些注释。在看到Gherkin步骤时,Cucumber会执行包含在该步骤中的代码。注释有一个模式,将Step Definition与.feature文件中定义的匹配步骤联系起来。
其他 - 我们可能需要其他文件来执行不同级别的测试。例如,我们正在测试Web UI;那么,我们将使用像Selenium这样的工具,它可能使用自己的框架,如Page Object Model。本文的主要重点是Cucumber的优秀实践,不详细讨论这些内容。
我们首先在项目目录下创建一个文件,该文件将由模仿某种功能的步骤组成。本文只关注如何编写feature文件来模拟测试场景,并在后面介绍具体的实现。作为一个例子,让我们用Gherkin来实现“登录”功能。
在项目文件夹中创建一个扩展名为.feature的文件,如将其命名为 "Login.feature"。
该文件中将给出一个描述该功能的标题,在这个例子中,它可以是 "Feature: Login Action"。
开始在feature文件中编写测试方案。在feature文件中编写场景的一般语法是
Feature: Login Action(登录动作)
Scenario: 作为一个现有的用户,我希望能成功登录。
建议.feature文件独立于其他功能,这意味着尽量使每个.feature文件对应一个单一的功能。
可以通过使用与需求相同的语言来使.feature文件易于理解,也就是说,总是试图按照用户所做的动作来描述它们。
Given- 定义了测试的前提条件。
When- 定义了将被执行的用户动作。
Then- 定义后置条件或测试的结果。
But- 用来向测试添加负面条件。
And- 用于添加条件到测试中。
始终记住:语句的顺序必须遵循 "Given-When-Then"。因为 "Given "意味着一个前置条件,"When"指的是一个行动,"Then"指的是行动的后置条件,所以将 "Then"写在 "When"之前会很不清楚。
请永远记住,"Given-When-Then"在每个场景中只应出现一次。你可以通过使用'And'来扩展任何句子。这是因为每个场景只描述一个单独的行为。如果我们将包括多个Then-When,那么作为一个单一的行为就没有意义了。
确保句子在谈及视角时是一致的。这意味着,如果场景描述是以第一人称描述的,那么句子也应该以第一人称来保持同质性。
尽量将场景中的步骤写到最少,这有助于使场景变得可理解和清晰。
试着写一些具有解释作用的简短句子。
尽量使场景独立。如果它们是相互联系的,可能会产生错误,例如,在平行测试执行的情况下。
当使用实时应用程序进行测试时,你可能需要创建多个.feature文件。在不同的文件中对feature进行分解变得很关键。组织好文件,使所有与特定功能有关的feature被归入一个包或一个目录。这是为无缝BDD实施推荐的另一个基本Cucumber最佳实践之一。
例如,考虑一个电子商务应用,可以这样组织文件,在第一层可以有一个package,例如Orders,在这个package中可以有多个feature,如Pending Orders、Completed Orders、Wishlist等等。这样做将使项目有条不紊,而且你将很容易根据功能定位测试。
有时,你应该用什么角度来写测试方案:第一人称还是第三人称?这一点变得非常令人困惑。Cucumber BDD框架的官方文档同时使用了两种视角。以下是这两种观点的论据。
第一人称:BDD是由Dan North创建的,他在《BDD介绍》一文中建议使用第一人称。使用第一人称是合理的,因为它描述了将自己置于实际执行行动的人的位置。
第三人称:喜欢第三人称观点的人指出,使用第一人称会使读者感到困惑。它没有澄清谁在执行这个行动,即一个个人用户、一个管理员或一些具有特定角色的用户。有人认为,第三人称的使用正确显示了信息,并最大限度地减少了对实际参与执行/测试场景的人做出任何错误假设的风险。
除了上面讨论的常用关键词,还有一些在Gherkin中使用的关键词。如果你想实施Cucumber的最佳实践,这是一个重要的初步实践。
Background简化了在一个给定功能中向多个场景添加相同步骤的工作。这意味着,如果一个功能中的所有场景都要执行一些共同的步骤,可以把它们写在Background关键字下。
打开网站
点击 "登录 "链接
输入用户名和密码
点击 "提交 "按钮
Scenario Outline类似于对应于测试场景的测试数据。并不强制要求用Scenario Outline来写场景,但如果需要,可以写。
示例:
如果一个场景中的信息不适合在一行中出现,可以使用DocStrings。它跟在一个步骤后面,并被括在三个双引号内。虽然经常被忽视,但它是最关键的Cucumber最佳实践之一,需要遵循。
数据表的作用是在单一步骤中输入数据。 没有必要定义数据表的头部,但建议保持对数据的参考,以方便理解。
Cucumber并不局限于用英语编写方案。与英语中遵循的惯例类似,可以用多种人类语言来编写方案。Cucumber官方文档中有关于使用语言功能和各种语言的方言代码的所有信息。
例如,要使用法语作为编写方案的语言,可以在功能中使用#Languages 作为标题,就像下面这样------。
# language : fr
(注意:fr是法语的方言代码)
在某些情况下,可能不需要执行测试的所有场景。在这种情况下,可以通过使用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标签下的方案将被忽略。
到目前为止,作为Cucumber最佳实践的一部分,我们只了解了场景会做什么。但是,使用Cucumber Selenium实现自动化的下一个重要步骤是添加 "Step Definition",它将完成 "如何 "部分,即场景如何执行。当Cucumber在Scenario中运行一个步骤时,它会引用一个匹配的Step Definition来执行。
步骤的实现可以用Ruby、C++、Javascript或任何其他语言来完成,但这里的例子将使用Java。
如果你使用的IDE已经安装了Gherkin和Cucumber,你会看到建议创建一个新的.java文件或者选择一个已经实现了步骤的文件。在选择任何一个选项时,将在类中创建一个方法。例如,我们正在恢复以下步骤的定义:
Given the user is on Home Page
尝试创建可重复使用的Step Definition。
可复用的Step Definition将使测试具有可维护性,如果将来有任何变化,对框架做的改动最小。
可以在Scenario Outline中使用Parameterization 来重复使用Step Definition。
你现在已经熟悉了一些最重要的Cucumber最佳实践,可以在BDD策略中或在实施Cucumber和Selenium时遵循。作为最后的总结,我们建议:
尝试在feature文件中以用户描述的方式编写场景。这将有助于创建简洁明了的步骤。
避免耦合的步骤,也就是说,总是倾向于在每个步骤中创建一个动作,避免不必要的错误。
尽可能地重复使用Step Definition,以提高代码的可维护性。
尽量利用 "Background"来减少在不同场景中不必要地增加相同的步骤。