Slide 1

Slide 1 text

Testing Sencha Touch apps (C) 2012 Mats Bryntse www.bryntum.com Tuesday, November 6, 12

Slide 2

Slide 2 text

Agenda Reasons for testing A look at Sencha Touch Getting to know Siesta Making the most out of your test suite Live example Tuesday, November 6, 12

Slide 3

Slide 3 text

About me Mats Bryntse Helsingborg, Sweden Background in ASP.NET Sencha enthusiast since 2007 Founded Bryntum 2009 (Gantt/Scheduler/Siesta) @bryntum facebook.com/bryntum Tuesday, November 6, 12

Slide 4

Slide 4 text

Before we start Tuesday, November 6, 12

Slide 5

Slide 5 text

Before we start Do you have a test suite for your Sencha Touch project? Tuesday, November 6, 12

Slide 6

Slide 6 text

Why should we test? ? Tuesday, November 6, 12

Slide 7

Slide 7 text

#1. Building a 2012 RIA 10 Tuesday, November 6, 12

Slide 8

Slide 8 text

=== Complexity Imagine making a UI change, and having to verify it in 20 browsers Tuesday, November 6, 12

Slide 9

Slide 9 text

#2. New guy joins your team Tuesday, November 6, 12

Slide 10

Slide 10 text

Hey, new guy! Can you rewrite some code in legacy-core.js? Tuesday, November 6, 12

Slide 11

Slide 11 text

New guy studies the code // drunk, fix later Tuesday, November 6, 12

Slide 12

Slide 12 text

New guy studies the code // When I wrote this, only God and // I understood what I was doing // Now, God only knows Tuesday, November 6, 12

Slide 13

Slide 13 text

New guy studies the code /** * Always returns true. */ function isAvailable() { return false; } Tuesday, November 6, 12

Slide 14

Slide 14 text

New guy scared No confidence Tuesday, November 6, 12

Slide 15

Slide 15 text

Without tests, how do you refactor code you’re not familiar with? Tuesday, November 6, 12

Slide 16

Slide 16 text

#3. Framework upgrade v.2.0 v.2.1 Tuesday, November 6, 12

Slide 17

Slide 17 text

1. Productivity, confidence 2. Frameworks contain bugs 3. So does your code 4. ...and mine... 5. Refactoring (code handover) 6. Fix bugs once Reasons for testing Tuesday, November 6, 12

Slide 18

Slide 18 text

A look at Sencha Touch Tuesday, November 6, 12

Slide 19

Slide 19 text

Anatomy of a ST application Application Tuesday, November 6, 12

Slide 20

Slide 20 text

Models & Stores Pure JS, not tied to DOM Testing is easy Good place to put business logic Tests are a great investment Tuesday, November 6, 12

Slide 21

Slide 21 text

Views View produces HTML, involves DOM Testing requires more effort. Render. Interact. Bad bad place to put business logic Tuesday, November 6, 12

Slide 22

Slide 22 text

Ext.define(‘UserForm’, { extend : ‘Ext.form.Panel’, getAnnualSalary : function() { return this.model.get(‘salaryPerMonth’) * 12: } }); Views Tuesday, November 6, 12

Slide 23

Slide 23 text

Ext.define(‘User’, { extend : ‘Ext.data.Model’, fields : [‘name’, ‘age’, ‘salaryPerMonth’] , getAnnualSalary : function() { return this.get(‘salaryPerMonth’) * 12: } }); Views Tuesday, November 6, 12

Slide 24

Slide 24 text

Controllers Not directly tied to DOM But, often tied to ST components Hard to isolate, mocking not trivial Tuesday, November 6, 12

Slide 25

Slide 25 text

Application “Black box testing” Launch app UI, issue commands to browser Does application work or not? Tuesday, November 6, 12

Slide 26

Slide 26 text

What to test? Data classes (UserModel.js) - Easy +++ View classes (UserList.js) - Medium ++ Controllers (UserController.js) - Adv + Whole application (index.html) - Adv + Tuesday, November 6, 12

Slide 27

Slide 27 text

Tools to use? Jasmine PhantomJS JsTestDriver YUI Test DOH ..... Tuesday, November 6, 12

Slide 28

Slide 28 text

“Stress free unit testing” Tuesday, November 6, 12

Slide 29

Slide 29 text

Why Siesta? Upgrade to Ext JS 4 was hard (lack of tests) Manual testing doesn’t scale No tools seemed to do the trick Selenium, Jasmine not enough Tuesday, November 6, 12

Slide 30

Slide 30 text

What we wanted: Write tests in JS Automatable Extensible Ext JS aware Easy to learn Tuesday, November 6, 12

Slide 31

Slide 31 text

Siesta overview Freemium, generic JS testing tool (Ext JS, jQuery, NodeJS) Unit testing and Functional testing Adapters for Ext JS, Sencha Touch We use it. 2000+ assertions Automation via PhantomJS or Selenium Tuesday, November 6, 12

Slide 32

Slide 32 text

Siesta features t.is(“foo”, “foo”, ‘values match’); // PASS t.isnt(“foo”, “bar”, “values mismatch”); // PASS t.isDeeply({ foo : ‘bar’}, { a : ‘b’ }, ‘Objects’); // FAIL t.ok(true, ‘True is truthy’); // PASS t.notOk(null, ‘null is falsy’); // PASS Basic assertions Tuesday, November 6, 12

Slide 33

Slide 33 text

Siesta features t.tap(myDiv, ...); t.moveFingerTo(myDiv); t.dragBy(myDiv, [50, 50], ...); t.type(myInput, ‘Hello world’, ...) User simulation Tuesday, November 6, 12

Slide 34

Slide 34 text

Siesta features Sandboxing Tuesday, November 6, 12

Slide 35

Slide 35 text

t.waitForStoresToLoad(...); t.waitForCQ(‘userlist’, fn); t.waitForEvent(myList, ‘selectionchange’, ...); Siesta features ST awareness Tuesday, November 6, 12

Slide 36

Slide 36 text

Siesta features initComponent : function() { var counter = 1; i = 0; this.callParent(arguments); } Globals detection Tuesday, November 6, 12

Slide 37

Slide 37 text

API Docs (JsDuck) Tuesday, November 6, 12

Slide 38

Slide 38 text

Simple unit test Ext.define(‘User’, { extend : ‘Ext.data.Model’, fields : [‘name’, ‘age’] }); var bob = new User({ name : ‘Bob’ }); t.is(bob.get(‘name’), ‘Bob’, ‘Name works!’); Tuesday, November 6, 12

Slide 39

Slide 39 text

Simple functional test var btn = new Ext.Button({ text : ‘Click me’, renderTo : document.body }); t.willFireNTimes(btn, ‘click’, 1, ‘1 click detected’); t.click(btn); Tuesday, November 6, 12

Slide 40

Slide 40 text

Targeting options Element id Component query Composite query CSS selector Coordinate DOM node function () {} Component instance Tuesday, November 6, 12

Slide 41

Slide 41 text

Targeting engine CSS selector ‘.foo’ Element id’s ‘#foo’ Coordinate [50, 50] Component Query ‘>>button’ Composite Query ‘gridpanel => .x-grid-cell’ Tuesday, November 6, 12

Slide 42

Slide 42 text

Async testing t.chain( { waitFor : ‘rowsVisible’, args : myGrid }, function (next) { // Assertions go here next(); }, { action : ‘click’, target : ‘.saveButton’ } ); Tuesday, November 6, 12

Slide 43

Slide 43 text

Object notation syntax t.chain( { action : ‘click’, target : ‘>>myform namefield’ }, { action : ‘type’, text : ‘John’ }, { action : ‘click’, target : ‘>> myform savebutton’ }, function () { t.is(myUser.get(‘name’), ‘John’, ‘Wooo!’); } ); Tuesday, November 6, 12

Slide 44

Slide 44 text

Future plans Fiesta - crowd sourced test tool Recorder Cloud testing environment [your idea here] Tuesday, November 6, 12

Slide 45

Slide 45 text

Ok, I have tests - now what? Tuesday, November 6, 12

Slide 46

Slide 46 text

Remember all our friends? 10 Tuesday, November 6, 12

Slide 47

Slide 47 text

Testing manually does not scale Tuesday, November 6, 12

Slide 48

Slide 48 text

#1. Don’t test in a browser UI if you can avoid it Tuesday, November 6, 12

Slide 49

Slide 49 text

#2. Launch tests from IDE Tuesday, November 6, 12

Slide 50

Slide 50 text

Chrome => iOS sim. => on device #3. Testing environments Tuesday, November 6, 12

Slide 51

Slide 51 text

#4. Nightly builds running full test suite Tuesday, November 6, 12

Slide 52

Slide 52 text

#5. Dealing with bugs Find new bug => New test case => Fix bug Tuesday, November 6, 12

Slide 53

Slide 53 text

Live demo time! Tuesday, November 6, 12

Slide 54

Slide 54 text

Before closing, let’s repeat Failing in JS/CSS is too easy. Testing manually doesn’t scale. Too many dimensions Testing only JS is not enough. DOM interaction Automation is king. Nightly builds, CI reports Tuesday, November 6, 12

Slide 55

Slide 55 text

Thanks for listening! “Without unit tests, you’re not refactoring. You’re just changing shit.” Tuesday, November 6, 12