Mit AngularJS Projekte schnell an die Wand fahren. © 2015 andrena objects ag Experts in agile...

50
© 2015 andrena objects ag Experts in agile software engineering Häufige Fehler und wie sie sich vermeiden lassen Rouven Röhrig Mit AngularJS Projekte schnell an die Wand fahren

Transcript of Mit AngularJS Projekte schnell an die Wand fahren. © 2015 andrena objects ag Experts in agile...

© 2015 andrena objects ag

Experts in agile software engineering

Häufige Fehler und wie sie sich vermeiden lassen

Rouven Röhrig

Mit AngularJS Projekte schnell an die Wand fahren

© 2015 andrena objects ag

Experts in agile software engineering 2

Agenda

1. Herausforderungen in Enterprise-JavaScript-Projekten

2. Was ist AngularJS und was bietet es

3. Wie man Projekte an die Wand fährt… und wie man es verhindert

4. Zusammenfassung und Ausblick

© 2015 andrena objects ag

Experts in agile software engineering 3

Agenda

1. Herausforderungen in Enterprise-JavaScript-Projekten

2. Was ist AngularJS und was bietet es

3. Wie man Projekte an die Wand fährt… und wie man es verhindert

4. Zusammenfassung und Ausblick

© 2015 andrena objects ag

Experts in agile software engineering 4

Herausforderungen in Enterprise-JavaScript-Projekten

• Kein Compiler

• Keine „natürliche“ Strukturierung

• Loser Zusammenhang der Dateien

• Dynamische Typisierung

• Kein „Klassen“-Konzept

• Asynchronität

• Client-seitige Ausführung

© 2015 andrena objects ag

Experts in agile software engineering 5

Agenda

1. Herausforderungen in Enterprise-JavaScript-Projekten

2. Was ist AngularJS und was bietet es

3. Wie man Projekte an die Wand fährt… und wie man es verhindert

4. Zusammenfassung und Ausblick

© 2015 andrena objects ag

Experts in agile software engineering 6

Was ist AngularJS?

• Client-seitiges JS für interaktives HTML

• Kümmert sich um die Abhängigkeiten der Dateien

• Hilft beim Strukturieren (u.a.) durch das MVVM-Pattern

• Entworfen für eine hohe Testbarkeit (UI- und Unit-Testing)

• Ermöglicht „expressive HTML“

JavaScript-Framework für Single-Page-Applikationen

© 2015 andrena objects ag

Experts in agile software engineering 7

Was ist eine Single-Page-Applikation?

Webseite aufrufen HTTP requests

Antwort(en) mit Dateien (HTML, CSS, JS etc.)

Webseite aufbauen

Link anklicken

Webseite aufrufen HTTP requests

Antwort(en) mit Dateien (HTML, CSS, JS etc.)

Webseite aufbauen

Link anklicken (HTTP requests)

Send updates

Klassische Webseite Single-Page-Applikation

© 2015 andrena objects ag

Experts in agile software engineering 8

Was ist „expressive HTML“? <div> <div> <div> <span>9</span> <span>1</span > ... </div> <div> <span> </ span > ... </div> ... </div> </div>

<sudoku> <grid> <row id="row1"> <cell id="r1c1">9</cell> <cell id="r1c2">1</cell> ... </row> <row id="row2"> <cell id="r2c1"> </cell> ... </row> ... </grid> </sudoku>

© 2015 andrena objects ag

Experts in agile software engineering 9

MVW-Pattern: Model-View-Whatever-Pattern

• Manche sagen Angular basiert auf dem MVC-Pattern

• Andere (darunter der Referent) sagen es entspricht eher dem MVVM-Pattern

• Angular sagt es ist ein Model-View-Whatever-Pattern1:

• Stellen Sie es sich so vor, wie es für Sie am meisten Sinn ergibt!

• … Angular sagt aber auch „[…] it's now closer to MVVM.“

Angular ermöglicht die Trennung von View und Logik

1 AngularJS: MVC vs MVVM vs MVP, https://plus.google.com/+AngularJS/posts/aZNVhj355G2, 19 Juli 2012

© 2015 andrena objects ag

Experts in agile software engineering 10

Angulars wichtigste Konzepte

• Dependency Injection

• Two-Way-Databinding

• Expressive HTML

© 2015 andrena objects ag

Experts in agile software engineering 11

Angulars wichtigste Bausteine

• Expressions

• Direktiven

• Controller

• Services

• Module

© 2015 andrena objects ag

Experts in agile software engineering 12

Controller im MVVM

View DOM

ViewModel Controller

stellt Daten und Methoden zur

Verfügung

Model nicht

festgelegt in Angular

Databinding ?

© 2015 andrena objects ag

Experts in agile software engineering 13

Two-way-Databinding

Hallo!

.controller('MyController', function() {

this.helloWorld = 'Hello World!';

this.input;

});

Hello World!

// 'Hallo!'

© 2015 andrena objects ag

Experts in agile software engineering 14

Zusammenspiel Direktive

HTML partial template

Direktive

Cont roller

Service HTML partial

Service

Service

Service

Direktive

Direktive

Service

HTML partial

Cont roller

HTML partial

Cont roller

Cont roller

© 2015 andrena objects ag

Experts in agile software engineering 15

Agenda

1. Herausforderungen in Enterprise-JavaScript-Projekten

2. Was ist AngularJS und was bietet es

3. Wie man Projekte an die Wand fährt… und wie man es verhindert

4. Zusammenfassung und Ausblick

© 2015 andrena objects ag

Experts in agile software engineering 16

Problem: Unzureichende Automatisierung

• Problematik:

• Manuelle Pflege der Abhängigkeiten

• Tests geben kein schnelles Feedback

• Es gibt keinen automatisierten Build-Prozess

• Build-Server ohne Build- und Test-Ergebnis

• => Tests werden vernachlässigt

• => Produktivitätsverlust

• => Nachgelagerte Automatisierung ist oft teuer!

„Wir fangen erst einmal an und automatisieren später“

© 2015 andrena objects ag

Experts in agile software engineering 17

Besser: Erst Automatisieren, dann Entwickeln

• JavaScript-basierte Anwendungen lassen sich sehr gut automatisieren

• Automatisierung muss mitwachsen

• Umso später automatisiert wird, umso aufwendiger

-> Geeignete Werkzeuge sind notwendig!

Wir machen Automatisierung zur Voraussetzung!

© 2015 andrena objects ag

Experts in agile software engineering 18

Besser: Erst Automatisieren, dann Entwickeln (2)

• NodeJS und npm für Entwicklungsabhängigkeiten

• npm als Command-line-tool

• npm als einziger Einstiegspunkt für

• Abhängigkeitsmanagement und Installation

• Build-Prozess

• Testausführung (Unit und GUI)

• Grunt oder Gulp? JA, Faustregel: „npm wenn möglich, Grunt/Gulp wenn nötig“

Build-Prozess: NodeJS und npm

© 2015 andrena objects ag

Experts in agile software engineering 19

Besser: Erst Automatisieren, dann Entwickeln (3)

package.json

Build-Prozess: npm als einziger Einstiegspunkt

install Entwicklungsabhängigkeiten postinstall: Frontend-Abhängigkeiten test: Unit-Tests e2e-test: UI-Tests taskXY: gulp complicated-job …

… gulp.task('complicated-job', …); …

gulpfile.js

© 2015 andrena objects ag

Experts in agile software engineering 20

Besser: Erst Automatisieren, dann Entwickeln (4)

• Beliebiges JavaScript-Projekt, beliebiger Rechner:

• Voraussetzung: NodeJS und git

1. git clone…

2. npm install (Installiert ALLE Abhängigkeiten lokal)

3. npm test (führt Tests aus)

4. npm start (optional: startet Webserver)

-> Komplexität massiv reduziert

Standardisierte autarke Projekte durch npm

© 2015 andrena objects ag

Experts in agile software engineering 21

Besser: Erst Automatisieren, dann Entwickeln (5)

• npm für Entwicklungsabhängigkeiten

• bower für Frontend-Abhängigkeiten

• Vorteile:

• Trennung von Frontend und Backend-Abhängigkeiten.

• Flacher Abhängigkeitsgraph

Bower für Frontend-Abhängigkeiten

© 2015 andrena objects ag

Experts in agile software engineering 22

Problem: Keine oder kaum GUI-Tests

• Problematik:

• Fehler treten trotz Unit-Tests auf

• Aufwand des manuellen Testens steigt

• Fehler bleiben lange unentdeckt

• => Äußere Qualität ist schlecht

• => Späte Automatisierung offenbart schlecht testbares HTML

© 2015 andrena objects ag

Experts in agile software engineering 23

GUI-Tests ab der ersten Seite

• GUI-Tests sind aufwendig und veralten schnell

• Auf wichtige Use Cases konzentrieren

-> Smoke-Tests

• Testbare HTML-Komponenten benötigen IDs

• Klassen sind fehleranfälliger

Das Gesamtsystem testen

<row id="row1"> <cell id="r1c1"> … </cell> <cell id="r1c2"> … </cell> … </row> <row id="row2"> <cell id="r2c1"> … </cell> … </row>

© 2015 andrena objects ag

Experts in agile software engineering 24

GUI-Tests: Page Object Pattern

• Egal ob Protractor oder Selenium, Java oder JavaScript: Page Objects!

• Ein Page Object

• repräsentiert eine Webseite

• weiß wie man darauf zugreift

• kennt Page Objects verlinkter Seiten

• Tests verwenden Page Objects statt eigene Locator

• Vorteil: Ändert sich eine Webseite, ändert sich nur ein Page Object

© 2015 andrena objects ag

Experts in agile software engineering 25

GUI-Tests: Page Object Pattern (2)

describe('Login Page', function() {

it('a user can login', function() {

var loginPage = new LoginPage();

loginPage.get();

loginPage.setUsernameAndPassword('user1', 'abc');

var overviewPage = loginPage.clickLoginExpectSuccess();

expect(overviewPage.isDisplayed()).toBe(true);

});

});

Eine von vielen Möglichkeiten, die auf die Folie

gepasst hat!

Für Page Objects bieten

sich auch „Singletons“ an!

© 2015 andrena objects ag

Experts in agile software engineering 26

GUI-Tests: Page Object Pattern (3)

function LoginPage() {

this.get = function () {

return browser.get('/#/login');

};

this.setUsernameAndPassword = function(username, password) {

element(by.id('login-username')).sendKeys(username);

element(by.id('login-password')).sendKeys(password);

};

this.clickLoginExpectSuccess = function() {

element(by.id('login-button')).click();

return new OverviewPage();

};

}

Eine von vielen Möglichkeiten, die auf die Folie

gepasst hat!

© 2015 andrena objects ag

Experts in agile software engineering 27

Problem: Keine oder wenig Unit-Tests

• Problematik:

• Viele Fehler

• Fehler werden spät entdeckt

• Entwicklung per „Trial and Error“

• Schlecht wartbarer und nicht testbarer Code

• => Schlechte innere und äußere Qualität

• => langsame riskante Entwicklung

„Das Frontend lässt sich nicht Unit-Testen“

© 2015 andrena objects ag

Experts in agile software engineering 28

Besser: Von Anfang an Unit-Tests

• Testbarkeit ist wichtige Metrik für Qualität

• In Angular: „Nur ein testbarer Controller kann ein guter Controller sein“

• Frontend-Code lässt sich auch testen (Direktiven und Controller)

• Strikte Trennung von View und Logik

• Controller darf nicht vom DOM abhängen (nur Zustand und Methoden)

• Direktiven:

• Operationen möglich mit Tools

• Fokus auf Controller

Noch besser: TDD oder Test-first

© 2015 andrena objects ag

Experts in agile software engineering 29

Besser: Von Anfang an Unit-Tests (2)

• Test-Framework: Jasmine oder Mocha

• Test-Runner: Karma

• Testausführung in verschiedenen Browsern

• Viele Erweiterungen:

• Code-Coverage

• Ergebnis für Build-Server (z.B. Jenkins)

• Automatisierung:

• npm führt Karma aus, Karma führt Jasmine-Tests aus

Geeignete Werkzeuge

© 2015 andrena objects ag

Experts in agile software engineering 30

Besser: Von Anfang an Unit-Tests (3)

• Viele Projekte haben einen größeren Build-Prozess

• z.B. Minification, Uglification, Sass-Build etc.

• Häufig muss der Code gebaut werden, bevor er getestet wird

• Okay und gut für Build-Server

• Schlecht für TDD und schnelles Feedback

• Empfehlung: Unit-Tests müssen auch ohne Build laufen

• Oder watch-Task für Entwickler der wirklich schnell ist

Automatisierung ≠ Automatisierung

© 2015 andrena objects ag

Experts in agile software engineering 31

Problem: Keine einheitlichen Codekonventionen

• Problematik:

• Flüchtigkeitsfehler schleichen sich ein

• Einfache Programmierfehler treten auf

• Schlechte Lesbarkeit und Wartbarkeit

• => Verringerte Softwarequalität

• => Verringerte Produktivität

© 2015 andrena objects ag

Experts in agile software engineering 32

Codekonventionen durchsetzen

• Statische Codeanalyse

• überprüft Codekonventionen und findet typische Fehler

• Bekannte Linter:

• JSLint: Fester Standard

• JSHint: Konfigurierbar

• ESLint: Konfigurierbar und erweiterbarer

• Zusätzlich: HTML validieren

=> Gute IDEs integrieren Linter-Errors

Linter findet einfache Fehler und stellt Konventionen sicher

© 2015 andrena objects ag

Experts in agile software engineering 33

Problem: IDE unterstützt JavaScript unzureichend

• Problematik: Schlechter oder kein JavaScript-Support

• Kein Syntax-Highlighting

• Keine Funktionen

• Keine automatisierten Refactorings

• Keine Linter-Integration

• => Langsame Entwicklungsgeschwindigkeit

• => Viele überflüssige Fehler

„Wir entwickeln schon immer mit <BLANK>.“

© 2015 andrena objects ag

Experts in agile software engineering 34

Eine IDE mit guter JavaScript-Integration

• WebStorm (kommerziell)

• Brackets, Atom, Sublime et al. (nicht-kommerziell)

• Visual Studio (kommerziell)

=> Aufwand und Kosten amortisieren sich schnell!

Folgende IDEs bieten eine Integration

© 2015 andrena objects ag

Experts in agile software engineering 35

Problem: Code-Duplikationen

• Problematik:

• Änderungen müssen an vielen Stellen erfolgen

• Gefixte Fehler tauchen wieder auf

• Features sind nicht an allen Stellen implementiert

• => Änderungen und Erweiterungen sind teuer

• => Zunehmend unwartbarer Code

• => Schlechte Codequalität

© 2015 andrena objects ag

Experts in agile software engineering 36

Keine Code-Duplikationen

• HTML-Duplikationen

• Controller-unabhängig: Template-Direktive

• Controller-abhängig: Direktive (mit eigenem Controller)

• Duplikationen im Controller:

• Wiederverwendbarer Service

• JavaScript-Objekt

Aber wie?

© 2015 andrena objects ag

Experts in agile software engineering 37

Keine Code-Duplikationen (2)

• Objekte können on-the-fly erzeugt werden

-> Führt zu Code-Duplikationen

function Message(title, content) {

this.title = title;

this.content = content;

} var message = {

title: 'a title',

content: 'a message'

};

.factory('Message', function() {

return Message;

});

JavaScript-Objekte explizit modellieren

Eine von vielen Möglichkeiten, die auf die Folie

gepasst hat!

Besser

© 2015 andrena objects ag

Experts in agile software engineering 38

Keine Code-Duplikationen (3)

• Methodik:

• Große Controller lassen sich schlecht testen, daher: TDD!

-> Kann ich einen Controller schwer Unit-Testen, ist er häufig zu groß.

• Werkzeuge:

• Services: (Wiederverwendbare) Logik auslagern

• Template-Direktiven: (Wiederverwendbare) HTML-Templates

• Direktiven: (Wiederverwendbare) UI-Aspekte kapseln

Kleine Controller, Direktiven und Services

© 2015 andrena objects ag

Experts in agile software engineering 39

Problem: ng-controller statt Direktiven

• Problematik:

• ng-controller wird verwendet

• HTML-Code-Duplikationen

• Ähnliche oder duplizierte Controller

• => Komplizierte Scope-Abhängigkeiten

• => Schwer verständlicher Code

• => Duplizierter Code

© 2015 andrena objects ag

Experts in agile software engineering 40

Besser: Domänenspezifische Sprache mit Direktiven

• Eine Direktive ist in sich abgeschlossen, bestehend aus:

• HTML-Template

• Controller

• Styling

• Unit-Test ;-)

• Eine Direktive manipuliert nur ihren eigenen DOM

Direktiven sind das Feature von AngularJS

© 2015 andrena objects ag

Experts in agile software engineering 41

Besser: Domänenspezifische Sprache mit Direktiven (2)

.directive('infobox', function() {

return {

templateUrl: 'infobox.html',

controller: function() {...},

controllerAs: 'infobox',

scope: {

'text': '@',

},

bindToController: true

};

});

<div class="alert alert-info"> {{infobox.text}} <div>

<infobox text="Hello World!"/>

https://jsbin.com/lonifo

Hello World!

infobox{ /* styling */ }

© 2015 andrena objects ag

Experts in agile software engineering 42

Besser: Domänenspezifische Sprache mit Direktiven (3)

.directive('anotherDirective',

function() {

return {

/*…*/

};

});

<infobox ng-if="{{anotherDirective.someCondition}}" text="{{anotherDirective.status}}"/> <input … /> <button .../>

anotherDirective{ /* styling */ }

© 2015 andrena objects ag

Experts in agile software engineering 43

Problem: Callback-based APIs

• Problematik:

• Führt meist in die „Callback Hell“ [1]

• Abhängigkeiten schlecht parallelisierbar

• Aufwendige Fehlerbehandlung

• Keine Trennung von Fehler- und Erfolgsfall

[1] http://callbackhell.com/

© 2015 andrena objects ag

Experts in agile software engineering 44

Besser: Promise-based APIs

• Promises ermöglichen

• Einheitliches API-Design

• Trennung von Fehler- und Erfolgsfall

• „Promise chaining“

• Sauberer Code

=> Achtung Design und Testing eigener APIs ist dennoch anspruchsvoll

Angular bietet eigene API für Promises

loadData(42)

.then( preprocessData )

.then( displayResult )

.catch( alertUser )

.finally( clearLoadingFlag );

© 2015 andrena objects ag

Experts in agile software engineering 45

Agenda

1. Herausforderungen in Enterprise-JavaScript-Projekten

2. Was ist AngularJS und was bietet es

3. Wie man Projekte an die Wand fährt… und wie man es verhindert

4. Zusammenfassung und Ausblick

© 2015 andrena objects ag

Experts in agile software engineering 46

Empfehlungen

• Automatisierung von Anfang an

• GUI-Tests ab der ersten Seite

• Unit-Tests -> TDD oder Test-first

• Hohe Testabeckung -> Testabdeckung messen!

• Code-Konventionen -> Linter und gute IDE

• Keine Code-Duplikationen -> Angulars Möglichkeiten nutzen

• Promise-based APIs

© 2015 andrena objects ag

Experts in agile software engineering 47

Rahmenbedingungen von Enterprise-JavaScript-Projekten

• Kein Compiler Testautomatisierung

• Keine „natürliche“ Strukturierung Disziplin und Angular-Module

• Loser Zusammenhang der Dateien Angular-Module

• Dynamische Typisierung Testautomatisierung

• Kein „Klassen“-Konzept Explizit modellierte Objekte

• Asynchronität ~ Promise-based APIs

• Client-seitige Ausführung

• => Einige Probleme werden von EcmaScript2015 adressiert

© 2015 andrena objects ag

Experts in agile software engineering 48

Noch besserer Code durch TypeScript

• Typisierung (Typdeklaration, Klassen, Interfaces)

• Compile-Errors

• Typsichere Rest-Schnittstelle

• Serverseitiges DTO (z.B. in Java geschrieben) kann als TypeScript-DTO generiert werden

-> TypeScript-Compile-Errors

• Kommt mit vielen zukünftigen EcmaScript-Features

• (Debugging mit Source in TypeScript-Dateien möglich)

Vorteile von Angular mit TypeScript

© 2015 andrena objects ag

Experts in agile software engineering 49

Noch besserer Code durch TypeScript (2)

• Konversion nicht immer ohne Cast möglich

• Compiler-Schritt kostet etwas Zeit

• Typdefinitionen für externen JavaScript-Code

• => Angular 2 wird mit TypeScript entwickelt

Einschränkungen beim Einsatz von TypeScript mit Angular

© 2015 andrena objects ag

Experts in agile software engineering 50

Vielen Dank für Ihre Aufmerksamkeit