首页 专题 H5案例 前端导航 UI框架

基于Angular的单元测试:(一)测试环境搭建

作者:TG 日期: 2017-05-02 阅读: 3306
一直以来都是拿到一个新项目,了解完整的需求后开发。现在公司要尝试新的开发模式,先写测试代码,再写开发代码。按个人理解,其实测试代码就是我们平时写的需求文档,只不过现在是以代码的方式来规范和要求。

开发模式转变:(以前)需求 -> 开发 , (现在)测试 -> 开发
至于测试的作用,可看这里: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.jsonscripts中添加:

"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的单元测试:(二)测试实战

如发现有不对之处,欢迎指正!

参考资料:


关注”全栈技术杂货铺“

全栈技术杂货铺