哈Ha!
我叫Vitaliy Kotov,我做过很多自动化测试,我喜欢它。 我最近参与了一个在TypeScript + Protractor + Jasmine堆栈上从头配置自动化的项目。 对我来说,这个堆栈是新的,我在Internet上搜索了必要的信息。
我设法只用英语找到了最有用,最明智的手册。 我认为俄语也需要这样做。 我只告诉您一些基础知识:为什么要这样的堆栈,需要配置什么以及最简单的测试是什么样的。
我必须马上说,我很少使用NodeJS,npm和一般的服务器端JavaScript(尤其是TypeScript)。 如果您发现某个地方的术语有误,或者我的某些决定可以改进,我将很高兴在经验丰富的专家的评论中了解到这一点。
顺便说一句,我已经有一篇类似的文章:
“我们在几个小时内部署自动化:PHPUnit,Selenium,Composer” 。

挑战赛
首先,让我们弄清楚我们正在解决什么问题。 我们有一个使用AngularJS编写的Web应用程序。 这是一个JavaScript框架,经常基于该框架编写Web项目。
在本文中,我们将不考虑AngularJS项目的利弊。 关于为此类项目编写端到端测试的几句话。
测试自动化的一个相当重要的方面是使用页面元素,这是在定位器的帮助下发生的。 定位器是根据某些规则组成并标识一个或多个UI元素的线。
对于Web,最常用的是CSS和Xpath。 有时,如果页面上有一个具有唯一ID的元素,则可以通过它进行搜索。 但是,在我看来,WebDriver最终仍将此ID转换为CSS定位器,并且已经在使用它。
如果我们看一些AngularJS项目的HTML代码,我们将看到很多经典HTML元素以外的属性:

该代码来自
量角器演示页面。
AngularJS使用所有以ng- *开头的属性来处理UI。 一个相当典型的情况是,除了这些控制属性以外的元素都没有其他元素,这使质量定位器的编译过程变得复杂。
那些做了很多自动化工作的人都知道可以轻松构建定位器的此类UI的价值。 毕竟,这对于大型项目而言很少见。 :)
实际上,对于这样的项目,我们还需要配置测试自动化。 走吧
什么是什么
首先,让我们弄清楚为什么需要堆栈中的每个组件。
量角器是基于WebDriverJS的测试框架。 将由他启动我们的浏览器,使它们打开必要的页面并与必要的元素进行交互。
该框架是专门为AngularJS项目量身定制的。 它提供了其他方法来指定定位器:
element(by.model('first')); element(by.binding('latest')); element(by.repeater('some'));
完整列表可以在
手册页上找到。
这些方法简化了项目中定位器的创建和支持。 但是,您必须了解,在任何情况下“全部”都将转换为css。 事实是,WebDriver中进行交互的W3C协议只能与一组有限的定位器一起使用。 可以在
w3.org上查看此列表。
TypeScript是Microsoft创建的一种编程语言。 TypeScript与JavaScript的不同之处在于其键入变量的能力,对使用完整类的支持以及连接模块的能力。
与V8引擎配合使用的TS代码编写的代码已转换为JS代码,该代码已经在执行。 在此转换过程中,将检查代码是否符合要求。 例如,如果将某个字符串而不是int显式传递给某个地方的函数,则它不会“编译”。
Jasmine是用于测试JavaScript代码的框架。 实际上,多亏了他,我们的JS代码才变成了我们所谓的测试。 他负责管理这些测试。
下面我们看一下它的功能。
组装和项目设置
好吧,我们决定了一套框架,现在让我们把整个事情放在一起。
为了使用该代码,我选择了Microsoft的
Visual Studio Code 。 尽管许多人用
WebStorm甚至是JetBrains的
Intellij Idea编写。
我已经安装了NodeJS(v11.6.0)和NPM(6.9.0)。 如果没有的话,这不是问题;安装它们并不困难。 一切在
官方网站上都有足够详细的描述。
可以使用纱线代替NPM,尽管这对于小型项目而言并不重要。
在我们的IDE中,我们正在创建一个新项目。 我们在项目的根目录中创建package.json-在其中将描述项目所需的所有软件包。
您可以使用
npm init命令创建它。 或者,您可以简单地将内容复制到文件中。
最初,
package.json如下所示:
{ "name": "protractor", "dependencies": { "@types/node": "^10.5.2", "@types/jasmine": "^3.3.12", "protractor": "^5.4.2", "typescript": "^3.4.1" } }
之后,我们执行
npm install命令来安装所有必需的模块及其依赖项(好吧,您还记得有关比黑洞重的东西的图片……)
结果,我们应该有一个node_modules目录。 如果她出现了,那么一切都按计划进行。 如果没有,那么值得研究一下命令执行的结果,通常所有内容都在此处进行了详细描述。
TypeScript及其配置
要安装TypeScript,我们需要npm:
npm install -g typescript
确保已安装:
$ tsc -v Version 3.4.1
一切似乎井井有条。
现在,我们需要创建一个用于使用TS的配置。 它也应该位于项目的根目录,并称为
tsconfig.json。其内容将如下所示:
{ "compilerOptions": { "lib": ["es6"], "strict": true, "outDir" : "output_js", "types" : ["jasmine", "node"] }, "exclude": [ "node_modules/*" ] }
简而言之,我们在此配置中指定了以下内容:
- 将最终的JS代码放在哪个目录中(在本例中为output_js)
- 启用严格模式
- 表明我们正在使用哪些框架
- 编译中排除的node_modules
TS具有多种设置。 这些足以满足我们的项目需求。 您可以
在typescriptlang.org上了解更多信息。
现在让我们看一下
tsc命令的
工作原理 ,它将把我们的TS代码变成JS代码。 为此,请创建一个包含以下内容的简单check_tsc.ts文件:
saySomething("Hello, world!"); function saySomething(message: string) { console.log(message); }
然后执行
tsc命令(为此,您需要在项目目录中)。
我们将看到我们具有output_js目录,并且其中包含以下内容的类似js文件已出现:
"use strict"; saySomething("Hello, world!"); function saySomething(message) { console.log(message); }
该文件已经可以使用node命令启动:
$ node output_js/check_tsc.js Hello, world!
因此,我们编写了第一个TypeScipt程序,恭喜。 现在让我们编写测试。 :)
量角器配置
对于量角器,我们还需要一个配置。 但它不再是json形式,而是ts文件形式。 让我们将其称为config.ts并在其中编写以下代码:
import { Config } from "protractor"; export const config: Config = { seleniumAddress: "http://127.0.0.1:4444/wd/hub", SELENIUM_PROMISE_MANAGER: false, capabilities: { browserName: "chrome", }, specs: [ "Tests/*Test.js", ] };
在此文件中,我们指定了以下内容:
首先,是运行中的Selenium服务器的路径。 运行起来非常简单,您只需
下载Standalone Server jar文件和必要的驱动程序(例如
Chrome浏览器的chrome驱动程序)。 接下来,编写以下命令:
java -jar -Dwebdriver.chrome.driver=/path/to/chromedriver /path/to/selenium-server-standalone.jar
结果,我们应该看到以下结论:
23:52:41.691 INFO [GridLauncherV3.launch] - Selenium build info: version: '3.11.0', revision: 'e59cfb3' 23:52:41.693 INFO [GridLauncherV3$1.launch] - Launching a standalone Selenium Server on port 4444 2019-05-02 23:52:41.860:INFO::main: Logging initialized @555ms to org.seleniumhq.jetty9.util.log.StdErrLog 23:52:42.149 INFO [SeleniumServer.boot] - Welcome to Selenium for Workgroups.... 23:52:42.149 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444
默认端口4444。 可以使用-port参数或通过配置参数“ seleniumArgs” =>“ -port”进行设置。
如果您想要更轻松,更快捷:可以下载npm软件包
webdriver-manager 。
然后使用启动,关闭等命令管理服务器。 并没有太大的区别,只是我更习惯于使用jar文件。 :)
其次 ,我们表示我们不想使用Promise管理器。 稍后再详细介绍。
第三 ,我们为浏览器指定了功能。 例如,我注释了一部分,我们很容易以无头模式启动浏览器。 这是一个很酷的功能,但是它不允许您直观地观察我们的测试。 同时,我们正在学习-我想。 :)
第四 ,我们为规格(测试)指定了一个掩码。 一切都位于Tests文件夹中,并以Test.js结尾。 为什么在js而不是ts上? 这是因为最后,Node将专门用于JS文件,而不适用于TS文件。 重要的是不要混淆,尤其是在工作开始时。
现在创建Tests文件夹并编写第一个测试。 他将执行以下操作:
- 禁用检查这是一个Angular页面。 否则,我们会收到以下错误消息:运行testForAngular时出错。 当然,对于“角度页面”,不需要关闭此检查。
- 转到Google页面。
- 检查是否有文本输入字段。
- 输入文本“量角器”。
- 单击提交按钮(它有一个相当复杂的定位器,因为有两个按钮,第一个是不可见的)。
- 可以预期URL将包含“量角器”一词-这意味着我们做对了所有事情,然后开始搜索。
这是我得到的代码:
import { browser, by, element, protractor } from "protractor"; describe('Search', () => { it('Open google and find a text', async () => {
在代码中,我们看到一切都以describe()函数开头。 她来自茉莉花框架。 这是我们脚本的包装。 在它内部,可能有功能beforeAll()和beforeEach()在所有测试之前和每个测试之前执行任何操作。 实际上,它所测试的功能与()一样多。 最后,如果已定义,则将在每个测试和所有测试之后执行afterAll()和afterEach()进行操作。
我不会谈论Jasmine的所有功能,您可以在
jasmine.imtqy.com网站上阅读有关它们的信息
。要运行我们的测试,您首先需要将TS代码转换为JS代码,然后运行它:
$ tsc $ protractor output_js/config.js
我们的测试开始了-我们很棒。 :)

如果测试没有开始,则值得检查:
- 该代码编写正确。 通常,如果代码中存在严重错误,我们将在tsc命令期间捕获它们。
- 该Selenium服务器正在运行。 为此,您可以打开URL http: //127.0.0.1-00-00444/wd/hub-应该有一个Selenium会话接口。
- 该Chrome通常从下载的chrome-driver版本开始。 为此,请在wd /集线器/页面上,单击创建会话,然后选择Chrome。 如果无法启动,则您需要更新Chrome或下载其他版本的chrome驱动程序。
- 如果所有操作均失败,则可以验证npm install命令是否已成功完成。
- 如果所有内容均正确编写,但仍然没有任何内容-尝试搜索该错误。 它通常会有所帮助。 :)
NPM脚本
为了使生活更轻松,您可以使命令的一部分成为npm别名。 例如,我想删除具有先前JS文件的目录,并在每次测试运行之前使用新的JS文件重新创建该目录。
为此,请将脚本项添加到package.json中:
{ "name": "protractor", "scripts": { "test": "rm -rf output_js/; tsc; protractor output_js/config.js" }, "dependencies": { "@types/node": "^10.5.2", "@types/jasmine": "^3.3.12", "protractor": "^5.4.2", "typescript": "^3.4.1" } }
现在输入
npm test命令将发生以下情况:带有旧代码的output_js目录将被删除,将重新创建该目录,并将新的JS代码写入其中。 之后,测试将立即开始。
除了这组命令,您还可以指定其他您个人需要使用的命令。 例如,您可以在两次测试运行之间启动和终止硒服务器。 尽管这当然更容易在测试代码内部进行控制。
关于承诺
最后,我将讨论Promise,异步/等待以及NodeJS中的测试编写与相同的Java或Python有何不同。
JavaScript是一种异步语言。 这意味着代码并不总是按照编写顺序执行。 这包括HTTP请求,我们记得该代码通过HTTP与Selenium Server通信。
承诺(通常称为“承诺”)提供了一种组织异步代码的便捷方法。 您可以在
learning.javascript.ru上了解有关它们的更多信息。
实际上,这些对象使一个代码依赖于另一代码的执行,从而保证了一定的顺序。 量角器会非常积极地处理这些对象。
让我们来看一个例子。 假设我们执行以下代码:
driver.findElement().getText();
在Java中,我们希望我们返回String类型的对象。 在量角器中,情况并非如此,我们将返回一个Promise对象。 就像那样,以调试为目标进行打印将不起作用。
通常我们不需要打印结果值。 我们需要将其传递给已经可以使用该值的其他方法。 例如,它将检查文本是否符合预期。
Protractor中类似的方法也接受Promise对象作为输入,因此没有问题。 但是,如果您仍然想查看该值,则()将派上用场。
这是我们可以在Google页面上打印按钮文本的方式(请注意,由于这是一个按钮,因此文本位于value属性内):
至于async / await关键字,这是使用异步代码的一种较新的方法。 它使您可以避免由于大量嵌套而先前在代码中形成的promise hell。 不过,您将无法完全摆脱Promise,需要与他们合作。 这是可以理解和详细的,可以
在JavaScript中设计异步/等待:优势,陷阱和使用功能中找到 。
家庭作业
作为一项家庭作业,我建议为用AngularJS编写的页面编写测试:
protractor-demo 。
不要忘记从代码中删除有关在AngularJS上关闭页面检查的行。 并确保使用专门为AngularJS设计的定位器。 这没有什么特别的魔术,但是很方便。
总结
让我们盘点一下。 我们设法编写了可以在TypeScript + Protractor + Jasmine上运行的测试。 我们学习了如何构建这样的项目,创建必要的配置,并编写了第一个测试。
在此过程中,我们讨论了有关使用JavaScript自动测试的一些知识。 几个小时似乎很好。 :)
阅读什么,在哪里看
量角器具有相当不错的手册,其中包含JavaScript示例:
https :
//www.protractortest.org/#/tutorial茉莉花有手册:
https :
//jasmine.imtqy.com/pages/docs_home.htmlTypeScipt有一个很好的入门:
https :
//www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html在媒介上,有一篇关于TypeScript + Protractor + Cucumber的英文很好的文章:
https :
//medium.com/@igniteram/e2e-testing-with-protractor-cucumber-using-typescript-564575814e4a在我的存储库中,我发布了本文讨论的最终代码:
https :
//github.com/KotovVitaliy/HarbProtractorJasmineJasmine 。
在Internet上,您可以找到此堆栈上更复杂和更大项目的示例。
感谢您的关注! :)