Protractor - Protractor 样式指南
在本章中,我们将详细了解 Protractor 样式指南。
简介
该样式指南由两位软件工程师创建,分别是 ING 的前端工程师 Carmen Popoviciu 和 Google 的软件工程师 Andres Dominguez。因此,该风格指南也被称为 Carmen Popoviciu 和 Google 的 Protractor 风格指南。
该风格指南可分为以下五个要点 −
- 通用规则
- 项目结构
- 定位器策略
- 页面对象
- 测试套件
通用规则
以下是使用 Protractor 进行测试时必须注意的一些通用规则 −
不要对已经进行过单元测试的代码进行端到端测试
这是 Carmen 和 Andres 给出的第一条通用规则。他们建议我们不能对已经进行过单元测试的代码执行端到端测试。其背后的主要原因是单元测试比端到端测试快得多。另一个原因是我们必须避免重复测试(不要同时执行单元测试和端到端测试)以节省时间。
仅使用一个配置文件
建议的另一个重要点是我们必须只使用一个配置文件。不要为您正在测试的每个环境创建配置文件。您可以使用grunt-protractor-coverage来设置不同的环境。
避免在测试中使用逻辑
我们必须避免在测试用例中使用 IF 语句或 FOR 循环,因为如果这样做,测试可能会在不测试任何内容的情况下通过,或者运行速度可能非常慢。
使测试在文件级别独立
启用共享后,Protractor 可以并行运行测试。然后,当这些文件可用时,它们会在不同的浏览器上执行。 Carmen 和 Andres 建议至少在文件级别使测试独立,因为 Protractor 运行测试的顺序不确定,而且单独运行测试也相当容易。
项目结构
关于 Protractor 样式指南的另一个重要关键点是项目的结构。以下是关于项目结构的建议 −
在合理的结构中摸索 e2e 测试
Carmen 和 Andres 建议我们必须将 e2e 测试分组为符合项目结构的结构。此建议背后的原因是,这样可以更轻松地查找文件,并且文件夹结构更易读。此步骤还将 e2e 测试与单元测试分开。他们建议应避免以下类型的结构 −
|-- project-folder |-- app |-- css |-- img |-- partials home.html profile.html contacts.html |-- js |-- controllers |-- directives |-- services app.js ... index.html |-- test |-- unit |-- e2e home-page.js home-spec.js profile-page.js profile-spec.js contacts-page.js contacts-spec.js
另一方面,他们推荐以下类型的结构 −
|-- project-folder |-- app |-- css |-- img |-- partials home.html profile.html contacts.html |-- js |-- controllers |-- directives |-- services app.js ... index.html |-- test |-- unit |-- e2e |-- page-objects home-page.js profile-page.js contacts-page.js home-spec.js profile-spec.js contacts-spec.js
定位器策略
以下是使用 Protractor 进行测试时必须注意的一些定位器策略 −
切勿使用 XPATH
这是 Protractor 样式指南中推荐的第一个定位器策略。其背后的原因是 XPath 需要大量维护,因为标记很容易发生变化。此外,XPath 表达式最慢且很难调试。
始终首选 Protractor 特定的定位器,例如 by.model 和 by.binding
Protractor 特定的定位器,例如 by.model 和 by.binding 简短、具体且易于阅读。借助它们,编写我们的定位器也非常容易。
示例
查看
<ul class = "red"> <li>{{color.name}}</li> <li>{{color.shade}}</li> <li>{{color.code}}</li> </ul> <div class = "details"> <div class = "personal"> <input ng-model = "person.name"> </div> </div>
对于上述代码,建议避免使用以下 −
var nameElement = element.all(by.css('.red li')).get(0); var personName = element(by.css('.details .personal input'));
另一方面,建议使用以下代码 −
var nameElement = element.all(by.css('.red li')).get(0); var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name')); var personName = element(by.model('person.name'));
当没有可用的 Protractor 定位器时,建议优先使用 by.id 和 by.css。
始终避免使用文本定位器来定位频繁更改的文本
我们必须避免使用基于文本的定位器,例如 by.linkText、by.buttonText 和 by.cssContaningText,因为按钮、链接和标签的文本会随时间频繁更改。
页面对象
如前所述,页面对象封装了有关应用程序页面上元素的信息,因此有助于我们编写更清晰的测试用例。页面对象的一个非常有用的优势是它们可以在多个测试中重复使用,并且如果我们的应用程序模板已更改,我们只需更新页面对象即可。以下是在使用 Protractor 进行测试时必须注意的页面对象建议 −
要与被测页面交互,请使用页面对象
建议使用页面对象与被测页面交互,因为它们可以封装被测页面上元素的信息,并且还可以重复使用。
始终在每个文件中声明一个页面对象
我们应该在自己的文件中定义每个页面对象,因为这样可以保持代码整洁,查找内容也变得容易。
在页面对象文件的末尾始终使用单个 module.exports
建议每个页面对象都声明一个类,这样我们只需要导出一个类。例如,应避免以下对象文件的使用 −
var UserProfilePage = function() {}; var UserSettingsPage = function() {}; module.exports = UserPropertiesPage; module.exports = UserSettingsPage;
但另一方面,建议使用以下 −
/** @constructor */ var UserPropertiesPage = function() {}; module.exports = UserPropertiesPage;
在顶部声明所有必需的模块
我们应该在页面对象的顶部声明所有必需的模块,因为这样可以使模块依赖关系清晰且易于查找。
在测试套件的开头实例化所有页面对象
建议在测试套件的开头实例化所有页面对象,因为这会将依赖关系与测试代码分开,并使依赖关系可用于套件的所有规范。
不要在页面对象中使用 expect()
我们不应该在页面对象中使用 expect(),即我们不应该在页面对象中做出任何断言,因为所有断言都必须在测试用例中完成。
另一个原因是测试的读者应该能够仅通过阅读测试用例来了解应用程序的行为。