1. 程式人生 > >Angular單元測試與整合測試

Angular單元測試與整合測試

使用Angular CLI建立的App已配置好測試環境,生成了測試配置檔案和樣例程式碼。預設,Angular單元測試使用Jasmine測試框架和Karma測試執行器,整合測試使用Jasmine測試框架和Protractor end-to-end 測試框架。

單元測試

Jasmine是一個用於測試JavaScript的行為驅動開發框架,不依賴於任何其他JavaScript框架。
Karma是測試執行器,為開發人員提供了高效的、真實的測試環境,支援多種瀏覽器,易於除錯。

配置檔案

單元測試配置檔案test.ts和karma.conf.js:
test.ts

import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

declare const require: any;

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

測試副檔名必須為.spec.ts。
karma.conf.js

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, '../coverage'),
      reports: ['html', 'lcovonly'],
      fixWebpackSourcePaths: true
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};

預設使用Chrome瀏覽器,可生成單元測試報告和覆蓋率報告,覆蓋率報告儲存在根目錄coverage資料夾內,啟用autoWatch。
singleRun預設為false,如設為true則測試結束後會自動退出並根據測試結果返回程式碼0或1,常用於CI環境。

瀏覽器配置

Karma支援的瀏覽器:

  • Chrome
  • ChromeCanary
  • ChromeHeadless
  • PhantomJS
  • Firefox
  • Opera
  • IE
  • Safari

可同時配置多個瀏覽器進行測試,要啟用其他瀏覽器,需安裝依賴,比如啟用Firefox:

npm install karma-firefox-launcher --save-dev

然後在karma.conf.js內增加配置:

...
require('karma-chrome-launcher'),
require('karma-firefox-launcher'),
...
browsers: ['Chrome', 'Firefox'],
...

執行測試

使用CLI建立App生成了一個單元測試檔案app.component.spec.ts。執行CLI命令 ng test 即可執行單元測試:

ng test

在控制檯會輸出測試結果,還會開啟瀏覽器:
Angular單元測試與整合測試
瀏覽器會顯示測試結果,總測試數,失敗數。在頂部,每個點或叉對應一個測試用例,點表示成功,叉表示失敗,滑鼠移到點或叉上會顯示測試資訊。點選測試結果中的某一行,可重新執行某個或某組(測試套件)測試。

常用引數:
--browsers 指定使用的瀏覽器
--code-coverage 輸出覆蓋率報告
--code-coverage-exclude 排除檔案或路徑
--karma-config 指定Karma配置檔案
--prod 啟用production環境
--progress 預設為true,在構建時將進度輸出到控制檯
--watch 預設為true,程式碼修改後會重新執行測試

自定義Launcher

karma-chrome-launcher、karma-firefox-launcher、karma-ie-launcher等均支援自定義Launcher,customLaunchers與--browsers結合使用可滿足多種環境的測試需求。每種瀏覽器支援的自定義屬性請檢視Karma Browsers文件。
比如,CI環境下常用Headless模式,不必使用瀏覽器介面,karma.conf.js增加如下配置:

browsers: ['Chrome'],
customLaunchers: {
  ChromeHeadlessCI: {
    base: 'ChromeHeadless',
    flags: ['--no-sandbox']
  }
},

執行如下命令進行測試:

ng test --watch=false --progress=false --browsers=ChromeHeadlessCI

測試覆蓋率

執行如下命令生成測試覆蓋率報告,報告儲存在專案根目錄下的coverage資料夾內:

ng test --watch=false --code-coverage

如想每次測試都生成報告,可修改CLI配置檔案angular.json:

"test": {
  "options": {
    "codeCoverage": true
  }
}

設定排除的檔案或路徑

ng test --watch=false --code-coverage --code-coverage-exclude=src/app/heroes/heroes.component.ts --code-coverage-exclude=src/app/hero-search/*

同樣可以在angular.json中配置:

"test": {
  "options": {
    "codeCoverage": true,
    "codeCoverageExclude": ["src/app/heroes/heroes.component.ts", "src/app/hero-search/*"]
  }
}

設定測試覆蓋率指標
編輯配置檔案karma.conf.js,增加如下內容:

coverageIstanbulReporter: {
  reports: [ 'html', 'lcovonly' ],
  fixWebpackSourcePaths: true,
  thresholds: {
    statements: 80,
    lines: 80,
    branches: 80,
    functions: 80
  }
}

測試報告中達到標準的背景為綠色。
Angular單元測試與整合測試
LCOV
coverageIstanbulReporter中reports引數為[ 'html', 'lcovonly' ],會生成html和lcov兩種格式的報告。報告檔案lcov.info可與Sonar整合,在Sonar管理介面配置LCOV Files路徑,即可在Sonar中檢視測試情況。
Angular單元測試與整合測試

編寫測試

待續...

整合測試

整合測試使用Jasmine和Protractor測試框架,Protractor是Angular端到端測試框架。

安裝Protractor

npm install -g protractor

在專案中執行npm install時會安裝protractor,不必單獨執行以上命令。安裝protractor後會安裝兩個命令列工具protractor和webdriver-manager(位於node_modules\protractor\bin目錄),webdriver-manager負責管理驅動、啟停Selenium Server。

webdriver-manager命令:

clean      removes all downloaded driver files from the out_dir
start      start up the selenium server
shutdown   shut down the selenium server
status     list the current available drivers
update     install or update selected binaries,更新的驅動儲存在node_modules\protractor\node_modules\webdriver-manager\selenium目錄下。
version    get the current version

配置檔案

使用CLI建立的App會生成一個e2e專案,其中包含測試配置protractor.conf.js及測試程式碼。
protractor.conf.js

const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {
  allScriptsTimeout: 11000,
  specs: [
    './src/**/*.e2e-spec.ts'
  ],
  capabilities: {
    'browserName': 'chrome'
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'jasmine',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    print: function() {}
  },
  onPrepare() {
    require('ts-node').register({
      project: require('path').join(__dirname, './tsconfig.e2e.json')
    });
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
  }
};

預設,Protractor使用Jasmine測試框架,使用直連方式連線Chrome瀏覽器,測試副檔名為.e2e-spec.ts。

瀏覽器配置

Protractor支援Chrome、Firefox、Safari、IE等瀏覽器。
多瀏覽器
Protractor可同時啟動多個瀏覽器,用一個瀏覽器時,在配置中使用capabilities選項;用多個瀏覽器時,使用multiCapabilities:

multiCapabilities: [{
  browserName: 'firefox'
}, {
  browserName: 'chrome'
}]

另外需在package.json中增加配置:

"scripts": {
  "webdriver-update": "webdriver-manager update"
}

在執行測試前執行:

npm run webdriver-update

否則專案中的驅動不會更新(預設只有chrome驅動,在命令列執行webdriver-manager update僅更新全域性的驅動),執行測試會報如下錯誤:

No update-config.json found. Run 'webdriver-manager update' to download binaries

瀏覽器選項

capabilities: {
  'browserName': 'chrome',
  'chromeOptions': {
    'args': ['show-fps-counter=true']
  }
},
capabilities: {
  'browserName': 'firefox',
  'moz:firefoxOptions': {
    'args': ['--safe-mode']
  }
},

更多選項請檢視相應驅動ChromeDriverGeckoDriver

Selenium Server配置

使用Standalone Selenium Server時,需安裝JDK。
更新driver後啟動Selenium Server:

webdriver-manager update
webdriver-manager start

刪除原配置中的directConnect、baseUrl:

directConnect: true,
baseUrl: 'http://localhost:4200/',

增加seleniumAddress(預設為http://localhost:4444/wd/hub):

seleniumAddress: 'http://localhost:4444/wd/hub',

執行測試

執行CLI命令 ng e2e即可執行整合測試:

ng e2e

常用引數:

--base-url  Base URL for protractor to connect to.
--configuration (-c)  A named configuration environment, as specified in the "configurations" section of angular.json.
--host  Host to listen on.
--port  The port to use to serve the application.
--prod  When true, sets the build configuration to the production environment.
--protractor-config  The name of the Protractor configuration file.
--webdriver-update  Try to update webdriver.

指定配置檔案

不同的環境若配置不同,可使用不同的配置檔案。

比如,在CI環境中啟用Chrome Headless模式:
在e2e根目錄下建立一名為protractor-ci.conf.js的新檔案,內容如下:

const config = require('./protractor.conf').config;

config.capabilities = {
  browserName: 'chrome',
  chromeOptions: {
    args: ['--headless', '--no-sandbox']
  }
};

exports.config = config;

注意: windows系統要增加引數--disable-gpu

執行以下命令測試:

ng e2e --protractor-config=e2e\protractor-ci.conf.js

編寫測試

待續...

參考資料

Jasmine Behavior-Driven JavaScript
Karma
Protractor - end-to-end testing for Angular