转载

基于 fis 的前端自动化单元测试方案

在上一片文章中,我介绍了如何在 fis 项目中使用 jasmine 进项单元测试,这个方案,可以解决 fis 中模块的引用的问题, 整个单元测试可以 run 起来,但是,还是有很多不足:

  1. 人工成本较高,需要手动配置 runner 页面,并在浏览器中查看结果。
  2. 难以统计单元测试的覆盖率。
  3. 无法生成测试报告。
  4. 无法部署到 ci 系统中。

为了解决以上问题,故采用了全新方案,实现全自动单测。新方案主要包含以下改进:

  1. 采用 karmar 代替手动配置的 runner 页面,测试 case 在 PhantomJS 跑。
  2. 采用 karmar-coverage 统计单测覆盖率,并生成 统计结果页面。
  3. 采用 karma-junit-report 生成测试报告。

karma.conf.js

我们知道,如果要引入 karma, 就需要通过 karma.conf.js 来配置相关的被测模块和 case,fis 的代码在编译前和编译后,会产生不同的 url,如何准确定位到单测的 case 和被测模块文件呢?

值得庆幸的是,fis 的编译会产出 map.json,所有资源的依赖关系都会记录在其中。我们可以把所有的 js 文件和 map.json 都添加到 karma server 且不自动加载,然后通过 require.async 的方式异步加载所需资源。

module.exports = function (config) {     config.set({         ……         frameworks: ['jasmine'],         reporters: ['progress', 'coverage', 'junit'],         browsers: ['PhantomJS'],          preprocessors: {             '**/*.js': 'coverage';         },          coverageReporter: {             type: 'html',             dir: './coverage/'         },          junitReporter: {             outputDir: './report/',             outputFile: 'report.xml'         },          files: [             // 优先加载mod.js             '**/*/common/mod*.js',              // 当前模块相关文件添加到Karma server上,设置included为false,不自动加载,通过modjs控制             {pattern: '**/*.js', included: false},              // 将map.json添加到 Karma server,后续读取文件内容,用以确定资源依赖关系             {pattern: 'config/**/*-map.json', included: false},              // 加载测试入口文件             './test/' + project + '/' + namespace + '/test-main.js'         ],         ……      }); }; 

test-main.js

测试入口文件,这里会读取 map.json,重写资源表中资源的路径为 karma server 上的真实地址,同时重写了 karma. start 方法,异步调用找出的 case 文件 (spec.js 结尾的文件 )。

(function () {      var tests = [];      if (window.XMLHttpRequest) // Firefox, Opera 8.0+, Safari,chrome,phantomjs         xhr = new XMLHttpRequest();     else // IE         xhr = new ActiveXObject("Microsoft.XMLHTTP");      // 遍历在karma.conf.js的files中配置的相关文件,这些文件已经在karma server上     for (var _file in window.__karma__.files) {          // 找到本模块和被依赖模块的map.json文件         if (window.__karma__.files.hasOwnProperty(_file) &&             _file.indexOf('map.json') > -1) {             xhr.open('get', _file, false);             xhr.send();              // 读取map.json文件内容,定义为resourceMap             var resourceMap = JSON.parse(xhr.responseText);              for (var file in resourceMap.res) {                  // 找出本模块所有单测文件                 if (//.spec/.js$/.test(file)) {                     console.log('add spec: ' + file);                     tests.push(file);                 }                 // 从karma server上保存的文件路径中,获取到resourceMap中所需文件的真实url                 for (var _file in window.__karma__.files) {                     if (window.__karma__.files.hasOwnProperty(_file) &&                         _file.indexOf(resourceMap.res[file]['uri']) > -1) {                         resourceMap.res[file]['url'] = _file;                     }                 }             }              // 调用mod.js提供的require.resourceMap接口,将resourceMap打出来,以此确定资源的依赖关系和url             require.resourceMap(resourceMap);         }     }      // 由于使用自定义资源加载控制,因此需要重写触发 karma的方法     // 使用 jasmine 只需要在资源加载完毕之后触发 start 方法即可     // 主动加载测试文件,后续mod.js根据resourceMap自动加载测试文件所需的被测文件以及被依赖的文件     var _fn = window.__karma__.start;     window.__karma__.start = function () {         require.async(tests, function () {             _fn.call();         });     }  })(); 

fis-conf.js

添加单测相关的输出配置:

fis.config.set('roadmap.path', [{     reg: /^//test//(.*/.spec/.js)$/i,     isMod: true,     useHash: false,     release: '/test/middlepage/yunying/${namespace}/$1' }, {     reg: /^//test//(.*)/i,     isMod: false,     useHash: false,     release: '/test/middlepage/yunying/${namespace}/$1' }, {     reg: 'karma.conf.js',     useHash: false,     release: '/test/middlepage/yunying/${namespace}/$&' }].concat(fis.config.get('roadmap.path', []))); 

目录结构

整个 fis 项目的目录类似如下:

编译前

基于 fis 的前端自动化单元测试方案

编译后

基于 fis 的前端自动化单元测试方案

运行测试

首先编译指定 fis 模块

fis release -r common -d output  fis release module1 -d output  

进入产出目录,执行 karma start

cd output karma start test/module1/karma.conf.js 

命令行可看到如下测试结果:

基于 fis 的前端自动化单元测试方案

覆盖率和统计报告

分别位于 output 目录的 coverage 和 report 子目录中(如 karma.conf.js 配置)。

部署CI

以 jenkins 为例:

  1. 在execute shell中填写脚本:

    cd /home/work/repos/fis2-karma

    rm -rf ./output

    fis release -r common -d ./output -mp

    cd ./output

    karma start test/common/karma.conf.js

  2. 设置 覆盖率报告位置

基于 fis 的前端自动化单元测试方案

  1. 设置测试结果报告位置

基于 fis 的前端自动化单元测试方案

至此,整个 fis 单测方案部署完毕。

正文到此结束
Loading...