开发模式转变:(以前)需求 -> 开发 , (现在)测试 -> 开发 至于测试的作用,可看这里:Angular测试入门
这篇文章主要为Angular的单元测试做准备:测试环境的搭建。
涉及到的框架:
Jasmine,Karma,protractor
; 脚手架: Angular CLI,Ionic CLI
。 在这里默认你已经安装了
Angular CLI
,如果没有安装,可参考这里:CLI QUICKSTART以一个项目为例,所以要先创建一个测试项目:
ng new angular-test
创建成功后,这个项目里已经帮助你安装好了测试环境,你只需进入当前项目:cd angular-test
别忘了安装依赖模块: npm install
接下来: npm test
当测试跑起来时,会自动打开一个记录测试的页面,如下图:

上面就是最简单的测试环境搭建,当然,还有一些项目是需要一步步去搭建测试环境,比如使用Ionic2或Ionic3时,Ionic CLI脚手架默认是不会给你安装测试环境,所以需要我们完整搭建。下面就来看看如何搭建!
这里以Ionic为例,也默认你已经安装了Ionic环境了,如果没有安装,可以看这里: Ionic CLI
创建一个基本的Ionic项目:
ionic start ionic-test --v2
接下来基于ionic-test项目来搭建测试环境。
首先安装
Karma
: npm install -g karma
然后进入项目: cd ionic-test
安装需要的模块,耐心逐一安装: npm install @angular/cli --save-dev
npm install codelyzer --save-dev
npm install jasmine-core --save-dev
npm install jasmine-spec-reporter --save-dev
npm install karma --save-dev
npm install karma-cli --save-dev
npm install karma-chrome-launcher --save-dev
npm install karma-jasmine --save-dev
npm install karma-jasmine-html-reporter --save-dev
npm install karma-coverage-istanbul-reporter --save-dev
npm install ts-node --save-dev
npm install tslint --save-dev
npm install tslint-eslint-rules --save-dev
npm install @types/jasmine --save-dev
npm install @types/node --save-dev
当然,你也可以将这些模块添加到package.json
文件中,然后执行npm install
来下载。初始化
Karma
配置: karma init karma.conf.js
如果看不懂,一直Enter下去就行了。 你会看到ionic-test里多了一个
karma.conf.js
文件,接着用下来的内容替换: module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular/cli/plugins/karma')
],
client:{
clearContext: false
},
files: [
{ pattern: './src/test.ts', watched: false }
],
preprocessors: {
'./src/test.ts': ['@angular/cli']
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
config: './.angular-cli.json',
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
再创建配置文件
ionic-test/.angular-cli.json
,添加如下内容: {
"project": {
"version": "1.0.0",
"name": "ionic-test"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets"
],
"index": "index.html",
"main": "./app/main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.spec.json",
"prefix": "app",
"mobile": false,
"styles": [
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}],
"addons": [],
"packages": [],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"prefixInterfaces": false,
"inline": {
"style": false,
"template": false
},
"spec": {
"class": false,
"component": true,
"directive": true,
"module": false,
"pipe": true,
"service": true
}
}
}
接着在
src
文件夹下创建一个名为environments
文件夹, 然后创建一个文件: src/environments/environment.prod.ts
:export const environment: any = {
production: true,
};
再新建src/environments/environment.ts
:export const environment: any = {
production: false,
};
接着创建src/polyfills.ts
: import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
然后创建测试入口文件
src/test.ts
: import './polyfills.ts';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function (): void {
// noop
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
let context: any = require.context('./', true, /\.spec\.ts/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();
最后创建一个测试的配置文件src/tsconfig.spec.json
:
{
"compilerOptions": {
"baseUrl": "",
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}
到这里,是不是看得晕乎乎的了,还没有完,还差最后一步,在
package.json
的scripts
中添加: "test": "ng test"
呼呼,终于可以和用
Angular CLI
安装的项目一样测试了: npm test
如下图:
问题集:
(1) 问题一:
ERROR in Could not resolve module @angular/router
由于用的是Angular4
,它将路由模块分离了出来, 安装即可: npm install @angular/router
(2) 问题二:
Uncaught TypeError: Cannot read property 'apply' of undefined
at http://localhost:9877webpack:///~/zone.js/dist/zone.js:1265:0 <- src/test.ts:123628
将zone.js更新:npm install zone.js@0.8.5
(3) 问题三
Uncaught Error: Zone already loaded.
注释或删除src/test.ts:
// import './polyfills.ts';
下一篇文章:基于Angular的单元测试:(二)测试实战
如发现有不对之处,欢迎指正!
参考资料: