Angular Testing 筆記 --- 2 測試程式的架構邏輯 Jasmine

Jasmine:

上一章節我們有大致介紹了一下Jasmine這個用來 Behaviour Driven Development (BDD)的Library,一般來說BDD會用比較喜歡口語的描述來撰寫測試,一來比容易閱讀,二來就算是非技術人員也能容易了解『這個測試在測什麼!』

下方是我們要測試的function
function helloWorld() { return 'Hello World'; }

接著是我們的測試程式碼:
describe('Hello World', () => { it('show hello world', () => { expect(helloWorld()).toEqual('Hello World'); }); });


  1. 從測試程式碼中可以看到 describe(string, function);  這個開頭。 後方的 function 這是Test Suite 裡面會有許多我們的關於 string (Hello World)的獨立單元測試,所以可說function是單元測試的集合。

  2. it(string, function) 這個定義了我們每一個獨立的單元測試,這會包含一個或是多個的Expectation(期望)。

  3. expect(actual) 這個描述我們稱之為 Expectation (期望)後方會接著呼應的結果(Matcher)來描述我們這個測試『期望的結果』是如何,通常這個matcher(expected)的描述就是我們說的呼應結果(Matcher)其值為boolean。

  4. 期待值(expected)與實際值(actual value)被丟到expect這個function內做比較,如果出來的值為false就代表這個測試失敗


所以上述的那段測試碼就是說:這一段是做 Hello World的相關測試,然後 show hello world 這個單元測試就是~期望(expect)helloWorld()這個function 會等於(toEqual)  'Hello World'這個字串。

我們把這些程式碼寫在 Angular 的一個新專案的 app.component.spec.ts 的內,但是在最下方並且 angular 內寫的 describe() 之外,最後執行在 ng cli 下執行  # ng test 來看看測試結果。


我們可以看到第二個小標題 " Hello World "就是我們 describe( string, function)string說明內容。而內容的show hello world就是我們寫在 it(string, function) 的string 說明。

現在我們故意把 expect(helloWorld()).toEqual('Hello World') 改成 expect(helloWorld()).toEqual('angular') 存檔之後 ng cli的測試會自動重新跑一次測試,這時候就會看到失敗的資訊了。


從程式碼中我們期待要等於"angular"這個字串,但是實際結果卻是失敗。因此會看到頁面顯示4個測試中(specs 包含angular 建立專案時自動幫你寫好的測試內容) 有 1 個 failure。

至於expect 後方的Matchers 除了目前看到的 toEqual() 之外 Jasmine 提供了許多 Matchers給我們,以下是我大概列舉的。更多的請上Jasmine官網參考。

  • toContain(number)
  • toThrow(string)
  • toBe(instance)
  • toBeFalsy()
  • toBeTruthy()
  • toEqual(mixed)
  • toMatch(pattern)
  • toBeGreaterThan(number);
  • toBeNaN();

有時候在測試某些功能時我們會預先建立一些物件、服務之類的或是在單元測試結束後要求清除一些檔案或是變數因此Jasmine提供了下列幾個特殊Function供我們測試時做『預處理』或是『後處理』。


beforeAll

這個function只會在describe()內的所有測試之前被呼叫一次


afterAll

這個function會在所有describe() 都做完之後被呼叫一次


beforeEach

這個function會在每一個 it function執行之前被執行


afterEach

這個function會在每一個單元測試後被呼叫。


我們來看一下 Angular 建立專案時幫我們事先寫好的測試碼
describe('AppComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ RouterTestingModule ], declarations: [ AppComponent ], }).compileComponents(); }));
it('should create the app', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); });

上方第2行的 beforeEach() 這段就會在下方每個 it(function) 執行之前被呼叫。

這邊就大概講解Jasmine 測試程式的邏輯架構。------ 待續


2019-01-07 補充:

忽略某些測試的方法

如果想要 Jasmine 在測試的時候忽略某些已經寫好的測試碼時,除了註解掉之外另外一種就是在 describe() 或是 it() 的前面加上 'x' 也就是變成 xdescribe() 或是 xit() 。這樣 Jasmine 一樣會列出這些測試的名稱但是不會真的進行測試,而且結果的圈圈會打上灰色的圓圈

專注某些測試

同樣專注某些測試的方法就是在 describe() 與 it() 前面加上 'f' ,這樣在測試結果的 report 中會把這些需要專注的測試清單列在最前面,連同失敗或是成功的綠色圈圈也會被列在最前方

REF:

留言