Protractor - Protractor样式指南
在本章中,让我们详细了解Protractor的样式指南。
介绍
该风格指南由两位软件工程师创建,分别是ING 前端工程师Carmen Popoviciu和Google 软件工程师Andres Dominguez 。因此,这个风格指南也被称为 Carmen Popoviciu 和 Google Protractor风格指南。
本风格指南可分为以下五个要点 -
- 通用规则
- 项目结构
- 定位策略
- 页面对象
- 测试套件
通用规则
以下是使用Protractor进行测试时必须注意的一些通用规则 -
不要对已经进行过单元测试的内容进行端到端测试
这是卡门和安德烈斯给出的第一个通用规则。他们建议我们不要对已经经过单元测试的代码进行端到端测试。其背后的主要原因是单元测试比 e2e 测试快得多。另一个原因是我们必须避免重复测试(不要同时执行单元测试和端到端测试)以节省时间。
仅使用一个配置文件
建议的另一要点是我们必须只使用一个配置文件。不要为您正在测试的每个环境创建配置文件。您可以使用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(),即我们不应该在页面对象中进行任何断言,因为所有断言都必须在测试用例中完成。
另一个原因是测试的读者应该能够仅通过阅读测试用例来理解应用程序的Behave。