Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testgetriebene Entwicklung von Angular Apps (WJAX 2018)

Testgetriebene Entwicklung von Angular Apps (WJAX 2018)

In der Präsentation stellen wir einen Ansatz vor, wie Angular Anwendungen sehr gut testgetrieben entwickelt werden können. Dabei gehe ich auf die verschiedenen Testarten ein und wie innerhalb eines agilen Prozesses eine Story testgetrieben umgesetzt werden kann. Anschließend demonstriere ich den Entwicklungsprozess anhand eines kleinen Demo-Projekts.
Das Projekt zur Präsentation liegt auf GitHub (https://github.com/maimArt/tddangular). Dort sind die einzelnen Schritte innerhalb der Commits und des GitHub Projects dokumentiert.

4947df30a5d020bb9d4c054da69d9f2d?s=128

Martin Maier

November 06, 2018
Tweet

Transcript

  1. sogehtsoftware.de So geht Software. AGILE FRONTEND QA/TEST WEB TESTGETRIEBENE ENTWICKLUNG

    EINER ANGULAR APP
  2. IHR KONTAKT Twitter: E-Mail: sogehtsoftware.de Z Twitter: E-Mail: Z Martin

    Maier Senior Consultant Softwareentwicklung @_maimArt_ martin.maier@saxsys.de Manuel Mauky Lead Developer @manuel_mauky manuel.mauky@saxsys.de
  3. Seite sogehtsoftware.de Agenda TDD ANGULAR 3 1. Testdriven Development 2.

    Testarten 3. Entwicklungsprozess 4. Coding (TODO-Liste) 5. Systemintegrationstests
  4. sogehtsoftware.de TEST DRIVEN DEVELOPMENT 4

  5. Seite sogehtsoftware.de › Was versteht man unter testgetriebener Entwicklung? ›

    TDD Zyklus TEST DRIVEN DEVELOPMENT Bringe Unit Test zum laufen Refactor Schreibe Unit Test
  6. Seite sogehtsoftware.de 6 › Unzufrieden mit › Codequalität › Testabdeckung

    › Mit TDD erreichen wir › hohe Testabdeckung › gut designter, lesbaren Code › Entwicklung fokussieren › hohen Synergieeffekt mit Pair-Programming TEST DRIVEN DEVELOPMENT Warum TDD?
  7. sogehtsoftware.de TESTARTEN 7

  8. Seite sogehtsoftware.de 8 Systemtests Integrationstests Unit-Tests TESTARTEN Testpyramide Protractor E2E-Tests

    Protractor E2E-Tests Karma Unit-Tests
  9. Seite sogehtsoftware.de 9 TESTARTEN Testgrenzen Modul Angular App Komponente Service

    Komponente Modul Modul Mock externes System Browser Komponententest Schnittstellen Angular-Integrationstests System-Integrationstests
  10. sogehtsoftware.de ENTWICKLUNGSPROZESS 10

  11. Seite sogehtsoftware.de Agiler Entwicklungsprozess ENTWICKLUNGSPROZESS PLANNING REVIEW SPRINT BACKLOG PRODUCT

    BACKLOG SPRINT Product Owner Inkrement Team lauffähiger Produktbestandteil Ergebnisse des Planning-Meetings n-tägige Iterationsschleife Backlog Grooming
  12. Seite sogehtsoftware.de 12 Testgetriebene Story ENTWICKLUNGSPROZESS neue Story Spezifizierte Akzeptanz-

    kriterien Skelett der E2E-Tests E2E erfolgreich Schreibe E2E-Test Bringe Unit Test zum laufen Refactor Schreibe Unit Test Erfolgreiche E2E-Tests fertige Story Erfüllte Akzeptanz- kriterien
  13. sogehtsoftware.de CODING: TODO APP 13

  14. Seite sogehtsoftware.de Stories TODO LISTE

  15. Seite sogehtsoftware.de 15 Systemüberblick TODO LISTE Angular APP Backend-Mock Backend

  16. Seite sogehtsoftware.de 16 › GitHub https://github.com/maimArt/tddangular › Entwicklungsschritte dokumentiert in

    „Projects“ und „Commits“ › Startpunkt: Nach Sprint 0 (Commit 4) GitHub TODO LISTE
  17. Seite sogehtsoftware.de 17 › ng new tddangular --p todo ›

    Karma.config → ChromeHeadless › Protractor config: › Headless Moduls aktiviert › Plugin „protractor-console“ installiert und aktiviert › Mock Server › json-server installiert › 3 Todos als Mock-Daten angelegt › Hilfsklasse MockServer: start(),stop(); › npm run start-mock-server in package.json › environment.todosUrl → Url zum MockServer › E2e Spec und PageObject angelegt Sprint 0 - Projekt Setup TODO LISTE
  18. Seite sogehtsoftware.de 18 todo-list.e2e-spec.ts Story Kickoff -> E2E-Skelett STORY „ZEIGE

    LISTE VON TODOS " xit('should display a header "TODOs"', () => { }); xit('should display a list of TODOs', function () { }); xit('should display TODOs of the backend', function () { }); E2E Unit
  19. Seite sogehtsoftware.de 19 todo-list.e2e-spec.ts Die Liste ist durch die Überschrift

    „TODOs“ erkennbar STORY „ZEIGE LISTE VON TODOS " getHeaderText(): Promise<string> { return element(by.css('todo-list h1')).getText(); } todo-list.po.ts it('should display a header "TODOs"', () => { expect(todoList.getHeaderText()).toEqual('TODOs'); }); E2E Unit
  20. Seite sogehtsoftware.de 20 list.component.spec.ts Die Liste ist durch die Überschrift

    „TODOs“ erkennbar STORY „ZEIGE LISTE VON TODOS " E2E Unit it('should display a header TODOs', function () { const headerElement: HTMLHeadElement = fixture.nativeElement.querySelector('h1'); expect(headerElement.textContent).toEqual('TODOs') }); list-component.html <h1>TODOs</h1> E2E Unit
  21. Seite sogehtsoftware.de 21 todo-list.e2e-spec.ts Ich sehe eine Liste von TODOs

    STORY „ZEIGE LISTE VON TODOS " todo-list.po.ts E2E Unit it('should display a list of TODOs', function () { expect(todoList.isTodoListShown()).toBe(true); }); isTodoListShown(): Promise<boolean> { return element(by.css('todo-list ul')).isPresent(); }
  22. Seite sogehtsoftware.de 22 list.component.spec.ts Ich sehe eine Liste von TODOs

    STORY „ZEIGE LISTE VON TODOS " E2E Unit list.component.html E2E Unit it('should display a todo list', function () { const todoListElement: HTMLUListElement = fixture.nativeElement.querySelector('ul'); expect(todoListElement).toBeTruthy(); }); <h1>TODOs</h1> <ul></ul>
  23. Seite sogehtsoftware.de 23 todo-list.e2e-spec.ts Die TODOs wurden aus dem Fremdsystem

    geladen STORY „ZEIGE LISTE VON TODOS " todo-list.po.ts E2E Unit it('should display TODOs of the backend', function () { expect(todoList.getTodoTexts()).toEqual(['Make coffee', 'Start coding', 'Make some coffee again']) }); getTodoTexts(): Promise<string[]> { return element.all(by.css('todo-list ul li')).map(listItem => listItem.getText()); }
  24. Seite sogehtsoftware.de 24 todo.service.spec.ts Die TODOs wurden aus dem Fremdsystem

    geladen STORY „ZEIGE LISTE VON TODOS " E2E Unit todo.service.ts E2E Unit it('should request all todos from the backend', function () { const todosFromBackend: Todo[] = [{ id: '1', text: 'TODO1' }, { id: '2', text: 'TODO2' }]; const todos$: Observable<Todo[]> = service.getTodos(); todos$.subscribe(nextTodos => { expect(nextTodos).toEqual(todosFromBackend); }); const testRequest = http.expectOne(environment.todosUrl); expect(testRequest.request.method).toEqual('GET'); testRequest.flush(todosFromBackend); http.verify(); }); export interface Todo { id: string; text: string; } constructor(private http: HttpClient) { } getTodos(): Observable<Todo[]> { return this.http.get<Todo[]>(environment.todosUrl); } todo.type.ts
  25. Seite sogehtsoftware.de 25 list.component.spec.ts Die TODOs wurden aus dem Fremdsystem

    geladen STORY „ZEIGE LISTE VON TODOS " E2E Unit list.component.ts E2E Unit todos$: Observable<Todo[]>; constructor(private todoService: TodoService) { } ngOnInit() { this.todos$ = this.todoService.getTodos(); } it('should initially load list of todos from todo service', function (done: DoneFn) { spyOn(todoService, 'getTodos').and.callThrough(); component.ngOnInit(); fixture.detectChanges(); expect(todoService.getTodos).toHaveBeenCalled(); component.todos$.subscribe(nextTodos => { expect(nextTodos).toEqual(todoService.todos); done(); }) });
  26. Seite sogehtsoftware.de 26 list.component.spec.ts Die TODOs wurden aus dem Fremdsystem

    geladen STORY „ZEIGE LISTE VON TODOS " E2E Unit E2E Unit it('should display todos requested from todo service', function () { component.ngOnInit(); fixture.detectChanges(); const todoElements: NodeListOf<HTMLElement> = fixture.nativeElement.querySelectorAll('li'); const todoTexts: string[] = Array.from(todoElements).map(todoElement => todoElement.textContent); expect(todoTexts).toEqual(todoService.todos.map(todo => todo.text)); }); <h1>TODOs</h1> <ul> <li *ngFor="let todo of todos$ | async">{{todo.text}}</li> </ul> list.component.html
  27. Seite sogehtsoftware.de 27 app.module.ts Die TODOs wurden aus dem Fremdsystem

    geladen STORY „ZEIGE LISTE VON TODOS " E2E Unit Story @NgModule({ declarations: [ AppComponent, ListComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
  28. sogehtsoftware.de SYSTEMINTEGRATIONSTESTS

  29. IHR KONTAKT Twitter: E-Mail: sogehtsoftware.de Z Twitter: E-Mail: Z Martin

    Maier Senior Consultant Softwareentwicklung @_maimArt_ martin.maier@saxsys.de Manuel Mauky Lead Developer @manuel_mauky manuel.mauky@saxsys.de