2. Contents
• Why test your JavaScript?
• Testing Methodologies
• Introducing Siesta
• Writing testable JS
• Automating tests
3. About me
var me = {
name : ”Mats Bryntse”,
age : 35+,
lives : ”Helsingborg, Sweden”,
does : ”Runs Bryntum”,
site : ”www.bryntum.com”,
twitter : ”@bryntum”
};
6. 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?
9. The backend
• Single controlled platform
• Simple to test and refactor
• Good IDEs and tools
PHP
C#
Java
10. 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
11. Conclusion
Too easy to #FAIL as a frontend developer
Testing helps you keep fails to a minimum.
12. 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”
13. A good investment
• Writing tests === investment in your code
• Takes time
• Will pay you back, though not instantly
18. A test suite...
=> confidence in your code
=> serves as extra documentation
=> easier refactoring
=> bugs happen once, easier to find
=======> quality of sleep
19. 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?
20. New guy studies codebase
application.js
/**
* 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...
22. 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?
25. 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
28. 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’, ...
30. Interacting with the DOM
Approaches to faking user input
• Synthetic events (JavaScript)
• Native events (via Java Applet)
31. 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 differences
DOM Events, Key events, key codes (http://unixpapa.com)
32. 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.
33.
34. 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.
36. 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
37. 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');
});
38. A Siesta Test
• is completely isolated in its own iframe
(no teardown, cleanup required)
39. 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’);
});
40. 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)
52. 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.
54. 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
55. 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;
}
});
57. Refactored view
Ext.define('UserForm', {
extend: 'Ext.FormPanel',
width: 400,
height: 400,
// Returns true if User is valid
isValid: function () {
return this.model.isValid();
}
});
58. Avoid private code
• Avoid overuse of private functions in
closures
• If your code cannot be accessed it cannot
be tested
59. 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.
61. 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.