我們只看測試,所以[S03E03] ngx-translate就跳過去囉
https://www.youtube.com/watch?v=l_eA6ti41ww&list=PL9LUW6O9WZqgUMHwDsKQf3prtqVvjGZ6S&index=41
ngx-translate在2019年的Angular Taiwan社群小聚有再分享,請參考Neil Sie大大的影片
https://www.facebook.com/ming.little.14/videos/2563679736986300/
所有程式碼都寫在
https://github.com/oomusou/NG43ATDDSelect
文章在dropbox
https://paper.dropbox.com/doc/Event-Binding-22-3I4TFShvLoxwwxtPSH9s0
由於SAM大大的文章寫得很清楚了,我沒必要再加註解了(畫蛇添足),很建議大家閱讀
我覺得e2e比單元測試難多了,因為要能把使用者用瀏覽器操作的行為,用程式碼寫出來
1、用selector找到element
2、操作element,例如:click(),模擬使用者點了一下
3、如果api是return promise物件,可能還要用await、async去等
驗收測試 整合測試 單元測試
Acceptance Test Failed -> Integration Test Failed -> Unit Test Failed
^ |
|Refactoring V
Acceptance Test Passed <- Integration Test Passed <- Unit Test Passed
Protractor
Jasmine
Karma
Wallaby.js,可以即時看紅燈、綠燈(要錢的),我也沒買
延伸閱讀:
https://dotblogs.com.tw/technicaldebt/2017/12/25/104427
https://poychang.github.io/wallaby-js-advanced-logging/
SAM大大會從
驗收測試(紅燈)->整合測試(紅燈)->單元測試(紅燈)
再從
單元測試(綠燈)->…寫回驗收測試(綠燈)
整段用簡單的下拉式選單,來示範ATTD,配合著dropbox的文章看很好理解
3
個選項AWS
時,下方應該出現 0
Azure
時,下方應該出現 1
Aliyun
時,下方應該出現 2
e2e/ // 驗收測試 寫在專案的這個目錄
app.e2e-spec.ts // 寫測試案例的地方
app.po.ts // 把css跟測試案例解耦合
tsconfig.e2e.json // 設定使用的測試框架
整合測試 在驗證template(html)的各種binding(data binding、event binding、property binding)
整合測試、單元測試都寫在/src/app/底下的各components的spec.ts檔裡
/src/app/app.component.spec.ts
測試案例
<select>
的 change
event,應該呼叫 onChange()
selectedId
field describe(`Integration Test`, () => {
it(`should use 'onChange()' on 'change' event in HTML`, () => {
spyOn(component, 'onChange');
debugElement.query(By.css('#TDDSelect')).triggerEventHandler('change', null);
expect(component.onChange).toHaveBeenCalled();
});
it(`should use 'selectedId' in HTML`, () => {
component.selectedId = '0';
^^^^^^^^整合測試用component
htmlElement = debugElement.query(By.css('p')).nativeElement;
expect(htmlElement.textContent).toBe('0');
});
});
測class
一樣寫在/src/app/底下的各components的spec.ts檔裡,但至少要另外寫一個describe(),目的不同
把class跟template(html)binding分開,以後重構class,才不會跟template有牽連
/src/app/app.component.spec.ts
測試案例
onChange()
使 selectedId
field 根據參數值改變在寫單元測試的時候,就要想class
要怎麼寫了
describe(`Unit Test`, () => {
it(`should have 'onChange()' to make 'selectedId' as selected value in Class`, () => {
const stub = <HTMLSelectElement> {'value': '1'};
^^^^Object轉型為HTMLSelectElement ^^^^^^先塞假資料
target.onChange(stub); // onChange還沒實作,目前還是(紅燈)
^^^^^ 單元測試在用的變數
expect(target.selectedId).toBe('1');
});
上面測試案例都寫完之後,再來就是從
單元測試
開始依照測試案例
開始實作
當測試寫完後,感覺實作會更明確,更快。
當然這只是一個下拉式選單,如果頁面較複雜不知道會怎麼樣
不過實測試能寫到什麼程度,就測到
實作class(app.component.ts)
實作template(html)上的各種binding
以上就實作完了
模擬使用者對瀏覽器的操作
例如:
*ngFor
先寫完整合測試(畫面要看到什麼、當使用者的操作時會有什麼結果…)
再拆解成整合測試,單元測試
使用者一直改需求,測試不是也要改?
沒導入測試,手動測試更花時間 > 修改測試案例的時間
有測試,可減少開瀏覽器測試的時間,專心coding
(排版還是得開瀏覽器、功能面就不需要開瀏覽器)
用Reactive Form會比較好寫測試
e2e的驗收測試不難寫,難在怎麼用selector找到要抓element
單元測試也不難寫,只是測class裡的function、變數
整合測試較難寫,測html各種binding,比較不直覺。需要獨特技巧
官網docs的testing要看細一點,內含需多測試技巧(但只適用Angular)
https://angular.io/guide/testing
TestBed()已幫我們降低「component跟html的關係」的難度
整合測試需要fixture.detectChanges()
,但單元測試不用
整合測試需要把model更新到view