ng test and ng e2e

2 분 소요

ng test와 ng e2e 적용 방법과 차이점을 알아봅시다.

ng test

  • jasmine, karma
  • browser에 표시되는 데이터의 결과까지 포함합니다.
  • component와 service를 모두 테스트 가능합니다.
  • native javascript 코딩방식으로 querySelector를 활용하는 것이 편합니다.

(업데이트)

  • 로컬에서 수행되는 테스트이므로, 실 테스트에 부적합합니다.
  • 단, service 단위까지 테스트 가능하므로 Unit Test 단위 테스트에 적합합니다.
  • 즉, 함수 단위의 테스트로 활용하는 것이 좋습니다.

적용 방법

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from '../app/app.component';
describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
  it('app component를 생성합니다.', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
  it(`타이틀은 'app title' 입니다.`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app title');
  }));
  it(`'컨텐츠는 'app content' 입니다.`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const app = fixture.debugElement.componentInstance;
    expect(app.content).toEqual('app content');
  }));
  it(`h1 태그에 들어갈 제목은 'Welcome to app title' 입니다.`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to app title!');
  }));
  it(`로그인 정보를 입력합니다`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    // fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('input#email').value = 'test@test.com';
    compiled.querySelector('input#password').value = 'password';
    compiled.querySelector('button.btn').click();
  }));
});

ng e2e

  • jasmine, protractor
  • 터미널에만 결과를 표시합니다.
  • dom에 접근하여 테스트 하므로 service의 DI 테스트가 불가합니다.
  • typescript 코딩이 일부 들어가므로 별도의 개발이 될 수 있습니다.
  • protractor에서 $를 elementFinder로 사용할 수 있는데 이는 jQuery처럼 $(element) 형태로 부를 수 있습니다.
  • 보다 정교하게 테스트 코드를 구성할 수 있습니다.
    • *.po.ts 파일에 service 처럼 테스트할 값을 return 하는 함수를 만들고,
    • e2e-spec.ts 파일에는 *.po.ts의 함수의 결과를 기록합니다.

(업데이트)

  • 실제 브라우저에서 수행되는 테스트이므로, 실 테스트에 적합합니다.
  • 브라우저 DOM 단위의 테스트로 활용 가능하므로 QA 용으로 적합합니다.

적용 방법

  • app.po.ts
import { browser, by, element, $ } from 'protractor';

export class AppPage {
  navigateTo() {
    return browser.get('/');
  }

  // getParagraphText() {
  //   return element(by.css('app-root h1')).getText();
  // }
  getTitle() {
    return $('h1').getText();
  }
  getContent() {
    return $('h3').getText();
  }
  loginTest() {
    $('input#email').sendKeys('test@test.com');
    $('input#password').sendKeys('password');
    $('button.btn').click();
  }
}
  • app.e2e-spec.ts
import { AppPage } from './app.po';

describe('workspace-project App', () => {
  let page: AppPage;

  beforeEach(() => {
    page = new AppPage();
  });

  it('제목 표시 여부', () => {
    page.navigateTo();
    expect(page.getTitle()).toEqual('Welcome to app title!');
  });
  it('로그인', () => {
    page.navigateTo();
    expect(page.loginTest());
  });
});

총평

  • e2e테스트는 내부 테스트로 구성하고, test는 외부 테스트용으로 구성하면 베스트이겠으나 중복 테스트가 될 가능성이 있습니다.
  • test는 service까지 테스트가 가능하므로 test가 유용하다고 보이나 구조는 e2e가 뛰어나므로 고민이 필요합니다.

참고 사이트

댓글남기기