Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JDays 2013 - Testing JavaScript with Siesta

Mats Bryntse
November 26, 2013

JDays 2013 - Testing JavaScript with Siesta

My presentation at JDays 2013

www.jdays.se

Mats Bryntse

November 26, 2013
Tweet

More Decks by Mats Bryntse

Other Decks in Programming

Transcript

  1. Who am I? • Started as .NET dev 2003 •

    Full time Ext JS developer since 2007 • Founded Bryntum 2009 • Components & tools for the Sencha ecosystem • www.bryntum.com
  2. Agenda ! •Why test your JS? •What is Siesta? •Writing

    your first unit Siesta test •Functional testing •Event Recorder
  3. Too many variants •Different OS’s •Different browsers •Different browser versions

    (IE7-11) •Strict vs quirks mode •Daylight savings issues •Testing all combinations doesn’t scale
  4. •Built with standard JS/CSS •Test any JS/web/Node codebase •Event simulation

    (click, type etc) •Event recorder •Sandboxed tests, 1 iframe per test •We use it to test all our products Siesta facts:
  5. Test Model Layer First •Easy to unit test, high ROI.

    •Your.data.Model •Your.data.Store •Your.util.Class •Focus on one class per test file •Test your code, not framework code
  6. Ext.define(“My.model.User”, { extend : ‘Ext.data.Model’, ! fields : [‘FirstName’, ‘LastName’,

    ‘Salary’], ! getAnnualSalary : function () { return this.get(‘Salary’) * 12; }, ! isValid : function() { return this.get(‘FirstName’) && this.get(‘LastName’); } }); My.model.User
  7. describe(“Testing my User model”, function(t) { t.it(‘Should get correct annual

    salary’, function(t) { var user = new My.model.User({ Salary : 5000 }); t.expect(user.getAnnualSalary()).toBe(60000); }); ! t.it(‘Should treat incomplete name as invalid’, function(t) { var user = new My.model.User({ FirstName : ‘Bob’ }); t.expect(user.isValid()).toBeFalsy(); }); }) User.t.js
  8. StartTest(function(t) { ! t.it(‘Should be able to get name’, function(t)

    { ! var user = new My.model.User({ FirstName : ‘Bob’ }); t.expect(user.get(‘FirstName’)).toBe(‘Bob’); }); }) Don’t test Ext JS
  9. var Harness = Siesta.Harness.Browser.ExtJS; ! Harness.configure({ preload : [ "http://cdn.sencha.io/ext-4.2.0-gpl/resources/css/ext-all.css",

    "http://cdn.sencha.io/ext-4.2.0-gpl/ext-all-debug.js", "my-app-all-debug.js" ] }); ! Harness.start({ group : 'Model Layer', items : [ 'User.t.js' ] }); Harness.js
  10. Testing views •Normally, your app consists of many view classes

    •Test your components in isolation: •My.app.UserList •My.app.OrderForm •Test your public config properties + API •Sanity tests give you peace of mind
  11. 10 Sanity tests 1. Your namespace is created, no global

    variable leaks. 2. Your component can be loaded on demand 3. No global Ext JS overrides 4. Basic JsHint rules 5. It does not use global CSS rules ('.x-panel' etc) 6. It can be sub-classed 7. It does not leak any additional components or DOM 8. It doesn't override any private Ext JS methods 9. It can be created, destroyed 10. It passes a basic monkey test
  12. Functional testing •More complex than unit testing, involves DOM •Interacting

    with the UI as a user (or cat) would •Siesta allows you to simulate user interactions: • type • click • drag
  13. Targeting the UI •A Sencha application consists of Components •1

    Component === Many HTML elements •HTML is not a good abstraction layer when testing Sencha apps •Markup is generated by the framework.
  14. Query Power - CSS Query “.x-column-header” - Component Query “gridcolumn”

    - Composite Query “gridcolumn => .x-header-text”
  15. Event recorder •Authoring UI tests manually takes time •The Event

    Recorder records user interactions •Understands the Sencha component model •Generates best practice JS test code
  16. Final thoughts… •Testing saves time and time === $$ •Automation

    and CI is key •High code coverage !== working code