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

Ember TDD - Unit & Integration Testing with Mocha

Ember TDD - Unit & Integration Testing with Mocha

Presentation given at the @EmberATX July 25th meetup

Jeff Schilling

July 25, 2013
Tweet

Other Decks in Programming

Transcript

  1. TENETS OF EMBER TESTING • Disables Ember run loop •

    Provides maximum control to tests Ember.testing = true; Thursday, July 25, 13
  2. TENETS OF EMBER TESTING • Wrap test code in Ember.Run

    to invoke runloop Ember.run(function() { this.set('someProperty',true); }); Thursday, July 25, 13
  3. MY TEST RIG • Mocha/Chai • Support for both expect/should

    • Karma • Server + kicker job to autobuild • Reporters = progress, coverage, growl Thursday, July 25, 13
  4. GLOBAL TEST CONFIG Ember.testing=true; expect = chai.expect; mocha.setup({ ui: 'bdd',

    reporter: 'html', globals:['XMLHttpRequest','jQuery*'] }); $().ready(function() { // Is the div to attach view DOM tests using `view.appendTo('#fixture')`. // Remember to view.destroy(). $('<div id="fixture" style="display:none;"><div>').appendTo('body'); }); // Define some utility methods to make tests more concise window.testLookup = function(identifier) { 'use strict'; return App.__container__.lookup(identifier); }; Thursday, July 25, 13
  5. TESTING MODELS Class methods & computed properties it('should clone itself

    from a template', function() { var plan = App.ReportPlan.createFromTemplate(template); expect(App.ReportPlan.detectInstance(plan)).to.be.ok; plan.get('title').should.equal('ACH Activity Report'); }); Thursday, July 25, 13
  6. TEST CONTROLLERS * Above is simplest possible - multi selection,

    content changes etc = +1 for tests beforeEach(function() { testContent = [1, 2, 3, 4, 5, 6]; }); it('should have selection', function() { var myArray = Q2.ArrayController.create({ content: testContent, selections: [] }), targetObject = testContent.objectAt(0); myArray.select(targetObject); myArray.get('selection').should.equal(targetObject, "should be equal"); }); Thursday, July 25, 13
  7. TESTING VIEWS Unit test views that have dynamic layouts it('should

    emit n dots based on content length', function() { Ember.run(function() { pageView.appendTo('#fixture'); pageView.set('content', Q2.NavigableList.create({ content: [1, 2, 3, 4, 5, 6] })); }); pageView.$('.dot').should.have.length(6, "should have six dots"); }); Thursday, July 25, 13
  8. TESTING HELPERS Lots of these it('should not add commas to

    number less than 1000', function() { testView('{{formatNumber view.value}}', 999).should.equal('999'); }); it('should add commas to numbers greater than 1000', function() { testView('{{formatNumber view.value}}', 1000).should.equal('1,000'); }); Thursday, July 25, 13
  9. FIXTURES/MOCKS AND SPIES • Mock datasource • ember-data fixtures •

    homebrew fixtures • ensure call model replicates real world e.g. async • Sinon • spy • fakeClock Thursday, July 25, 13
  10. FAST TRACK TIME var clock; before(function() { clock = sinon.useFakeTimers();

    }); after(function() { clock.restore(); }); it('should start a long running task', function(done) { var wasCalled = 0; App.LongRunner.run(function() { wasCalled = wasCalled + 1; }, 10); clock.tick(12); expect(wasCalled).to.equal(1); done(); }); Thursday, July 25, 13
  11. COVERAGE IS YOUR FRIEND • identify hidden corners • correlation

    to defect count * not a direct proxy for quality Thursday, July 25, 13