集成 Karma 和 Angular2 咱們須要作不少工做,因爲須要使用 TypeScript 進行開發,首先須要正確配置 Typescript ,而後正確配置對 Angular2 的引用。還要建立 Karma 的入口文件,以便進行打包。node
安裝 Angular2.beta.7webpack
karma3@1.0.0 C:\study\karmaStudy\karma3 ├── angular2@2.0.0-beta.7 ├── UNMET PEER DEPENDENCY es6-promise@^3.0.2 ├── UNMET PEER DEPENDENCY es6-shim@^0.33.3 ├── UNMET PEER DEPENDENCY reflect-metadata@0.1.2 ├── UNMET PEER DEPENDENCY rxjs@5.0.0-beta.2 └── UNMET PEER DEPENDENCY zone.js@0.5.15 npm WARN EPEERINVALID angular2@2.0.0-beta.7 requires a peer of es6-promise@^3.0.2 but none was installed. npm WARN EPEERINVALID angular2@2.0.0-beta.7 requires a peer of es6-shim@^0.33.3 but none was installed. npm WARN EPEERINVALID angular2@2.0.0-beta.7 requires a peer of reflect-metadata@0.1.2 but none was installed. npm WARN EPEERINVALID angular2@2.0.0-beta.7 requires a peer of rxjs@5.0.0-beta.2 but none was installed. npm WARN EPEERINVALID angular2@2.0.0-beta.7 requires a peer of zone.js@0.5.15 but none was installed.
若是使用了 NPM 3 以上版本,須要手工安裝依賴庫es6
es6-promise@^3.0.2
es6-shim@^0.33.3
reflect-metadata@0.1.2
rxjs@5.0.0-beta.2
zone.js@0.5.15
安裝 webpack 和它的插件 ts-loaderweb
npm i -D webpack ts-loader
安裝 karma 及其插件chrome
npm i -D karma karma-chrome-launcher karma-jasmine jasmine-core karma-webpack
安裝 typingsnpm
這裏,咱們須要 es6-shim 的定義和 jasmine 的定義。json
奇怪的是 install 必須是第一個參數。promise
安裝 jasmine 的定義angular2
> typings install --save --ambient jasmine ? Found jasmine typings for DefinitelyTyped. Continue? Yes Installing jasmine@~2.2.0 (DefinitelyTyped)... jasmine └── (No dependencies)
安裝 es6-shim 的定義app
> typings install --save --ambient es6-shim ? Found es6-shim typings for DefinitelyTyped. Continue? Yes Installing es6-shim@~0.31.2 (DefinitelyTyped)... es6-shim └── (No dependencies)
這些組件安裝完成以後,你的 package.json 應該是這樣的。
{ "name": "karma3", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "angular2": "^2.0.0-beta.7", "es6-promise": "^3.0.2", "es6-shim": "^0.33.3", "reflect-metadata": "^0.1.2", "rxjs": "^5.0.0-beta.2", "zone.js": "^0.5.15" }, "devDependencies": { "jasmine-core": "^2.4.1", "karma": "^0.13.21", "karma-chrome-launcher": "^0.2.2", "karma-jasmine": "^0.3.7", "karma-webpack": "^1.7.0", "ts-loader": "^0.8.1", "typings": "^0.6.8", "webpack": "^1.12.14" } }
在項目目錄中建立 src 文件夾,在其中建立名爲 MyMaths.ts 的代碼文件
import { Component } from 'angular2/core'; import { Injectable } from 'angular2/core'; @Component({ selector: "hello" }) export class MyMaths{ add(a: number, b:number ){ return a + b; } }
在項目目錄中,建立 test 和其中的 unit 子文件夾,咱們的單元測試將會保存在這個文件夾中。
建立名爲 MyMaths.spec.ts 的單元測試文件
import { MyMaths } from '../../src/MyMaths'; describe('hello, unit test.', function(){ var myMaths = new MyMaths(); it('hello, add', function(){ let a = 2, b = 3; let result = myMaths.add(a, b ); expect(result).toBe( 5 ); }); it('it should failded.', function(){ let a = 2, b = 3; let result = myMaths.add(a, b); expect(result).toBe( 100 ); }) });
在項目目錄中建立名爲 tsconfig.Json 的 TypeScript配置文件。
注意其中的 noEmitHelpers 必須配置爲 false,emitDecoratorMetadata 必須配置爲 true.
{ "compilerOptions": { "target": "es5", "module": "commonjs", "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "noEmitHelpers": false, "noImplicitAny": false, "sourceMap": true }, "exclude":[ "node_modules", "typings/main", "typings/main.d.ts" ], "filesGlob": [ "./src/**/*.ts", "!./node_modules/**/*.ts" ] }
webpack 的默認配置文件爲 webpack.config.js,咱們這裏用來測試打包的正確性。
var path = require('path'); var ROOT_PATH = path.resolve(__dirname); var BUILD_PATH = path.resolve(ROOT_PATH, 'build'); module.exports = { resolve: { extensions: ['', '.js', '.ts'] }, entry: "./spec-bundle.js", output: { path: BUILD_PATH, filename: 'bundle.js' }, module: { loaders: [ { test: /\.ts$/, loader: 'ts-loader' } ] }, node: { global: 'window', progress: false, crypto: 'empty', module: false, clearImmediate: false, setImmediate: false } };
首先,建立 karma 的入口文件,咱們經過這個文件將全部的測試代碼和待測試代碼一塊兒打包。
建立名爲 spec-bundle.js 的入口文件。
require('es6-shim'); require('es6-promise'); require('reflect-metadata'); require('rxjs'); require('zone.js'); var testContext = require.context('./test', true, /\.spec\.ts/); var appContext = require.context('./src', true, /\.ts/); appContext.keys().forEach(appContext); testContext.keys().forEach(testContext); var domAdapter = require('angular2/src/platform/browser/browser_adapter'); domAdapter.BrowserDomAdapter.makeCurrent();
而後,建立 karma 的配置文件。能夠先使用 karma init 建立基本的配置信息,而後修改成咱們須要的內容。
// Karma configuration // Generated on Thu Feb 25 2016 10:11:36 GMT+0800 (China Standard Time) module.exports = function(config) { var testWebpackConfig = require('./webpack.test.config.js'); config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // list of files / patterns to load in the browser files: [ 'spec-bundle.js' ], // list of files to exclude exclude: [ ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { 'spec-bundle.js': ['webpack'] }, webpack: testWebpackConfig, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], // 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 // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['Chrome'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: true, // Concurrency level // how many browser should be started simultaneous concurrency: Infinity }) }
這裏用到了 webpack 進行打包,並且聲明瞭使用 webpack.test.config.js 做爲 webpack 的配置文件。
建立這個名爲 webpack.test.config.js 的配置文件。這個文件不須要入口文件,也不須要輸出目錄。Karma 將提供入口和獲取打包以後的輸出。
var path = require('path'); var ROOT_PATH = path.resolve(__dirname); var BUILD_PATH = path.resolve(ROOT_PATH, 'build'); module.exports = { resolve: { extensions: ['', '.js', '.ts'] }, module: { loaders: [ { test: /\.ts$/, loader: 'ts-loader' } ] }, node: { global: 'window', progress: false, crypto: 'empty', module: false, clearImmediate: false, setImmediate: false } };
因爲已經配置了 webpack,能夠直接在項目目錄中執行 webpack,應該能夠在 build 子目錄中看到打包以後的文件,文件中應該已經正確包含了咱們的全部代碼。
執行 karma start ,能夠完成測試過程。
25 02 2016 11:13:15.560:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/ 25 02 2016 11:13:15.576:INFO [launcher]: Starting browser Chrome 25 02 2016 11:13:18.349:INFO [Chrome 47.0.2526 (Windows 7 0.0.0)]: Connected on socket /#uBbzQ9xOIQzT1jNOAAAA with id 85611572 Chrome 47.0.2526 (Windows 7 0.0.0) hello, unit test. it should failded. FAILED Expected 5 to be 100. at Object.<anonymous> (C:/study/karmaStudy/karma3/spec-bundle.js:17352:25) Chrome 47.0.2526 (Windows 7 0.0.0): Executed 2 of 2 (1 FAILED) (0.026 secs / 0.013 secs)
這個過程的配置信息較爲複雜,須要耐心檢查錯誤。