前台自动化测试环境搭建javascript
在Java领域,Apache, Spring, JBoss 三大社区的开源库,一应俱全,但每一个库都在其领域中都鹤立鸡群。而Nodejs中各类各样的开源库,却让人眼花缭乱,不知从何下手。html
Nodejs领域: Jasmine作单元测试,Karma自动化完成单元测试,Grunt启动Karma统一项目管理,Yeoman最后封装成一个项目原型模板,npm作nodejs的包依赖管理,bower作javascript的包依赖管理。java
Java领域:JUnit作单元测试, Maven自动化单元测试,统一项目管理,构建项目原型模板,包依赖管理。node
Nodejs让组合变得更丰富,却又在加剧咱们的学习门槛。我还说不清楚,也看不透!jquery
上面写的有点远了,回到文章的主题,Jasmine+Karma自动化单元测试。web
Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular更名为Karma。Karma是一个让人感到很是神秘的名字,表示佛教中的缘分,因果报应,比Cassandra这种名字更让人猜不透!chrome
Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner)。该工具可用于测试全部主流Web浏览器,也可集成到CI(Continuous integration)工具,也可和其余代码编辑器一块儿使用。这个测试工具的一个强大特性就是,它能够监控(Watch)文件的变化,而后自行执行,经过console.log显示测试结果。npm
Jasmine是单元测试框架,本单将介绍用Karma让Jasmine测试自动化完成。数组
istanbul是一个单元测试代码覆盖率检查工具,能够很直观地告诉咱们,单元测试对代码的控制程度。浏览器
Jasmine是一个用来编写Javascript测试的框架,它不依赖于任何其它的javascript框架,也不须要DOM。它有拥有灵巧而明确的语法可让你轻松的编写测试代码。
jasmine的结构很简单:
describe("A suite", function() {
var foo;
beforeEach(function() {
foo = 0;
foo += 1;
});
afterEach(function() {
foo = 0;
});
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});
每一个测试都在一个测试集中运行,Suite就是一个测试集,用describe函数封装。 Spec表示每一个测试用例,用it函数封装。经过expect函数,做为程序断言来判断相等关系。setup过程用beforeEach函数封装,tearDown过程用afterEach封装。
win7 64bit, node v0.10.32, npm 1.4.28
E:\workspace npm install -g karma
注:
-g
表明全局安装
E:\workspace karma start
打开浏览器访问http:\\localhost:9876出现下面界面表示OK
~ D:\workspace\javascript\karma>karma init
Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine
注:测试框架选择
Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> yes
注:需不须要引入requirejs
引入requirejs的缘由:加载相互依赖的js文件
Do you want to capture a browser automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
>
注:选择打开的浏览器
What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
>
注:karma启动时加载的目标文件和测试文件
Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>
注:加载的目标文件不须要测试的文件
Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes
注:karma要不要动态监听目标文件和测试用例变化
Config file generated at "D:\workspace\javascript\karma\karma.conf.js".
这个指令跑完后你就会发现目录底下多了个配置文件karma.conf.js,test-main.js
karma.conf.js: karma配置文件
test-main.js: requireJS配置文件
4.2.Karma
第一次启动时的问题
1,chrome的plugins
~
E:\workspace npm install karma-chrome-launcher --save-dev
2,环境变量CHROM_BIN的问题
~ D:\workspace\javascript\karma>karma start
INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
ERROR [launcher]: Cannot start Chrome
Can not find the binary C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe
Please set env variable CHROME_BIN
设置chrom的CHROM_BIN
~
E:\workspace Set CHROM_BIN= “C:/Program Files (x86)/Chrome/chrome.exe”
~ E:\workspace npm install karma-jasmine
RequireJS是一个Javascript 文件和模块框架,能够从 http://requirejs.org/下载,若是你使用Visual Studio也能够经过Nuget获取。它支持浏览器和像node.js之类的服务器环境。使用RequireJS,你能够顺序读取仅须要相关依赖模块。
RequireJS所作的是,在你使用script标签加载你所定义的依赖时,将这些依赖经过head.appendChild()函数来加载他们。当依 赖加载之后,RequireJS计算出模块定义的顺序,并按正确的顺序进行调用。这意味着你须要作的仅仅是使用一个“根”来读取你须要的全部功能,而后剩下的事情只须要交给RequireJS就好了。为了正确的使用这些功能,你定义的全部模块都须要使用RequireJS的API,否者它不会像指望的那样 工做。
经过nodejs安装RequireJS
~
E:\workspace npm install requires –save-dev
~
E:\workspace npm install karma-requires –save-dev
注:
-save-dev :
能够直接
安装的包自动添加到
grunt
包管理配置文件中
在通常的web项目中 require都是经过<sricpt>标签静态加载到项目中去的
例如:< sricpt data-main=”main.js” src=”require.js”></ sricpt >
注:RequireJS是怎么开始工做:当RequireJS被加载的时候,它会使用 data-main属性去搜寻一个脚本文件(它应该是与使用src加载RequireJS是相同的脚本)。data-main须要给全部的脚本文件设置一 个根路径。根据这个根路径,RequireJS将会去加载全部相关的模块。
Data-main:指向的requirejs的配置文件
配置test-main.js
// This file is test/spec/main.js
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
var pathToModule = function(path) {
return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
allTestFiles.push(pathToModule(file));
}
});
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: 'base/src/js',
paths: {
'mootools' : ' lib/mootools',
'jquery' : 'lib/jquery-1.10.2',
'jquery-ui' : 'ib/jquery-1.10.2/jquery-ui'
},
shim: {
'jquery-ui': {
deps: ['jquery']
}
},
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
});
再经过 karma 配置文件将其引入
files: [
{pattern: 'src/js/lib/*.js', included: false},
{pattern: 'src/js/apps/*.js', included: false},
{pattern: 'test/*-spec.js', included: false},
'test/*-spec.js',
‘test-main.js',
'src/*.js'
],
源文件:用于实现某种业务逻辑的文件,就是咱们平时写的js脚本
假如咱们的源文件原来有个需求有一个需求:要实现单词倒写的功能,如:”ABCD” ==> “DCBA”
Src/test.js
function reverse(name){
return name.split("").reverse().join("");
}
测试文件:符合jasmineAPI的测试js脚本
Test/spec/module1/test-spec.js
describe("A suite of basic functions", function() {
it("reverse word",function(){
expect("DCBA").toEqual(reverse("ABCD"));
});
});
前期 自动生成的配置文件比较凌乱,并且有好多地方配置不到位,这个时候你们能够地下的代码 替换其内容
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// frameworks to use
frameworks: ['jasmine', 'requirejs'],
// list of files / patterns to load in the browser
files: [
{pattern: 'src/js/apps/inspect/*.js', included: false},
{pattern: 'src/js/modules/*.js', included: false},
{pattern: 'src/js/lib/*.js', included: false},
{pattern: 'src/js/apps/settings/*.js', included: false},
{pattern: 'test/spec/**/*-spec.js', included: false},
'test-main.js'
],
preprocessors: {
'src/js/apps/inspect/*.js': ['coverage']
},
// list of files to exclude
exclude: [],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['progress', 'coverage'],
coverageReporter: {
type: 'html',
dir: 'coverage/'
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
browsers: ['Chrome'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
1.将前面的test.js剪切至src/js/apps/inspect/
2.修改karma配置文件引入路径
3. 运行karma start会出现下面的结果
~
E:\workspace npm install karma-coverage
注:打完指令若是细心观察你就会发现karma的配置文件中多了蓝色部分代码,是对UT覆盖率输出的配置。
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// frameworks to use
frameworks: ['jasmine', 'requirejs'],
// list of files / patterns to load in the browser
files: [
{pattern: 'src/js/apps/inspect/*.js', included: false},
{pattern: 'src/js/modules/*.js', included: false},
{pattern: 'src/js/lib/*.js', included: false},
{pattern: 'src/js/apps/settings/*.js', included: false},
{pattern: 'test/spec/**/*-spec.js', included: false},
'test-main.js'
],
preprocessors: {
'src/js/apps/inspect/*.js': ['coverage']
},
// list of files to exclude
exclude: [],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['progress', 'coverage'],
coverageReporter: {
type: 'html',
dir: 'coverage/'
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
browsers: ['Chrome'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
启动karma start,在工程目录下面找到index.html文件,coverage/chrome/index.html
打开后,咱们看到代码测试覆盖绿报告
点击文件路径进入文件夹点击文件能够此文件的UT覆盖率
有颜色的文件表明未覆盖到的文件(覆盖由好到坏显示显色绿,黄,红)
Grunt是一个自动化的项目构建工具. 若是你须要重复的执行像压缩, 编译, 单元测试, 代码检查以及打包发布的任务. 那么你可使用Grunt来处理这些任务, 你所须要作的只是配置好Grunt, 这样能很大程度的简化你的工做.
若是在团队中使用Grunt, 你只须要与其余人员约定好使用Grunt应该规避的问题, 就可以很方便的自动化的处理大部分的常见工做任务, 你所付出的努力几乎为0.
Install grunt-karma
使用install grunt-karma –save-dev将 grunt-karma载入grunt包管理配置文件Gruntfile.js
Gruntfile.js中增长配置
注:任务配置
karma: {
unit: {
configFile: "karma.conf.js",
singleRun: true
}
},
注:载入模块文件
grunt.loadNpmTasks('grunt-karma');
注:定义具体的任务。第一个参数为任务名,第二个参数是一个数组,表示该任务须要依次使用的模块。default任务名表示,若是直接输入grunt命令,后面不跟任何参数,这时所调用的模块(该例为jshint,concat和uglify)
grunt.registerTask('unit', [‘jshint’, ‘concat’, ‘uglify’]);
grunt.registerTask('unit', ['karma']);