Hello all,
I’ve been struggling for countless hours getting testing setup for our ember app. We’ve put it off for too long (nearly at production now) and we are finding we really need the integration tests. I’ve read countless articles, watched a handful of videos, dug through jsbins, gists, other apps, you name it I’ve looked at it.
We setup our project using generator ember and yeoman and we had issues with the built in mocha/chai so we decided to go with Qunit and testem. I’ve managed after a few hours to get it setup so I can run grunt testem and grunt will run testem under a ci environment. It works fine if I have a static test that doesn’t do anything, but once it starts to do something I run into Uncaught Error: Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an run.
Ok well I’ll wrap the test code in this, wrong I was there. After googling and coming up with mostly useless (and potentially outdated) articles I decided to take to the emberjs channel on freenode. The only response I got was switch to ember-cli. This wasn’t helpful as the project lead is not interested in switching as there is no reason why the testing in there should work and not in our project. I then found this which says to wrap pretty much everything in Ember.run(function(){}); After spending a few hours doing that to the entire app not only did it not work but it broke the app in the process.
which has only added to the frustration.
Can someone please help me get this setup? Testing you application shouldn’t be this hard.
Useful snippets:
test.js
/* global describe, it */
/* jshint ignore: start */
// put app in qunit-fixture
App.rootElement = '#qunit-fixture';
// turn on testing mode
App.setupForTesting();
App.injectTestHelpers();
module("Testing the homepage", {
setup: function () {
App.reset();
App.injectTestHelpers();
}
});
test("Can login", function () {
expect(1);
visit("/login");
fillIn("#email", 'email@email.com');
fillIn('#password', 'test');
fillIn('#organization', 'test');
click('button');
andThen(function(){
equal(currentURL(), '/', 'Moved to homepage');
});
});
/* jshint ignore: end */
test index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Web App Testing</title>
<link rel="stylesheet" href="../app/bower_components/qunit/qunit/qunit.css">
<link rel="icon" type="../app/images/png" href="images/logo_mini.png" />
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../app/bower_components/jquery/jquery.js"></script>
<script src="../app/bower_components/handlebars/handlebars.runtime.js"></script>
<!-- Bootstrap 3.1.1 -->
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/affix.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/alert.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/dropdown.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tooltip.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/modal.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/transition.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/button.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/popover.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/carousel.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/scrollspy.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/collapse.js'></script>
<script src='../app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tab.js'></script>
<!-- End Bootstrap 3.1.1 -->
<script src="../app/bower_components/momentjs/min/moment.min.js"></script>
<script src="../app/bower_components/d3/d3.min.js"></script>
<script src="../app/bower_components/nvd3/nv.d3.min.js"></script>
<script type="text/javascript" src="../app/bower_components/ember/ember.js"></script>
<script src="../app/bower_components/ember-data/ember-data.js"></script>
<script src="../app/bower_components/magnific-popup/dist/jquery.magnific-popup.min.js"></script>
<script src="../app/bower_components/blueimp-md5/js/md5.min.js"></script>
<script src="../app/bower_components/bootstrap-tour/build/js/bootstrap-tour.js"></script>
<script src="../app/bower_components/ember-nvd3/build/ember-nvd3.js"></script>
<script src="../app/bower_components/jsSHA/src/sha.js"></script>
<script src="../app/bower_components/ember-data.model-fragments/dist/ember-data.model-fragments.js"></script>
<script src="../app/bower_components/pdfjs-bower/dist/pdf.js"></script>
<!-- PDFJS -->
<script src="../app/bower_components/pdfjs-bower/dist/compatibility.js"></script>
<!-- PDFJS -->
<script src="../app/bower_components/c3/c3.min.js"></script>
<!-- C3 -->
<script src="../app/bower_components/ember-c3/build/lib.js"></script>
<!-- Ember-C3 -->
<script src="../app/bower_components/pikaday/pikaday.js"></script>
<!-- Pikaday -->
<script src="../app/bower_components/ember-pikaday/build/lib.js"></script>
<!-- Ember-Pikaday -->
<script src="../app/bower_components/cubism/cubism.v1.js"></script>
<!-- Cubism -->
<script src="../app/bower_components/select2/select2.js"></script>
<!-- Select2 -->
<script src="../app/bower_components/ember-select2/build/lib.js"></script>
<!-- Ember Select2 -->
<script src="../app/bower_components/bowser/src/bowser.js"></script>
<!-- Bowser -->
<script src="../app/bower_components/favico.js/favico.js"></script>
<!-- Favico.js -->
<script type="text/javascript" src="../app/bower_components/qunit/qunit/qunit.js"></script>
<script type="text/javascript" src="../app/bower_components/ember-qunit/dist/globals/main.js"></script>
<script type="text/javascript" src="../.tmp/scripts/combined-scripts.js"></script>
<script type="text/javascript" src="../.tmp/scripts/compiled-templates.js"></script>
<script type="text/javascript" src="spec/test.js"></script>
</body>
</html>
testem.json
{
"framework": "qunit",
"test_page": "test/index.html",
"launch_in_dev": ["PhantomJS","Chrome"],
"launch_in_ci": ["PhantomJS"]
}
gruntfile.json
// load testem
grunt.loadNpmTasks('grunt-contrib-testem');
...
testem: {
environment1: {
// List of files to attach
src: [
'app/bower_components/**/*.js',
'.tmp/scripts/*.js',
'test/spec/*.js'
],
// Options that will be passed to Testem
options: {
parallel: 8,
launch_in_ci: ['PhantomJS', 'Chrome'],
launch_in_dev: ['PhantomJS', 'Chrome']
}
}
},