讓 TypeScript 也能 Alive

很羨慕 Visual Studio 有 Alive 可以即時跑單元測試嗎?只要安裝了 Wallaby,在 Visual Studio Code 也可以如 Alive 一樣為 Angular 即時跑 TypeScript 與 Jasmine 單元測試。

Version


Angular CLI 1.1.2
Angular 4.2.3
Wallaby 1.0.52
Visual Studio Code 1.14.0

安裝 Wallaby


vscode000

  1. 按左側 Extension 按鈕。
  2. 搜尋 Wallaby
  3. 安裝 Wallaby.js

vscode001

Visual Studio Code 關閉重新啟動後,會開始下載 Wallaby.js core

設定 Angular CLI


新增 wallaby.js

wallaby.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
var wallabyWebpack = require('wallaby-webpack');
var path = require('path');

var compilerOptions = Object.assign(
require('./tsconfig.json').compilerOptions,
require('./src/tsconfig.spec.json').compilerOptions);

module.exports = function (wallaby) {

var webpackPostprocessor = wallabyWebpack({
entryPatterns: [
'src/wallabyTest.js',
'src/**/*spec.js'
],

module: {
loaders: [
{test: /\.css$/, loader: 'raw-loader'},
{test: /\.html$/, loader: 'raw-loader'},
{test: /\.ts$/, loader: '@ngtools/webpack', include: /node_modules/, query: {tsConfigPath: 'tsconfig.json'}},
{test: /\.js$/, loader: 'angular2-template-loader', exclude: /node_modules/},
{test: /\.json$/, loader: 'json-loader'},
{test: /\.styl$/, loaders: ['raw-loader', 'stylus-loader']},
{test: /\.less$/, loaders: ['raw-loader', 'less-loader']},
{test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'sass-loader']},
{test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}
]
},

resolve: {
extensions: ['.js', '.ts'],
modules: [
path.join(wallaby.projectCacheDir, 'src/app'),
path.join(wallaby.projectCacheDir, 'src')
]
}
});

return {
files: [
{pattern: 'src/**/*.ts', load: false},
{pattern: 'src/**/*.d.ts', ignore: true},
{pattern: 'src/**/*.css', load: false},
{pattern: 'src/**/*.less', load: false},
{pattern: 'src/**/*.scss', load: false},
{pattern: 'src/**/*.sass', load: false},
{pattern: 'src/**/*.styl', load: false},
{pattern: 'src/**/*.html', load: false},
{pattern: 'src/**/*.json', load: false},
{pattern: 'src/**/*spec.ts', ignore: true}
],

tests: [
{pattern: 'src/**/*spec.ts', load: false}
],

testFramework: 'jasmine',

compilers: {
'**/*.ts': wallaby.compilers.typeScript(compilerOptions)
},

middleware: function (app, express) {
var path = require('path');
app.use('/favicon.ico', express.static(path.join(__dirname, 'src/favicon.ico')));
app.use('/assets', express.static(path.join(__dirname, 'src/assets')));
},

env: {
kind: 'electron'
},

postprocessor: webpackPostprocessor,

setup: function () {
window.__moduleBundler.loadTests();
},

debug: true
};
};

在專案的根目錄下新增 wallaby.js

vscode002

注意 wallaby.js 為 JavaScript 檔,不是 TypeScript 檔。

新增 src/wallabyTest.ts

src/wallabyTest.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import './polyfills';

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 } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);

src 目錄下新增 wallabyTest.ts

vscode003

注意 wallabyTest.ts 為 TypeScript 檔,不是 JavaScript 檔。

src/tsconfig.app.json

src/tsconfig.app.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "",
"types": []
}
,

"exclude": [
"test.ts",
"**/*.spec.ts",
"wallabyTest.ts"
]
}

12 行

1
"wallabyTest.ts"

新增 "wallabyTest.ts"

vscode004

安裝 Node.js 套件

1
~/MyProject$ npm install wallaby-webpack angular2-template-loader electron --save-dev

安裝 Wallaby 所需要的 Node.js 套件。

vscode005

執行 Wallaby


  • Start:⌘ + ⇧ + R, R
  • Stop:⌘ + ⇧ + R, S

vscode006

第一次執行時,會要求設定 config file。

vscode007

選擇剛剛在根目錄建立的 wallaby.js

vscode008

通過測試的案例,左側會出現綠燈,下方也會顯示目前通過測試案例的個數。

vscode009

不用按存檔就可以立即跑測試顯示紅燈綠燈,且立刻顯示實際值與期望值的差異。

顯示 Code Coverage


寫單元測試的另外ㄧ件重大的事情,就是關心 code coverage 是否達到團隊目標。Wallaby 提供了 Wallaby App,只要輸入 http://wallabyjs.com/app,就可以顯示目前整個專案的 code coverage 狀況。

不用擔心 http://wallabyjs.com/app 是連到外面,事實上它相當於 http://localhost:51245,還是跑在本機。

vscode010

  1. App 目錄顯示整個專案的 code coverage。
  2. 也可以顯示單一檔案的 code coverage。

Wallaby App 可貴的地方在於他不是靜態 HTML report,而是隨著測試結果自動改變,隨時顯示最新的 code coverage。

Conclusion


  • Wallaby 有各種版本,如 Visual Studio、WebStorm,甚至於 Sublime Text 與 Atom 也有支援。
  • Wallaby 雖然是個付費軟體,但非常有其價值。
  • TDD 會讓開發變慢,主要是因為工具不夠方便,Wallaby 讓我們寫單元測試的同時,就即時知道紅燈綠燈測試結果,將大幅提升 TDD 開發效率。

Reference


Wallaby.js Blog, Wallaby.js for Visual Studio Code
Wallaby, Angular.js 2 angular-cli (Webpack) generated project