详解Angular Karma测试的持续集成实践


Posted in Javascript onNovember 15, 2019

使用Angular + Karma + Jasmine可以进行前端的单体测试,从前面的文章中我们了解到了Karma的工作原理,它会启动一个指定种类的浏览器,然后在此浏览器中运行测试用例。如果需要进行持续集成,比如结合Jenkins或者其他方式进行自动化的测试,如果需要手动关闭浏览器的操作,或者无法提供图形化的界面的情况保证测试的执行这些都会成为持续集成的障碍,这篇文章整理一下解决的常见方法。

可使用浏览器的测试环境

当测试环境可以使用浏览器,在这台机器上使用ng test则能进行测试,Karma会启动Chrome浏览器,然后执行测试用例,持续集成的时候,Jenkins通过远程命令执行的方式到可使用浏览器的测试环境中执行ng test完成测试。

这种方式非常简单,需要解决的只有一个问题,Angular 的demo应用执行ng test时,执行完毕之后,Chrome浏览器也不会退出,这样Jenkins的调用部分也不会返回,只需要保证其执行结束后立即关闭浏览器,这种方式就没有问题了。而实际上Karma的设定文件中,singleRun正是这个选项,缺省被设定为false,这就是其不退出的原因。只需要将此选项设定为true即可。demo示例的Karma设定文件改成如下即可:

liumiaocn:demo liumiao$ cp karma.conf.js karma.conf.js.origin
liumiaocn:demo liumiao$ vi karma.conf.js
liumiaocn:demo liumiao$ diff karma.conf.js karma.conf.js.origin 
29c29
<   singleRun: true,
---
>   singleRun: false,
liumiaocn:demo liumiao$

执行日志如下所示:

liumiaocn:demo liumiao$ rm -rf coverage/
liumiaocn:demo liumiao$ ls
README.md      e2e         node_modules     src         tsconfig.spec.json
angular.json     karma.conf.js    package-lock.json  tsconfig.app.json  tslint.json
browserslist     karma.conf.js.origin package.json     tsconfig.json
liumiaocn:demo liumiao$ 
liumiaocn:demo liumiao$ ng test --code-coverage
30% building 12/12 modules 0 active31 10 2019 20:19:39.308:INFO [karma-server]: Karma v4.1.0 server started at http://0.0.0.0:9876/
31 10 2019 20:19:39.314:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
30% building 13/13 modules 0 active31 10 2019 20:19:39.324:INFO [launcher]: Starting browser Chrome
31 10 2019 20:19:43.028:INFO [Chrome 78.0.3904 (Mac OS X 10.14.0)]: Connected on socket Pwhf3R-KNkzVDi1AAAAA with id 46366297
Chrome 78.0.3904 (Mac OS X 10.14.0): Executed 3 of 3 SUCCESS (0.373 secs / 0.321 secs)
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS

=============================== Coverage summary ===============================
Statements  : 100% ( 6/6 )
Branches   : 100% ( 0/0 )
Functions  : 100% ( 1/1 )
Lines    : 100% ( 5/5 )
================================================================================
liumiaocn:demo liumiao$ ls
README.md      coverage       karma.conf.js.origin package.json     tsconfig.json
angular.json     e2e         node_modules     src         tsconfig.spec.json
browserslist     karma.conf.js    package-lock.json  tsconfig.app.json  tslint.json
liumiaocn:demo liumiao$

在这个过程中可以看到Chrome被自动打开、执行测试用例并显示结果然后自动退出了。通过远程方式调用应该也没有问题。不评价解决方法的好坏与局限性,这也是一种实现的方式。

无需打开浏览器的测试环境: PhantomJS

比如测试环境在一个基于Alpine版Linux的容器之中的情况下,无法使用或者不希望使用图形化的浏览器的情况下,可以使用浏览器的Headless模式或者无界面方式的浏览器。PhantomJS就是这样的一种解决方法,Phantom是一个隐形的浏览器,就像它的名字那样,像一个“鬼魂/幻影/幽灵”,而事实上并没有那么高深。PhantomJS是基于Webkit内核的Headless模式,所以Webkit浏览器能做的事情,基本上它都能做,在之前爬虫的一些使用场景中有需要爱好者的追随。目前稳定版本为2.1,短时间内将为稳定在这一版本,因为目前其已经暂停更新了,更新时间据说会另行通知,但是迟迟未到。使用这个暂时停更的PhantomJS也是一种解决方法,具体步骤如下。

步骤1: 安装PhantomJS

安装非常简单,PhantomJS提供Windows/Linux/MacOS的二进制文件,只需要将相应的bin目录加入到PATH搜素路径中即完成了安装,此处以MacOS上的安装为例。

下载地址:https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-macosx.zip

解压:解压至/usr/local/phantomjs下

版本确认:phantomjs --version

liumiaocn:demo liumiao$ export PATH=$PATH:/usr/local/phantomjs/phantomjs-2.1.1-macosx/bin
liumiaocn:demo liumiao$ which phantomjs
/usr/local/phantomjs/phantomjs-2.1.1-macosx/bin/phantomjs
liumiaocn:demo liumiao$ phantomjs --version
2.1.1
liumiaocn:demo liumiao$

步骤2: 安装karma-phantomjs-launcher

执行日志入如下所示:

liumiaocn:demo liumiao$ npm install --save-dev karma-phantomjs-launcher

> phantomjs-prebuilt@2.1.16 install /Users/liumiao/Desktop/demo/node_modules/phantomjs-prebuilt
> node install.js

Considering PhantomJS found at /usr/local/phantomjs/phantomjs-2.1.1-macosx/bin/phantomjs
Found PhantomJS at /usr/local/phantomjs/phantomjs-2.1.1-macosx/bin/phantomjs ...verifying
Writing location.js file
PhantomJS is already installed on PATH at /usr/local/phantomjs/phantomjs-2.1.1-macosx/bin/phantomjs
npm WARN eslint-plugin-compat@3.3.0 requires a peer of eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 but none is installed. You must install peer dependencies yourself.

+ karma-phantomjs-launcher@1.0.4
added 16 packages from 36 contributors in 9.804s
liumiaocn:demo liumiao$

步骤3: 修改Karma的配置文件

将缺省的karma配置文件做如下修改即可

liumiaocn:demo liumiao$ diff karma.conf.js karma.conf.js.origin 
10c10
<    require('karma-phantomjs-launcher'),
---
>    require('karma-chrome-launcher'),
28,29c28,29
<   browsers: ['PhantomJS'],
<   singleRun: true,
---
>   browsers: ['Chrome'],
>   singleRun: false,
liumiaocn:demo liumiao$

修改说明:

  • 仍然需要将singleRun设定为true
  • 将chrome的launcher换成phantomjs
  • 将浏览器也从Chrome换成PhantomJS

如果使用的是Angular 8或者是es6的target设定需要将target做如下修改

liumiaocn:demo liumiao$ diff tsconfig.json tsconfig.json.org 
13c13
<   "target": "es5",
---
>   "target": "es2015",
liumiaocn:demo liumiao$

步骤3: 执行测试

执行ng test可以看到使用的是PhantomJS进行的测试,而且在执行过程中并没有浏览器被打开和执行。

liumiaocn:demo liumiao$ ng test --code-coverage
25% building 94/94 modules 0 active01 11 2019 06:11:48.490:INFO [karma-server]: Karma v4.1.0 server started at http://0.0.0.0:9876/
01 11 2019 06:11:48.493:INFO [launcher]: Launching browsers PhantomJS with concurrency unlimited
25% building 96/96 modules 0 active01 11 2019 06:11:48.573:INFO [launcher]: Starting browser PhantomJS
01 11 2019 06:11:52.035:INFO [PhantomJS 2.1.1 (Mac OS X 0.0.0)]: Connected on socket PTR3E6eTdHOW0JcEAAAA with id 8370488
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 3 of 3 SUCCESS (0.512 secs / 0.769 secs)
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS

=============================== Coverage summary ===============================
Statements  : 100% ( 7/7 )
Branches   : 100% ( 0/0 )
Functions  : 100% ( 2/2 )
Lines    : 100% ( 6/6 )
================================================================================
liumiaocn:demo liumiao$

此中方式由于PhantomJS已经暂停更新,碰到问题时可能会较为尴尬,比如目前就出现在Angular 8升级是PhantomJS无法正常动作的网上发帖求助,实际上修改为es5能解决大部分问题,所以选择时需要慎重考虑。

无需打开浏览器的测试环境: Chrome的无头模式

PhantomJS使用Webkit内核,无需打开浏览器来完成测试,而实际上除去IE的很多浏览器都提供这种所谓的无头(Headless)模式,Chrome也可以直接提供,在Chrome 59开始提供了headless mode(无头模式)。在Angular 8中使用Chrome的无头模式进行测试非常简单,只需要修改缺省的浏览器从Chrome到ChromeHeadless即可。

步骤1: 修改Karma的配置文件

将缺省的karma配置文件做如下修改即可

liumiaocn:demo liumiao$ diff karma.conf.js karma.conf.js.origin 
28,29c28,29
<   browsers: ['ChromeHeadless'],
<   singleRun: true,
---
>   browsers: ['Chrome'],
>   singleRun: false,
liumiaocn:demo liumiao$

修改说明:

  1. 仍然需要将singleRun设定为true
  2. 将浏览器从Chrome改成ChromeHeadless

步骤2: 执行测试

执行ng test可以看到使用的是ChromeHeadless进行的测试,而且在执行过程中并没有浏览器被打开和执行。

liumiaocn:demo liumiao$ ng test --code-coverage
25% building 15/15 modules 0 active01 11 2019 06:37:05.037:INFO [karma-server]: Karma v4.1.0 server started at http://0.0.0.0:9876/
01 11 2019 06:37:05.040:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited
25% building 93/93 modules 0 active01 11 2019 06:37:05.154:INFO [launcher]: Starting browser ChromeHeadless
01 11 2019 06:37:08.720:INFO [HeadlessChrome 78.0.3904 (Mac OS X 10.14.0)]: Connected on socket Br7fkzwejyGNs2WgAAAA with id 35869507
HeadlessChrome 78.0.3904 (Mac OS X 10.14.0): Executed 3 of 3 SUCCESS (0.374 secs / 0.319 secs)
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS

=============================== Coverage summary ===============================
Statements  : 100% ( 7/7 )
Branches   : 100% ( 0/0 )
Functions  : 100% ( 2/2 )
Lines    : 100% ( 6/6 )
================================================================================
liumiaocn:demo liumiao$

总结

这篇文章介绍了三种常见的Karma的集成方式,由于PhantomJS暂停更新,并且其内核只是Webkit,所以大多数情况直接使用浏览器的Headless Mode可能是个更好的主意。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 的方法重载效果
Aug 07 Javascript
JavaScript实现查找字符串中第一个不重复的字符
Dec 29 Javascript
JS读写CSS样式的方法汇总
Aug 16 Javascript
jQuery Validate设置onkeyup验证的实例代码
Dec 09 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
Mar 04 Javascript
Vue 单文件中的数据传递示例
Mar 21 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
Jul 13 Javascript
详解Vue双向数据绑定原理解析
Sep 11 Javascript
vue.js获得当前元素的文字信息方法
Mar 09 Javascript
Angularjs之ngModel中的值验证绑定方法
Sep 13 Javascript
微信小程序动态设置图片大小的方法
Nov 21 Javascript
js刷新页面location.reload()用法详解
Dec 09 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
Nov 15 #Javascript
JavaScript定时器常见用法实例分析
Nov 15 #Javascript
解决Layui 表格自适应高度的问题
Nov 15 #Javascript
layui前端时间戳转化实例
Nov 15 #Javascript
JavaScript变量基本使用方法实例分析
Nov 15 #Javascript
JavaScript字符串处理常见操作方法小结
Nov 15 #Javascript
layui数据表格重载实现往后台传参
Nov 15 #Javascript
You might like
Terran兵种介绍
2020/03/14 星际争霸
PHP和XSS跨站攻击的防范
2007/04/17 PHP
解析VS2010利用VS.PHP插件调试PHP的方法
2013/07/19 PHP
PHP设计模式概论【概念、分类、原则等】
2020/05/01 PHP
javascript常用对话框小集
2013/09/13 Javascript
setTimeout和setInterval的深入理解
2013/11/08 Javascript
JS实现局部选择打印和局部不选择打印
2014/04/03 Javascript
javascript实现带节日和农历的日历特效
2015/02/01 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
每天一篇javascript学习小结(Array数组)
2015/11/11 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
2016/05/12 Javascript
关于微信中a链接无法跳转问题
2016/08/02 Javascript
Bootstrap 设置datetimepicker在屏幕上面弹出设置方法
2017/03/21 Javascript
设置cookie指定时间失效(实例代码)
2017/05/28 Javascript
vue-router 源码之实现一个简单的 vue-router
2018/07/02 Javascript
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
ant-design-vue 实现表格内部字段验证功能
2019/12/16 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
2020/04/01 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
2020/04/14 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
[10:42]Team Liquid Vs Newbee
2018/06/07 DOTA
Python之文字转图片方法
2018/05/10 Python
pandas带有重复索引操作方法
2018/06/08 Python
python 可视化库PyG2Plot的使用
2021/01/21 Python
梅西百货澳大利亚:Macy’s Australia
2017/07/26 全球购物
上班睡觉检讨书
2014/01/09 职场文书
幼儿园中秋节活动反思
2014/02/16 职场文书
党员承诺书内容
2014/03/26 职场文书
房产公证委托书范本
2014/09/20 职场文书
企业党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
旷课检讨书范文
2014/10/30 职场文书
2015年超市工作总结范文
2015/05/26 职场文书
成绩单家长意见
2015/06/03 职场文书
放飞理想主题班会
2015/08/14 职场文书
《学会看病》教学反思
2016/02/17 职场文书
pytorch model.cuda()花费时间很长的解决
2021/06/01 Python