讓 TypeScript 也能 Alive

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

Version


Angular CLI 1.1.2
Angular 4.2.3
Wallaby 1.0.92

下載 Wallaby


wallaby000

到 Wallaby.js 官網 https://wallabyjs.com,選擇 WebStorm 版本下載。

安裝 Wallaby

wallaby001

WebStorm -> Preferences -> Plugins

Install plugin from disk…

wallaby002

選擇剛剛由 Wallaby.js 官網下載的 zip 檔。

若由 Safari 下載,zip 檔已經被解開,可選擇解開後的 jar 檔。

wallaby003

  1. 安裝成功後會出現 Wallaby
  2. Restart WebStorm 才能使用。

wallaby004

WebStorm 重新啟動後,右下角會出現 Wallaby License 提示,表示已經安裝成功。

Trial versions available for download are fully functional and should work for 30 days. Note that in the trial mode wallaby will sometimes prompt you to restart your editor to get another trial session.

根據 Wallaby 官網說明,可試用 30 天,在試用過程中,偶爾會提示你重新啟動 WebStorm。

設定 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

wallaby005

注意 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

wallaby006

注意 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"

wallaby007

安裝 Node.js 套件

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

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

wallaby008

設定 WebStorm

wallaby009

Run -> Edit Configurations…

wallaby010

  1. 按左上角 +
  2. 選擇 Wallaby.js

wallaby011

  1. Name : 取名為 Wallaby
  2. Configuration file:設定為剛剛在根目錄建立的 wallaby.js

執行 Wallaby

wallaby012

上方選擇 Wallaby,按下右邊的綠色三角形執行 Wallaby。

wallaby013

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

wallaby014

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

Conclusion


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

Reference


Wallaby, Angular.js 2 angular-cli (Webpack) generated project
CK’s Notepad, [Angular] 學習筆記(1) - Techniques and practices for testing Angular 2
Techniques and practices for testing Angular 2 | Identity Server 4 with Angular 2 ASP.NET core