iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Modern Web

Angular TDD (Test-driven development ) 從0到1系列 第 6

Angular TDD 測試從0到1: Day 6 Jasmine 介紹

  • 分享至 

  • xImage
  •  

當建立新的Angular專案時,已內建spec檔案,內容會長這樣:

describe('Test Suite 測項大類描述', () => {
  // lifecycle 測試的生命週期之一
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    });
  });

  it('Test case 測試案例的描述', async(() => {
    let fixture = TestBed.createComponent(AppComponent);
    let app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
});
  • describe: 是測試集合 (Test Suite),可控制測試程式碼的生命週期(lifecycle),如:line 3 beforeEach() (後面會繼續介紹),能夠包含多個測試案例,如:line 11 ~ line 15,每個spec檔案中至少會有一個測試集合。

  • TestBed: 是Angular預設的測試工具,來建立@NgModule,透過configureTestingModule,可以在測試前配置測試所需的component, service, module..,模擬測試情境。

TestBed.configureTestingModule({
    // 元件
    declarations: [ AppComponent ],
    
    // service
    providers: [ AppService ],
    
    // 模組
    imports: [ FormsModule ]
  }).compileComponents();
  • it: 是測試案例 (Test Case),測試的基本單位,可包含多個expect,如:line 14。通常測試集合(describe)會有一個或多個測試案例(it)。

多個的話,會長這樣:

describe('第一個測試集合描述', () => {
  describe('第二個測試集合描述', () => {
      describe('第三個測試集合描述', () => {
          it('Test case 測試案例(1) 的描述', async(() => {}));
          it('Test case 測試案例(2) 的描述', async(() => {}));
      });
  });
});
  • Expectations: 預期結果,如:line 14 -> expect(app).toBeTruthy();預期app是否為true

  • Matchers: 判斷預期的結果是否符合,如 line 14 -> toBeTruthy() 是否為true

  • fixture: 用來處理瀏覽器上的DOM元素,測試component,如下方line 6 ~ line 7,透過fixture調用DOM上的元素,取得元素後判斷其結果。

it(`HTML should have FAKE_NAME in li`, () => {
    const fakeNames = [{ name: 'FAKE_NAME' }];
    spyOn(appService, 'getNames').and.returnValue(of(fakeNames));
    component.ngOnInit();
    fixture.detectChanges();
    const el = fixture.debugElement.query(By.css('li')).nativeElement;
    expect(el.textContent).toEqual('FAKE_NAME');
});

常見的Matchers

  • expect(result).not(actual result); result和實際結果不同的話,pass
  • expect(result).toEqual(actual result); result和實際結果相同,pass,等同於判斷 ==
  • expect(result).toBe(actual result); result和實際結果的對象相同,pass,等同於判斷 ===
  • expect(result).toMatch(pattern); 當result符合pattern,pass
  • expect(result).toBeDefined(); result不是undefined,pass
  • expect(result).toBeUndefined(); result是undefined,pass
  • expect(result).toBeNull(); result是null,pass
  • expect(result).toBeNaN(); result是是否為NaN(not a number)
  • expect(result).toBeTruthactual result(); 判斷 result是否為true
  • expect(result).toBeFalsactual result(); 判斷 result是否為false
  • expect(result).toBeLessThan(actual result); 判斷result是否小於actual result
  • expect(result).toBeGreaterThan(actual result); 判斷result是否大於actual result

更多 Jasmine Matcher,可參考官網

Lifecycle 生命週期 又指作用範圍(Scoping)

前面提到describe中可以設定測試的生命週期,像是beforeEach(),表示在每個測試案例(it)
之前要執行xxx事情。共有4個生命週期如下:

  • beforeAll: 在所有describe(Test Suite)之前,==只會==執行一次裡面的測試。
  • beforeEach: 在每個it(Test Case)測試前,==都==會執行一次裡面的測試。
  • afterAll: 在結束所有describe(Test Suite)後,==只會==執行一次裡面的測試。
  • afterEach: 在每個it(Test Case)測試後,==都==會執行一次裡面的測試。

順序會長這樣:

describe('Test Suite 測項大類描述', () => {
  // 在所有describe(Test Suite)之前,only run once
  beforeAll(() => {
    // test sth...
  });
  
  // 在結束所有describe(Test Suite)後,only run once
  afterAll(() => {
    // test sth...
  });

  // 在每個it(Test Case)測試前, before the test cases, run every time
  beforeEach(() => {
    // test sth...
  });

  it('Test case 測試案例的描述', () => {
    // test sth...
  });
  
  // 在每個it(Test Case)測試後,after the test cases, run every time
  afterEach(() => {
    // test sth...
  });
});

內容參考來源:

對Karma和茉莉認識後,開始動手做吧!
下一篇開始建立測試環境~


上一篇
Angular TDD 測試從0到1: Day 5 Karma 介紹
下一篇
Angular TDD 測試從0到1: Day 7 跑第一個測試
系列文
Angular TDD (Test-driven development ) 從0到130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言