Slide 1

Slide 1 text

TEST-DRIVEN CLIENT-SIDE APPS Pete Hodgson @ph1 | [email protected]

Slide 2

Slide 2 text

UNIT
 TESTING

Slide 3

Slide 3 text

TEST DRIVEN DEVELOPMENT

Slide 4

Slide 4 text

me me me Pete Hodgson Consultant at ThoughtWorks @ph1 blog.thepete.net

Slide 5

Slide 5 text

WRITE A
 FAILING TEST GET THE TEST TO PASS REFACTOR

Slide 6

Slide 6 text

WRITE A
 FAILING TEST GET THE TEST TO PASS REFACTOR

Slide 7

Slide 7 text

FEEDBACK

Slide 8

Slide 8 text

NXTBRT.COM

Slide 9

Slide 9 text

the
 backend the
 browser single-page javascript app REACT {JSON}

Slide 10

Slide 10 text

{ dest_name: “Richmond”, etd: 8, … } Departure Domain Object { destination: “Richmond”, departing: “8 mins” } View Object presenter function

Slide 11

Slide 11 text

var presentDeparture = function(departure){ return { destination: departure.dest_name }; };

Slide 12

Slide 12 text

var departurePresenter = require('../../js/departure_presenter'); ! describe( 'Departure presenter', function(){ it('presents the destination', function(){ // Given var departure = { dest_name: "Ontario", etd: 10 }; // When var viewModel = departurePresenter(departure); // Then expect(viewModel).to.have.property('destination','Ontario'); }); });

Slide 13

Slide 13 text

var departurePresenter = require('../../js/departure_presenter'); ! describe( 'Departure presenter', function(){ it('presents the destination', function(){ // Given var departure = { dest_name: "Ontario", etd: 10 }; // When var viewModel = departurePresenter(departure); // Then expect(viewModel).to.have.property('destination','Ontario'); }); });

Slide 14

Slide 14 text

{ dest_name: “Richmond”, etd: 8, … } Departure Domain Object { destination: “Richmond”, departing: “8 mins” } View Object

Slide 15

Slide 15 text

{ dest_name: “Richmond”, etd: 8, … } Departure Domain Object { destination: “Richmond”, departing: “8 mins” } View Object

Slide 16

Slide 16 text

FEEDBACK

Slide 17

Slide 17 text

RAPID FOCUSED ACCURATE FEEDBACK

Slide 18

Slide 18 text

25

Slide 19

Slide 19 text

26

Slide 20

Slide 20 text

27

Slide 21

Slide 21 text

27 TEST SCOPE

Slide 22

Slide 22 text

TEST SCOPE DOM HTTP 28

Slide 23

Slide 23 text

29

Slide 24

Slide 24 text

30 ISOLATION

Slide 25

Slide 25 text

30 ISOLATION test code

Slide 26

Slide 26 text

presenter function test code ✓ ISOLATION

Slide 27

Slide 27 text

departures gateway controller AJAX function “station-id” GET
 http://blah/station-id LIST OF DEPARTURE OBJECTS BIG BLOB
 OF JSON

Slide 28

Slide 28 text

34

Slide 29

Slide 29 text

HTTP 35 ajax function

Slide 30

Slide 30 text

36 fake ajax function

Slide 31

Slide 31 text

36 fake ajax function

Slide 32

Slide 32 text

departures gateway test code mock
 ajax fn

Slide 33

Slide 33 text

departures gateway test code “station-id” “http://blah/station-id” mock
 ajax fn

Slide 34

Slide 34 text

departures gateway test code CORRECTLY-PARSED DOMAIN OBJECT SOME JSON mock
 ajax fn

Slide 35

Slide 35 text

it( 'parses the AJAX response as JSON', function(){ // Given var fakeJson = '{ "some":"json" }'; var fakeAjaxResponse = Q(fakeJson); var fakeAjaxFn = function(){ return fakeAjaxResponse; }; ! var departuresGateway = createDeparturesGateway(fakeAjaxFn); ! // When var departuresPromise = departuresGateway.fetchDeparturesFor('blah'); ! // Then return expect(departuresPromise) .to.eventually .deep.equal({some:"json"}); });

Slide 36

Slide 36 text

RAPID FOCUSED ACCURATE FEEDBACK

Slide 37

Slide 37 text

42 ISOLATION

Slide 38

Slide 38 text

mocha test runner chai assertion library gulp task runner, file watcher testem browser manager sinon stubbing/mocking chai-as-promised …

Slide 39

Slide 39 text

45 github.com/moredip/test-driven-react @ph1 | [email protected] http://slides.thepete.net