网页前端持续集成(2) - qunit+JSCoverage+PhantomJS使用小记
2013-12-12 23:42
260 查看
今年早些时候为公司项目做过一些网页前端程序的持续集成(CI),在过去的几个月中不断地给不同的人讲解过之后,我决定开一篇介绍一下。
公司项目是一个ASP.net的网站,其中核心是一些JavaScript 的框架库以及扩展函数。基本目标是在Jenkins上集成单元测试(Unit Test), 和代码覆盖率的统计。由于是前端程序,所以我们采用qunit来做单元测试,代码覆盖率使用JSCoverage(使用简介可移步helloworld)。不过CI需要的是后台自动运行各个步骤,怎么办?我们找到了一个很好用的工具PhantomJS,
它通过一个webkit浏览器内核,实现了后台隐式的打开网址或网页,可以极大的方便前端程序的测试。那么,怎么把这几样宝贝集成起来?这篇介绍的就是这样一个windows上的例子,把它做一遍,可以对这几项工具有基本的了解。
0. 环境搭建
下载qunit, JSCoverage, PhantomJS, ant(apache-ant)。除qunit外,把其余三项的bin目录添加到环境变量Path中去。
用到的压缩包下载地址会列在文末。其解压缩后的根目录列表如下,数目稍多因为把qunit, jscoverage,phantomjs的exe和一些默认配置辅助文件都放过来了,省得来回切换。
1. 定义待测试JavaScript 文件及函数
testme.js:
2. 编辑待测试网页
testme.test.html
其中写了5个测试用例,并加载了qunit.js
3.在build.xml中定义目录结构。
4.在build.xml中定义各项任务
任务clean是清空全部已有文件,prep是准备工作,把所有用到的文件拷贝到目标目录中去。
到目前为止,各项任务定义完毕,可以调用了。
5. 编辑jscoverage.bat
注意定义成本地的绝对路径。最后一行的末尾 %* 意思是接受后续的参数。
6. 编辑phantomjs.bat
7. 编辑run-qunit.js
这个文件告诉PhantomJS如何启动。最重要的是要定义onReady函数,在网页启动完成后执行。这里我们仅仅基于JSCoverage的各行执行次数,计算了总的文件覆盖率。
额外的还有test-support.js文件,定义了一些辅助函数。因这两文件较长,此处就不列了,文件细节可以在压缩包中找到。
8.执行ant
运行成功的输出如下,注意到这里两个文件的覆盖率均为100%。
9.检查输出网页
打开.\target\testhtm\testme.test.html,可以看到qunit的执行结果。
打开.\target\testhtm\testme.coverage.testme.js.html,能够看到以不同颜色标示的代码覆盖部分。怎么样?还算清楚吧:)有同学可能注意到了,这些颜色就是在testme.test.html中<style>部分定义的。
当然 testme.coverage.testme02.js.html也能带来同样的显示。
小结:
1. qunit+JSCoverage+PhantomJS 的组合能够满足前端程序对于持续集成的基本需要。对于目标程序,其开发语言限制较少,比如Java完全可以。
2. 如果想要集成到Jenkins的平台中,只需要将JSCoverage, PhantomJS等执行步骤单独设置成Jenkins的一个任务即可。
3. 如果想把相应的测试结果,代码覆盖率等输出到文件,可以编辑PhantomJS.exe 后紧跟的第一个文件,比如这里的run-qunit,js,在onReady()函数中加入你所需要的部分。
注:压缩包下载地址phantomjs-jscoverage.zip
公司项目是一个ASP.net的网站,其中核心是一些JavaScript 的框架库以及扩展函数。基本目标是在Jenkins上集成单元测试(Unit Test), 和代码覆盖率的统计。由于是前端程序,所以我们采用qunit来做单元测试,代码覆盖率使用JSCoverage(使用简介可移步helloworld)。不过CI需要的是后台自动运行各个步骤,怎么办?我们找到了一个很好用的工具PhantomJS,
它通过一个webkit浏览器内核,实现了后台隐式的打开网址或网页,可以极大的方便前端程序的测试。那么,怎么把这几样宝贝集成起来?这篇介绍的就是这样一个windows上的例子,把它做一遍,可以对这几项工具有基本的了解。
0. 环境搭建
下载qunit, JSCoverage, PhantomJS, ant(apache-ant)。除qunit外,把其余三项的bin目录添加到环境变量Path中去。
用到的压缩包下载地址会列在文末。其解压缩后的根目录列表如下,数目稍多因为把qunit, jscoverage,phantomjs的exe和一些默认配置辅助文件都放过来了,省得来回切换。
1. 定义待测试JavaScript 文件及函数
testme.js:
function add(){ var sum =0; var count=0; for (var i=0; i<arguments.length; i++){ if(arguments[i] < 10){ sum += arguments[i]; count++; } } if(count < arguments.length){ for (var i=0; i<arguments.length; i++){ if(arguments[i] >= 10){ sum += arguments[i]; } } } return sum; }testme02.js:
function divide(){ if(arguments.length == 0){ return 0; } if(arguments[0] == 0) return 0; var quotient = arguments[0]; for (var i=1; i<arguments.length; i++){ if(arguments[i] == 0){ continue; }else{ quotient /= arguments[i]; } } return quotient; }
2. 编辑待测试网页
testme.test.html
<!DOCTYPE html> <html> <head> <!-- we need QUnit as a test runner --> <link rel="stylesheet" href="qunit.css" type="text/css" media="screen" /> <script src="qunit.js"></script> <!-- we'd like to have the file we're going to test --> <script src="testme.js"></script> <script src="testme02.js"></script> <script src="test-support.js"></script> <!-- and finally lets write some tests --> <script> test("add(1, 2, 10, 9)", function(){ equal(add(1, 2, 10, 9), 22); }); test("divide ()", function(){ equal(divide(), 0); }); test("divide (0, 1, 2)", function(){ equal(divide(0, 1, 2), 0); }); test("divide (10, 0, 5)", function(){ equal(divide(10, 0, 5), 2); }); test("add (int, divide())", function(){ equal(add(1, divide(12, 3)), 5); }); </script> <style> .code { white-space: pre; font-family: courier new; width: 100%; } .miss { background-color: #FFFFFF; } .hit { background-color: #94FF7C; } .undef { background-color: #00FF9E; } </style> </head> <body> <h1 id="qunit-header">QUnit Tests</h1> <h2 id="qunit-banner"></h2> <div id="qunit-testrunner-toolbar"></div> <h2 id="qunit-userAgent"></h2> <ol id="qunit-tests"></ol> <div id="qunit-fixture"></div> </body> </html>
其中写了5个测试用例,并加载了qunit.js
3.在build.xml中定义目录结构。
<project name="jsunittests" basedir="." default="main"> <property name="basedir" location="."/> <property name="builddir" location="${basedir}/target"/> <proerty name="jstestdir" location="${builddir}/testjs"/> <property name="jsdir" location="${jstestdir}/js"/> <property name="jsinstrumenteddir" location="${jstestdir}/jsinstrumented"/> <property name="testhtmdir" location="${builddir}/testhtm"/> <condition property="phantom.filename" value="phantomjs.bat"><os family="windows"/></condition> <property name="jscoverage.filename" value="jscoverage.bat"/> ... </project>$basedir 是当前目录,$jstestdir下的两个目录存放待测试js文件,其中\js是原始文件,\jsinstrumented是经过JSCoverage注入过锚标记的文件。$testhtmdir是测试用的HTML目录。
4.在build.xml中定义各项任务
任务clean是清空全部已有文件,prep是准备工作,把所有用到的文件拷贝到目标目录中去。
<target name="clean"> <delete dir="${builddir}"/> </target> <target name="prep"> <mkdir dir="${builddir}"/> <mkdir dir="${jstestdir}"/> <mkdir dir="${jsdir}"/> <mkdir dir="${jsinstrumenteddir}"/> <mkdir dir="${testhtmdir}"/> <!--copy test source js files to target--> <copy todir="${jsdir}"> <fileset dir="${basedir}"> <include name="testme.js" /> <include name="testme02.js" /> </fileset> </copy> <!-- run jscoverage to produce a version of the file instrumented for code coverage --> <exec executable="${jscoverage.filename}" failonerror="true"> <arg value="${jsdir}"/> <arg value="${jsinstrumenteddir}"/> </exec> <!-- copy our test htm files and modify them to point to the coverage indexed version of the test file. --> <copy todir="${testhtmdir}"> <fileset dir="${basedir}"> <include name="*.test.html" /> </fileset> </copy> <!-- copy core resources to testhtmdir so we can load them with same paths as when executing test htm files directly --> <copy todir="${testhtmdir}"> <fileset dir="${jsinstrumenteddir}"> <include name="**/*.js" /> <exclude name="jscoverage.js"/> </fileset> </copy> <copy todir="${testhtmdir}"> <fileset dir="${basedir}"> <include name="test-support.js" /> <include name="run-qunit.js" /> <include name="qunit.css" /> <include name="qunit.js" /> </fileset> </copy> </target>接下来,定义实际做测试的任务jstest。我们用PhantomJS打开一个HTML文件,这个html包含qunit文件,并调用已经带有JSCoverage标记的JS待测试函数。这样如果运行成功,我们可以得到测试例子的通过率和代码覆盖率。
<target name="jstest"> <!--Run all tests via phantom, fail if tests fail. Execute all files with extension .test.htm. --> <apply executable="${basedir}/${phantom.filename}" failonerror="true" dir="${testhtmdir}" relative="false"> <arg value="run-qunit.js"/> <srcfile/> <!--arg[0]--> <fileset dir="${testhtmdir}"> <include name="*.test.html" /> </fileset> <!--argp[1]--> <arg value="${basedir}"/> </apply> </target>这里的run-qunit.js是PhantomJS的启动文件,它从中得知该从哪个网址/网页启动,导入后又该执行什么动作。之后的第一个参数是输入的网页文件,第二个参数是输出路径。
到目前为止,各项任务定义完毕,可以调用了。
<target name="main" depends="clean, prep, jstest"> </target>
5. 编辑jscoverage.bat
注意定义成本地的绝对路径。最后一行的末尾 %* 意思是接受后续的参数。
set JSCov_Dir=D:\Product\VEF-CI-ref\jsunit\ %JSCov_Dir%\jscoverage.exe %*
6. 编辑phantomjs.bat
set PhantomJS_Dir=D:\Product\VEF-CI-ref\jsunit\ %PhantomJS_Dir%/phantomjs.exe %*
7. 编辑run-qunit.js
这个文件告诉PhantomJS如何启动。最重要的是要定义onReady函数,在网页启动完成后执行。这里我们仅仅基于JSCoverage的各行执行次数,计算了总的文件覆盖率。
额外的还有test-support.js文件,定义了一些辅助函数。因这两文件较长,此处就不列了,文件细节可以在压缩包中找到。
8.执行ant
运行成功的输出如下,注意到这里两个文件的覆盖率均为100%。
9.检查输出网页
打开.\target\testhtm\testme.test.html,可以看到qunit的执行结果。
打开.\target\testhtm\testme.coverage.testme.js.html,能够看到以不同颜色标示的代码覆盖部分。怎么样?还算清楚吧:)有同学可能注意到了,这些颜色就是在testme.test.html中<style>部分定义的。
当然 testme.coverage.testme02.js.html也能带来同样的显示。
小结:
1. qunit+JSCoverage+PhantomJS 的组合能够满足前端程序对于持续集成的基本需要。对于目标程序,其开发语言限制较少,比如Java完全可以。
2. 如果想要集成到Jenkins的平台中,只需要将JSCoverage, PhantomJS等执行步骤单独设置成Jenkins的一个任务即可。
3. 如果想把相应的测试结果,代码覆盖率等输出到文件,可以编辑PhantomJS.exe 后紧跟的第一个文件,比如这里的run-qunit,js,在onReady()函数中加入你所需要的部分。
注:压缩包下载地址phantomjs-jscoverage.zip
相关文章推荐
- Python使用Selenium和PhantomJS解析动态JS的网页
- 使用Selenium和PhantomJS解析带JS的网页
- 使用Selenium和PhantomJS解析带JS的网页
- 使用phantomjs&casperjs+jsoup获取网页内容
- 微信网页分享JS-SDK的集成使用
- Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目
- Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目
- Node.js 动态网页爬取 PhantomJS 使用入门
- Python爬虫学习——使用selenium和phantomjs爬取js动态加载的网页
- Python使用Selenium和PhantomJS解析动态JS的网页
- 使用Django向网页的页面js中传递一个数组的方法
- 使用 Visual Studio Team Services 和 IIS 创建持续集成管道
- 前端开发者使用JS框架的三个等级
- linux学习:持续集成篇--svn版本管理系统的安装与使用-02
- 使用 PhantomJS + GM 实现网页中校检图片的截取
- 使用Hudson持续集成Android项目
- Jenkins+Node.js持续集成
- 常用网页使用js技巧收集(231个)
- Jenkins构建Android项目持续集成之findbugs的使用
- (转)使用CruiseControl+SVN+ANT实现持续集成之二