详解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 相关文章推荐
动态刷新 dorado树的js代码
Jun 12 Javascript
Javascript this 的一些学习总结
Aug 31 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
浅谈Javascript变量作用域问题
Dec 16 Javascript
javascript鼠标滑动评分控件完整实例
May 13 Javascript
js实现仿京东2级菜单效果(带延时功能)
Aug 27 Javascript
基于javascript实现listbox左右移动
Jan 29 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
May 13 Javascript
JS冒泡事件与事件捕获实例详解
Nov 25 Javascript
基于vue.js实现的分页
Mar 13 Javascript
关于layui时间回显问题的解决方法
Sep 24 Javascript
如何使用three.js 制作一个三维的推箱子游戏
Jul 29 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
php 中文处理函数集合
2008/08/27 PHP
php无限分类且支持输出树状图的详细介绍
2013/06/19 PHP
PHP面试题之文件目录操作
2015/10/15 PHP
php安装扩展mysqli的实现步骤及报错解决办法
2017/09/23 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
2019/05/13 PHP
Flash+XML滚动新闻代码 无图片 附源码下载
2007/11/22 Javascript
javaScript 判断字符串是否为数字的简单方法
2009/07/25 Javascript
Javascript学习笔记5 类和对象
2010/01/11 Javascript
javascript preload&amp;lazy load
2010/05/13 Javascript
根据对象的某一属性进行排序的js代码(如:name,age)
2010/08/10 Javascript
javascript中parseInt()函数的定义和用法分析
2014/12/20 Javascript
js实现的万能flv网页播放器代码
2016/04/30 Javascript
实例讲解Jquery中隐藏hide、显示show、切换toggle的用法
2016/05/13 Javascript
Node调用Java的示例代码
2017/09/20 Javascript
浅谈Vue的响应式原理
2019/05/30 Javascript
深入解析koa之异步回调处理
2019/06/17 Javascript
js实现点赞按钮功能的实例代码
2020/03/06 Javascript
Vue发布订阅模式实现过程图解
2020/04/30 Javascript
处理JavaScript值为undefined的7个小技巧
2020/07/28 Javascript
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
python自动格式化json文件的方法
2015/03/11 Python
python检查URL是否正常访问的小技巧
2017/02/25 Python
Python 高级专用类方法的实例详解
2017/09/11 Python
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
python线程池threadpool实现篇
2018/04/27 Python
如何解决python多种版本冲突问题
2020/10/13 Python
利用纯CSS3实现tab选项卡切换示例代码
2016/09/21 HTML / CSS
HTML5资源预加载(Link prefetch)详细介绍(给你的网页加速)
2014/05/07 HTML / CSS
日本动漫周边服饰销售网站:Atsuko
2019/12/16 全球购物
Puccini乌克兰:购买行李箱、女士手袋网上商店
2020/08/06 全球购物
高级文秘工作总结的自我评价
2013/09/28 职场文书
2014最新离职证明范本
2014/09/12 职场文书
2015年全国科普日活动总结
2015/03/23 职场文书
2015年公务员工作总结
2015/04/24 职场文书
我的暑假生活作文(五年级)范文
2019/08/07 职场文书
在ubuntu下安装go开发环境的全过程
2022/08/05 Golang