testing ext js and sencha touch
DESCRIPTION
My SourceDevCon 2012 presentation slides.TRANSCRIPT
Testing Ext JS & Sencha Touch
2012 Mats Bryntse@bryntum
• Why test your JavaScript?
• Testing Methodologies
• Introducing Siesta
• Writing testable JS
• Automating tests
Contents
var me = { name : ”Mats Bryntse”, age : 35+, lives : ”Helsingborg, Sweden”, does : ”Runs Bryntum”, site : ”www.bryntum.com”, twitter : ”@bryntum”};
About me
What we do
Ext JS/ST Components
Siesta (JS Test Tool)
First, a quick raise of hands:
How many of you...
• have a frontend test suite?
• have frontend test suite as part of your CI?
• run your test suite in all major browsers?
• have zero or fewer frontend tests for your app?
How many of you...
Why test your JavaScript?
A typical web app...
Interwebs
http://www.app.com
The backend
• Single controlled platform
• Simple to test and refactor
• Good IDEs and tools
C#Java
PHP
The frontend
• Multiple platforms & versions (Mac, Windows XP/Vista/7/8, Linux...)
• Multiple browser versions
• Hard to refactor
• JavaScript support in IDEs is still !== awesome
Conclusion
Too easy to #FAIL as a frontend developer
Testing helps you keep fails to a minimum.
But...
”... my code is bug free”
”...testing takes time away from adding new features (+ new bugs)”
”...it’s QA’s job to test”
”... it’s boring and I’ll quit my job”
A good investment
• Writing tests === investment in your code
• Takes time
• Will pay you back, though not instantly
Scenario: A nasty bug was found
3 options
[panic]
[patch it]
[proper fix]
A test suite...
=> confidence in your code
=> serves as extra documentation
=> easier refactoring
=> bugs happen once, easier to find
=======> quality of sleep
Code handover
• Test cases are really useful when handing over responsibility for a JS module
• Developer Bob quits his job. New guy gets responsibility of his JS code.
• How will new guy know what parts of the codebase is safe to change & refactor?
New guy studies codebase
/** * When I wrote this, only God and I understood what I was doing * Now, God only knows **/
/* I am not sure if we need this, but too scared to delete. */
// drunk, fix later
// This is my last day...
application.js
Code handover
New guy, scared
Code handover
• Without test suite, will new guy feel good about making major changes?
• Only minor cosmetic changes on the surface.
• System accumulates cruft over time. • Sounds familiar?
JS Testing Methodologies
Unit testing
Integration testing
Functional testing
Unit testing
• Testing the API of a single isolated ’unit’
• Typically pure JS, non UI / DOM• verify set/get method of a Model• verify date manipulation logic
• Many tools available
Unit testing
• Siesta
• Jasmine
• QUnit (jQuery)
• Google js-test (V8)
Integration testing
• Testing integration between units.
• E.g. verify cell editing plugin works in GridPanel
Functional Web testing
• UI testing of a component or an application as a whole.
• Send commands to the web page and evaluate result.
• ’click button’, ’type into login field’, ...
Functional Web testing
• Siesta
• Selenium
• JsTestDriver
Interacting with the DOM
Approaches to faking user input
• Synthetic events (JavaScript)
• Native events (via Java Applet)
Synthetic events+ Supported in all major browsers+ Compatible with mobile+ Don’t rely on native event queue
Tests can be run in parallell.
- Browsers don’t ”trust” synthetic events- Enter key on a focused link- Tab between input fields, etc...
- X-browser differencesDOM Events, Key events, key codes (http://unixpapa.com)
Native events
+ Java applets are supported in desktop browsers+ As close to a ’real’ user as possible
- Won’t work on iOS, Android.- No parallell tests since native event queue is used.
What is Siesta?
• Unit testing and DOM testing tool
• Optimized for Ext JS & Sencha Touch - also supports jQuery, NodeJS, or any JS
• Simple syntax, Extensible
• Automate using PhantomJS & Selenium.
Siesta Browser Harness
Siesta Browser Harness
• A UI for Siesta, view DOM, inspect assertions
• Define a tree of tests, in logical groups
• Global settings for the test suite autoCheckGlobals, preload, testClass
A Siesta Test
• is pure JavaScript, no magic.
StartTest(function(t) { $('body').html('JQuery was here'); t.contentLike(document.body,
'JQuery was here', 'Found correct text in DOM');
});
A Siesta Test
• is completely isolated in its own iframe(no teardown, cleanup required)
A Siesta Test
• can be extended with your own custom assertions and helper methods
StartTest(function(myTest) { var app = myTest.startApplication(); myTest.performLogin(app); myTest.isLoggedIn(app, ’Logged in ok’); myTest.is(app.nbrUsers, 1, ’Found 1 user’);});
Lifecycle of a UI test
Setup create grid, load stores
Wait for store to load, grid rows to render
Simulate click button, type into textbox
Verify isEqual(a, b)
Setup
var userGrid = new My.UserGrid({ … });
userGrid.render(Ext.getBody());
Wait
t.waitForRowsVisible(userGrid, function(){ // Do something});
t.waitForComponentQuery(“formpanel > textfield”);
t.waitForCompositeQuery(“grid => .x-grid-row”);
Simulate
// A list of actions to simulatet.chain(
{ desc : 'Should click trigger field',
action : 'click', target : 'testgrid triggerfield'
},{
desc : 'Should type into filter field', action : 'type',
target : 'testgrid triggerfield',text : 'FOO'
}, ...);
Verify
t.is(userStore.getCount(), 5, ”5 users found”);
t.willFireNTimes(store, 2, ”write”);
t.hasCls(grid.getEl(), ”myClass”, ”Found CSS”);
t.hasSize(myWindow, 300, 300, ”Window size ok”);
DEMO
Sencha Touch support
Simulate tap, doubleTap, swipe, longPress, etc...
Siesta.next
• Benchmarking
• Code coverage
• Multi-browser, multi-device testing• Crowd sourced test case tool “Code
Cowboy”
• Your suggestion?
Headless testing
• Headless browsers are great, fast
• Command line, easy to integrate with IDEs
• PhantomJS, GUI-less WebKit browser
Phantom JS
Created by Ariya Hidayat (Sencha Inc.)
Fast headless testing
Site scraping
SVG rendering, PDF/PNG output
Supports CoffeeScript
Headless browsers
+ Run tests on command line+ Faster+ Automation+ Doesn’t require an actual browser
- Not 100% accurate, but close.
Writing testable JS
Some ground rules
• Keep your JavaScript in JS files
• Never put JavaScript in your HTML page/tags
• Keep code organized in logical manageable files. Decide on some max nbr of lines/file.
No no no
Testable MVC code
• Fat model, skinny view
• Don’t pollute your views with business logic
• Testing pure JS is a lot easier than testing DOM-dependent JS
• Promotes reuse of your code
Mixing view and logic
Ext.define('UserForm', { extend: 'Ext.FormPanel', width: 400, height: 400,
// Returns true if User is valid isValid: function (userModel) { return userModel.name.length > 4 &&
userModel.password.length > 8; }});
Better
Ext.define('UserModel', { extend: 'Ext.data.Model ', name : '', password : '',
isValid : function () { return this.name.length > 4 &&
this.password.length > 8; }});
Refactored view
Ext.define('UserForm', { extend: 'Ext.FormPanel', width: 400, height: 400, // Returns true if User is valid isValid: function () { return this.model.isValid(); }});
Avoid private code
• Avoid overuse of private functions in closures
• If your code cannot be accessed it cannot be tested
Testing Ajax
• Try to avoid involving your database.
• Use either static JS files with mock data (async, slower)
• Or Mock the entire Ajax call (sync, faster)
Sinon.js, Jasmine-ajax etc.
Automation & Continuous Integration
Continuous Integration
• Once you have decided on your testing toolset, integrate it with your CI.
• Automatically run test suite on pre-commit or post-commit
• Nightly builds, full test suite execution, reporting via email etc.
CI Tools
• Jenkins
• TeamCity
• Cruise Control
• Test Swarm
JS Code Coverage
• JsCoverageSeems abandoned
• ScriptCoverGoogle Chrome Plugin
• JsTestDriverAdd-in module for coverage
• JesCov Rhino, Jasmine
Resources - Yahoohttp://screen.yahoo.com/
Resources - GTAC
”Without unit tests, you’re not refactoring. You’re just changing shit.”
Hamlet D’Arcy
Thanks for listening!
Questions?
2012 Mats Bryntse@bryntum