unit and functional testing with siesta
DESCRIPTION
Mats Bryntse at ModUX 2013TRANSCRIPT
Unit and functional testing with Siesta
Mats Bryntse, developer at Bryntum@bryntum
Wednesday, September 25, 13
Mats Bryntse
• Ext JS developer since 2007
• Started Bryntum 2009
• Components & tools for the Sencha ecosystem
• www.bryntum.com
Wednesday, September 25, 13
Agenda
• Benefits of Siesta in your project
• Writing your first unit Siesta test
• Functional testing
• New Siesta features & improvements
Wednesday, September 25, 13
Do you test your JS?
Wednesday, September 25, 13
3 benefits of Siesta
Wednesday, September 25, 13
Unit + Functional tests
Wednesday, September 25, 13
Wednesday, September 25, 13
Wednesday, September 25, 13
A look at the Siesta UI
Wednesday, September 25, 13
Wednesday, September 25, 13
What should I test?
Wednesday, September 25, 13
Test Model layer first
Wednesday, September 25, 13
Test Model layer first• Easy to test, high ROI.
Wednesday, September 25, 13
Test Model layer first• Easy to test, high ROI.
• Your.data.Model
Wednesday, September 25, 13
Test Model layer first• Easy to test, high ROI.
• Your.data.Model
• Your.data.Store
Wednesday, September 25, 13
Test Model layer first• Easy to test, high ROI.
• Your.data.Model
• Your.data.Store
• Your.util.Class
Wednesday, September 25, 13
Test Model layer first• Easy to test, high ROI.
• Your.data.Model
• Your.data.Store
• Your.util.Class
• Focus on one class per test file
Wednesday, September 25, 13
Test Model layer first• Easy to 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
Wednesday, September 25, 13
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
Wednesday, September 25, 13
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
Wednesday, September 25, 13
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
Wednesday, September 25, 13
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
Wednesday, September 25, 13
Wednesday, September 25, 13
Using PhantomJS (or Selenium)
Wednesday, September 25, 13
Testing views
Wednesday, September 25, 13
Testing views
• Normally, your app consists of many view classes
Wednesday, September 25, 13
Testing views
• Normally, your app consists of many view classes
• Test your components in isolation:
Wednesday, September 25, 13
Testing views
• Normally, your app consists of many view classes
• Test your components in isolation:
• My.app.UserList
Wednesday, September 25, 13
Testing views
• Normally, your app consists of many view classes
• Test your components in isolation:
• My.app.UserList
• My.app.OrderForm
Wednesday, September 25, 13
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
Wednesday, September 25, 13
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
Wednesday, September 25, 13
http://github.com/matsbryntse
Wednesday, September 25, 13
10 Sanity tests
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules5. It does not use global style rules ('.x-panel' etc)
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules5. It does not use global style rules ('.x-panel' etc)6. It can be sub-classed
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules5. It does not use global style rules ('.x-panel' etc)6. It can be sub-classed7. It does not leak any additional components or DOM
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules5. It does not use global style rules ('.x-panel' etc)6. It can be sub-classed7. It does not leak any additional components or DOM8. It doesn't override any private Ext JS methods
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules5. It does not use global style rules ('.x-panel' etc)6. It can be sub-classed7. It does not leak any additional components or DOM8. It doesn't override any private Ext JS methods9. It can be created, destroyed
Wednesday, September 25, 13
10 Sanity tests1. Your namespace is created, global variable leaks.2. Your component can be loaded on demand3. No global Ext JS overrides4. Basic JsHint rules5. It does not use global style rules ('.x-panel' etc)6. It can be sub-classed7. It does not leak any additional components or DOM8. It doesn't override any private Ext JS methods9. It can be created, destroyed10. It passes a basic monkey test
Wednesday, September 25, 13
Functional testing
Wednesday, September 25, 13
Functional testing
• Interacting with the UI as a real user
Wednesday, September 25, 13
Functional testing
• Interacting with the UI as a real user
• Hard to solve w/ tools focusing on raw DOM/HTML.
Wednesday, September 25, 13
Functional testing
• Interacting with the UI as a real user
• Hard to solve w/ tools focusing on raw DOM/HTML.
• Siesta allows you to simulate user interactions:
Wednesday, September 25, 13
Functional testing
• Interacting with the UI as a real user
• Hard to solve w/ tools focusing on raw DOM/HTML.
• Siesta allows you to simulate user interactions:
• type
Wednesday, September 25, 13
Functional testing
• Interacting with the UI as a real user
• Hard to solve w/ tools focusing on raw DOM/HTML.
• Siesta allows you to simulate user interactions:
• type
• click
Wednesday, September 25, 13
Functional testing
• Interacting with the UI as a real user
• Hard to solve w/ tools focusing on raw DOM/HTML.
• Siesta allows you to simulate user interactions:
• type
• click
• drag
Wednesday, September 25, 13
Query Power
Wednesday, September 25, 13
Query Power
- CSS Query “.x-btn”
Wednesday, September 25, 13
Query Power
- CSS Query “.x-btn”
- Component Query “>>button”
Wednesday, September 25, 13
Query Power
- CSS Query “.x-btn”
- Component Query “>>button”
- Composite Query “gridpanel => .x-grid-cell”
Wednesday, September 25, 13
Targeting demo
Wednesday, September 25, 13
Siesta news
Wednesday, September 25, 13
Siesta news
• 2.0: New User Interface
Wednesday, September 25, 13
Siesta news
• 2.0: New User Interface
• Auto-scroll element into view
Wednesday, September 25, 13
Siesta news
• 2.0: New User Interface
• Auto-scroll element into view
• Assertion detecting global Ext JS overrides
Wednesday, September 25, 13
Siesta news
• 2.0: New User Interface
• Auto-scroll element into view
• Assertion detecting global Ext JS overrides
• Assertion to detect unnecessary layouts
Wednesday, September 25, 13
Siesta news
• 2.0: New User Interface
• Auto-scroll element into view
• Assertion detecting global Ext JS overrides
• Assertion to detect unnecessary layouts
• Code coverage
Wednesday, September 25, 13
Siesta.next
Wednesday, September 25, 13
Siesta.next
• UI Localization, Japanese translation
Wednesday, September 25, 13
Siesta.next
• UI Localization, Japanese translation
• Guides + blog posts
Wednesday, September 25, 13
Siesta.next
• UI Localization, Japanese translation
• Guides + blog posts
• Test recorder
Wednesday, September 25, 13
Siesta.next
• UI Localization, Japanese translation
• Guides + blog posts
• Test recorder
Wednesday, September 25, 13
Recorder demo
Wednesday, September 25, 13
Questions?
Wednesday, September 25, 13