### 常用語法
Lint a single file
Angular CLI v8
```DOS=
ng lint --files src/app/app.component.ts
```
Angular CLI v10.1.7+
```DOS=
ng lint --lint-file-patterns src/app/app.component.ts
```
在src下生成html測報
```DOS=
ng test --code-coverage
```
在src下生成html測報(指定路徑,好像不吃絕對路徑,所以先cd到專案目錄src所在層)
```DOS=
ng test --code-coverage --include src/unit/test.spec.ts
```
在src下生成html測報(指定路徑,CLI v9↓)
```DOS=
ng test --main src/unit/test.spec.ts
```
*排除指定路徑則用-exclude
*預設–watch為true會在code修改後自動觸發一輪測試
斷點測試流程:
1. ng test
2. 跳出的瀏覽器頁面點debug按鈕
3. F12 → cmd+p → 找要測的component及其spec → 設定好想要的斷點
4. 5F
**ng test通常是一個對應compenent的spec.ts檔案**
```javascript=
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { BackupListComponent } from './backup-list.component';
import { DebugElement } from '@angular/core';
describe('HorizontalGridComponent test', () => {
let component: HorizontalGridComponent;
let fixture: ComponentFixture<HorizontalGridComponent>;
// 設定 TestBed 環境
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
declarations: [HorizontalGridComponent],
}).compileComponents();
}));
beforeEach(() => {
// new 你想要測的 Component
fixture = TestBed.createComponent(HorizontalGridComponent);
// 使用 fixture.componentInstance 扮演發動測試的角色
component = fixture.componentInstance;
// 使用 fixture.detectChanges() 偵測是否有變動被觸發
fixture.detectChanges();
});
it('should create', () => {
expect(fixture).toBeDefined();
expect(component).toBeDefined();
});
it('should have <h3> with "Hello"', () => {
// const El: HTMLElement = fixture.nativeElement;
const De: DebugElement = fixture.debugElement;
const El: HTMLElement = De.nativeElement; // nativeElement相當於debugElement的一個屬性
// js原生的querySelector api去獲取h3標籤
const p = El.querySelector('h3');
// 判斷h3標籤的內容
expect(p.textContent).toEqual('Hello');
});
it('should find the <h3> with fixture.debugElement.query(By.css)', () => {
const De: DebugElement = fixture.debugElement;
const El = De.query(By.css('h3')); // nativeElement相當於debugElement的一個屬性
// js原生的querySelector api去獲取h3標籤
const p: HTMLElement = El.nativeElement;
// 判斷h3標籤的內容
expect(p.textContent).toEqual('Hello');
});
afterEach(() => {
TestBed.resetTestingModule();
});
});
```
CLI 會產生 Jasmine 和 Karma 的設定檔,主要包括karma.conf.js和test.ts。
karma.conf.js設定環境,test.ts決定跑哪些script
**test.ts**
``` javascript=
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);
```
**karma.conf.js**
``` javascript=
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plug×××: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plug×××/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
});
};
```
### 常用Method
describe(string, function): Jasmine 的廣域函數,可以理解為一個測試組(Test Suite),用來劃分單元測試。
it(string, function):可以理解為測項。Specs 用 it 的廣域函數來定義。每個 Spec 包含一個或多個 expectations 期望值來測試。
Jasmine 中的每個 expectation 是一個斷言,可以是 true 或者 false。當每個 Spec 中的所有 expectations 都是 true,則通過測試。
beforeEach() 在 describe 函數中每個 Spec(it)執行之前執行。
afterEach() 在 describe 函數中每個 Spec(it)執行之後執行。
beforeAll() 在 describe 函數中所有的 Spec(it)執行之前執行一次。
afterAll() 在 describe 函數中所有的 Spec(it)執行之後執行一次。
xdescribe:跳過整個測試組
xit:跳過該 it
fdescribe 和 fit:只測試特定對象
spy:監測任何 function 的呼叫和參數的呼叫痕跡,不會影響函數真實返回值,配合 2 個特殊的 Matcher 如下
toHaveBeenCalled 可以檢查 function 是否被呼叫過
toHaveBeenCalledWith 可以檢查傳入參數是否被作為參數呼叫過
```Jacascript=
describe("spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
foo.setBar(123);
foo.setBar(456, 'another param');
});
it("追蹤函式呼叫情況", function() {
// 上面
了foo.setBar,所以返回true
expect(foo.setBar).toHaveBeenCalled();
// 上面呼叫了foo.setBar,並且傳入參數123,所以返回true
expect(foo.setBar).toHaveBeenCalledWith(456, 'another param');
// Spy的呼叫並不會影響真實的值,所以bar仍然是null。
expect(bar).toBeNull();
});
});
```
###### tags: `Angular`