Test Driven Development mit JavaScript

50

description

Die JavaScript Projekte werden zunehmend größer und komplexer. Test Driven Development (TDD) hilft dabei, die Entwicklung zu beschleunigen, spätere Problemsuche zu erleichtern und den Code im Griff zu behalten. Im Vortrag werden Techniken für den praktischen Einsatz von TDD gezeigt. Niveau: mittel, JavaScript Kenntnisse werden vorausgesetzt

Transcript of Test Driven Development mit JavaScript

Page 1: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Test-Driven Development mit JavaScript

Vladimir Dobriakov

KarlsruheJS User Group, 1. Dezember 2011

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 2: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

JavaScript

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 3: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Desktop-Anwendung

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 4: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Mobile Anwendung

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 5: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Motivation

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 6: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Vorteile von UnitTesting

Regression

Refactoring

Cross-Browser

Dokumentation

Bessere Schnittstellen

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 7: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

TDD

Ohne Ziel kein Weg

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 8: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Verwandte

BDD und acceptance-TDD

Continuous Integration

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 9: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Frameworks

und

Test Runner

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 10: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

In-Browser Frameworks

YUI Test for YUI

QUnit for jQuery

Test.AnotherWay for OpenLayers

qooxdoo

mein eigenes

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 11: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Headless (Kommandozeile)

v8

phantomjs

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 12: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

JsTestDriver

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 13: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

JsTestDriver

kein HTML Container benötigt, Liste zur ladenden js Dateien

`gem install jstdutil`

assertions: assertEquals, assertElementId etc.

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 14: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Eclipse, IDEA PlugIns

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 15: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

TestSwarm

http://testswarm.com/

von John Resig

gehostet bei Mozilla

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 16: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Watir

http://watir.com (ruby based)

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 17: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Jetzt anfangen!

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 18: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

jsTestDriver.conf

server: http://localhost:4224

load:− static/jquery.js− static/jj.js− static/*.js− static/js−test/*.js

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 19: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Test Case

TestCase("mapMarkerTest", {"test agent disappears": function () {

loadAgentData();var n = count_agents();

loadNewData();

assertTrue( n != count_agents());},"test another thing": function () {}

}

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 20: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Lerntests

keine Spec für JS, ECMA-262 zählt nicht

Programming by observation

GDD und Cargo Kult

relative Performance

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 21: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

HTML snippets

TestCase("mapMarkerTest", {setUp: function () {

/*:DOC +=<div class='post' id='map_wrapper'>

<div class='map' id='map'></div>

</div>*/

},

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 22: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Tipps für gute Tests

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 23: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Lesbarkeit

Namen - mit Leerzeichen

Intention (Was und Warum nicht Wie)

'should'

Leerzeile zwischen Setup, Machen, Prüfen

befreien von 'test' Pre�x

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 24: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

helper Beispiel

(function () {function example_agent_data() {}

TestCase("mapMarkerTest", {"test agent appears": function () {/* implementation using example_agent_data */

},"test agent disappears": function () {/* implementation using example_agent_data */

}}());

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 25: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

testCaseEnhanced von Christian Johansen

function testCaseEnhanced(name, tests) {var testMethods = {};var property;for (var testName in tests) {property = tests[testName];if (typeof property == "function" &&!/^(setUp|tearDown)$/.test(testName)) {testName = "test " + testName;

}testMethods[testName] = property;

}return TestCase(name, testMethods);

}Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 26: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

High level Abstractions

assertCalledWith von Sinon stubbing library

assertMapZoom(15) - domain speci�c assertion

domain speci�c helpers

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 27: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

DRY

nicht zu weit treiben

Redundanz, nicht die Klarheit verringern

genügend Kontext in den Test-Methoden beibehalten

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 28: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Beispiel

"test agent appears": function () {loadInitialAgentData();assertMarkerCount(2);processAgentData(agent3_with_location());assertMarkerCount(3);

},"test agent disappears": function () {loadInitialAgentData();assertMarkerCount(2);processAgentData(agent2_without_location());assertMarkerCount(1);

}

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 29: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Tests als Behavior Spec

'should'

nur ein Verhalten auf Einmal

jedes Verhalten nur ein Mal testen - denk an Wartung

die eingesetzten Frameworks nicht noch mal testen

Isolieren mit Mocks und Stubs

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 30: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Tests testen

neuer Test muss ein Mal rot sein

Test zuerst schreiben

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 31: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Break the Code

Variablen löschen

parameter-Werte ändern etc.

Test hinzufügen, der das Problem erfasst

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 32: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Break the Code

Variablen löschen

parameter-Werte ändern etc.

Test hinzufügen, der das Problem erfasst

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 33: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Test Double

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 34: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Zweck

unbequemes Interface vermeiden

spezielle Code-Pfad prüfen, die sonst schwer zu erreichen sind

insbesondere Probleme simulieren

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 35: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

stub

myproj.send_sms('+49 178 5555555', 'hello');

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 36: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

stub

myproj.send_sms('+49 178 5555555', 'hello');

myproj.send_sms = stubFn(true);postNewOrder('Repair X');assertTrue(myproj.send_sms.called);assertEquals('new order: Repair X', myproj.send_sms.args[1]);

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 37: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

stubFn

function stubFn(returnValue) {var fn = function () {fn.called = true;fn.args = arguments;return returnValue;

};

fn.called = false;

return fn;}

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 38: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

State vs. Behaviour Veri�cation

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 39: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Sinon Library

http://sinonjs.org/

stubs

mocks

fake timers

fake XHR

fake server

assertions

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 40: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Risiko von Mocks und Stubs

Javascript ist sehr dynamisch

sinon.stubEverything(target) verdeckt Typos

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 41: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Build Process

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 42: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

precommit + continuous

Tests der Web-Anwendung

jslint

JsTestDriver

minify + merge

Integration Tests (z.B. Selenium)

Tests durch Menschen

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 43: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

precommit + continuous

Tests der Web-Anwendung

jslint

JsTestDriver

minify + merge

Integration Tests (z.B. Selenium)

Tests durch Menschen

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 44: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

jslint

für Produktions-Code

für die Tests

Teil von dem Build

Precommit

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 45: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Integration Tests

JsTestDriver Tests ersetzen nicht die Integration-Tests

HTML Snippets

vom echten Server liefern oder nicht?

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 46: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Menschliches Versagen

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 47: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Go!

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 48: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Kontakt

http://www.mobile-web-consulting.de/

http://www.geekq.net

http://twitter.com/#!/enterprise_geek

http://www.xing.com/pro�le/Vladimir_Dobriakov

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 49: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Literatur

Douglas Crockford "JavaScript: The Good Parts"

Christian Johansen "Test-Driven JavaScript Development"

Vladimir Dobriakov Test-Driven Development mit JavaScript

Page 50: Test Driven Development mit JavaScript

KontextMotivationFrameworks

Aller Anfang ist schwerTipps für gute Tests

Mocks, Stubs und andere SpioneBuild Process

Go!

Bildernachweis

jslint http://www.�ickr.com/photos/codepo8/2051752263/

break http://www.�ickr.com/photos/mr_mo-fo/3570580386/

JsTestDriver Projekt Seitehttp://code.google.com/p/js-test-driver/

Wikipedia "Train wreck at Montparnasse_1895.jpg"

Vladimir Dobriakov Test-Driven Development mit JavaScript