ng test and ng e2e

2 분 소요

Let’s explore how to apply ng test and ng e2e, as well as their differences.

ng test

Purpose: It verifies the internal logic and dependency injection (DI) of individual components, services, pipes, etc.

  • Uses Jasmine and Karma.
  • Includes the results of data displayed in the browser.
  • Can test both components and services.
  • It’s convenient to use native JavaScript methods like querySelector.

(Update)

  • Since it runs locally, it may not be suitable for real-world testing.
  • It is ideal for unit testing, as it can test up to the service level.
  • By using Mocking and HttpTestingController, external dependencies can be isolated, improving unit test reliability.
  • Asynchronous processing: Use Angular’s async, fakeAsync, and tick appropriately to verify asynchronous logic.
  • It is best used for function-level testing.

Implementation

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from '../app/app.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [AppComponent],
    }).compileComponents();
  }));

  it('should create the app component', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));

  it(`should have the title 'app title'`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app title');
  }));

  it(`should have content 'app content'`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const app = fixture.debugElement.componentInstance;
    expect(app.content).toEqual('app content');
  }));

  it(`should display title 'Welcome to app title' in an h1 tag`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to app title!');
  }));

  it(`should enter login information`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    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

  • Uses Jasmine and Protractor.
  • Displays results only in the terminal.
  • Since it accesses the DOM, it cannot test the service DI.
  • It involves some TypeScript coding, which may require additional development.
  • Protractor allows using $ as elementFinder, similar to jQuery ($(element)).
  • Enables more fine-grained test code configuration:
    • You can create a .po.ts file that returns test values like a service.
    • The .e2e-spec.ts file then records the results from the .po.ts file.

(Update)

  • Since it runs in a real browser, it is suitable for real-world testing.
  • It is ideal for QA testing, as it can verify browser DOM interactions.
  • From Angular 12 onwards, Protractor is officially deprecated, and no longer receives updates.

Implementation

app.po.ts

import { browser, by, element, $ } from 'protractor';

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

  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('should display the title', () => {
    page.navigateTo();
    expect(page.getTitle()).toEqual('Welcome to app title!');
  });

  it('should log in', () => {
    page.navigateTo();
    expect(page.loginTest());
  });
});

Final Thoughts

  • Ideally, e2e testing should be used for internal testing, while unit testing should be used for external validation. However, this may lead to test duplication.
  • ng test is useful since it can test services, but ng e2e has a better structure, requiring careful consideration of their use cases.

References

댓글남기기