Unit Testing my Durandal code

1,579 views
Skip to first unread message

Gary Robinson

unread,
Oct 9, 2013, 2:32:37 PM10/9/13
to duran...@googlegroups.com
I'm planning on using Durandal to build my app, and I'm using the HTML Starter Kit as the basis for my initial experimentation/learning.

Of course, it's essential that I have a way of unit testing my code. Durandal includes the Durandal Test Framework (https://github.com/BlueSpire/Durandal/tree/master/test) but it appears to be for internal Durandal testing, and it wasn't immediately obvious to me how to use it as the basis for testing my own code that I write in the context of the Starter Kit. When I tried, I immediately got incomprehensible errors and a phantomjs hang:

Error: Script error
http://requirejs.org/docs/errors.html#scripterror
  file:///Users/garyrob/Source/Durandal%20Projects/HTML%20StarterKit%20(Durandal%202.0)%20Exp%202/lib/require/require.js:32
  file:///Users/garyrob/Source/Durandal%20Projects/HTML%20StarterKit%20(Durandal%202.0)%20Exp%202/lib/require/require.js:12 in C
  file:///Users/garyrob/Source/Durandal%20Projects/HTML%20StarterKit%20(Durandal%202.0)%20Exp%202/lib/require/require.js:29


That was very frustrating, but after some time spent playing with it, I noticed that the problem is that the paths in spec.html aren't compatible with the paths in the HTML Starter Kit. All I had to do was change some of those paths (the ones for durandal, plugins, and transitions), and I could add the test directory from the Durandal Test Framework into the HTML Starter Kit (at the same level as the lib, css, and app directories), and all was well.

I was about to blog about how a developer can unit test his Durandal code, by basically doing what I said above: take the test directory, add it to your own project, and modify the paths in spec.html. If I had been able to find a blog post about that, it would have saved me significant time.

But it occurred to me that it might be a good idea to ask about it here, before I do that, in case anyone has any other useful advice that I should know about adopting the Durandal Test Framework to work a developer's own code. So... if anyone has any feedback or advice, I'd really appreciate it!

Thanks,
Gary

Rob Eisenberg

unread,
Oct 9, 2013, 2:46:47 PM10/9/13
to Gary Robinson, duran...@googlegroups.com
Gary, thanks so much for posting this. Actually, one of the best things you can do to help the Durandal community right now is go out and write that blog post. If you want me to review it before you post it, I'm happy to do so. After you do post it, send me a link and I will tweet it. If you want to go the extra mile.....then consider writing a markdown file and sending that to me ;) That would enable me to incorporate your work directly into our official documentation. Anything you can do to help is always appreciated...and I apologize for the frustration.


--
You received this message because you are subscribed to the Google Groups "DurandalJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to durandaljs+...@googlegroups.com.
Visit this group at http://groups.google.com/group/durandaljs.
To view this discussion on the web visit https://groups.google.com/d/msgid/durandaljs/20cd86f5-e9e3-4aa4-8f70-cf58827373cc%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Rob Eisenberg,
President - Blue Spire
www.durandaljs.com

Rainer Wittmann

unread,
Oct 9, 2013, 3:21:50 PM10/9/13
to duran...@googlegroups.com
As an alternative you might give grunt a try. As a bare minimum you'd need grunt-contrib-jasmine and grunt-requirejs, but using grunt-contrib-jshint in addition will help catching issues even before testing.

Christopher Shepherd

unread,
Oct 10, 2013, 6:33:13 AM10/10/13
to duran...@googlegroups.com
I've had some success using Squire.js (https://github.com/iammerrick/Squire.js).

I'll try and put a post together about how I integrated it using QUnit.

Rob Eisenberg

unread,
Oct 10, 2013, 8:18:45 AM10/10/13
to Christopher Shepherd, duran...@googlegroups.com
That would be great! If you want to write a markdown file, that's another good candidate for the official docs. On a related note, I was talking to an Ember aficionado the other day and he was lamenting that people think that Angular is the only framework that allows for testable code, while the story for Ember was as good if not better. I told him that Durandal apps are pretty easy to test as well. So, I think it's really important to get the word out there on this in a big way via blogs, docs, etc. because the Angular marketing is making both Ember and Durandal look as if they produce untestable code, which is obviously far from the truth. I'm also considering an additional download that is a pre-configured test setup and maybe adding some things like that to the starter kits too. Any feedback is welcome.


--
You received this message because you are subscribed to the Google Groups "DurandalJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to durandaljs+...@googlegroups.com.
Visit this group at http://groups.google.com/group/durandaljs.

For more options, visit https://groups.google.com/groups/opt_out.

Rainer Wittmann

unread,
Oct 10, 2013, 9:25:03 AM10/10/13
to duran...@googlegroups.com

Testing of individual viewmodels works fine.
I'm unsure if a functional testing (main.js) shouldn't be better done with something like selenium, sauce lab etc.

Nevertheless I gave it a try, but currently Durandal stops loading with a failure in app.js line 44. Might be me setting up something wrong of course.


On Wednesday, October 9, 2013 8:32:37 PM UTC+2, Gary Robinson wrote:

Gary Robinson

unread,
Oct 10, 2013, 12:39:05 PM10/10/13
to duran...@googlegroups.com, Gary Robinson, r...@bluespire.com
Rob, I've attached markdown for the post I'm planning to put on my blog. If I'm missing anything, I'd really appreciate any feedback. If you have any use for all or some of the text in Durandal docs, that would be fun.
durandal_unit_tests.txt

Rob Eisenberg

unread,
Oct 10, 2013, 12:40:53 PM10/10/13
to Gary Robinson, duran...@googlegroups.com
Thanks!

Gary Robinson

unread,
Oct 10, 2013, 12:49:43 PM10/10/13
to duran...@googlegroups.com, Gary Robinson, r...@bluespire.com
The attachment here has some improvements over the markdown I sent with my previous post.


On Wednesday, October 9, 2013 2:46:47 PM UTC-4, EisenbergEffect wrote:
durandal_unit_tests.txt

Christopher Shepherd

unread,
Oct 10, 2013, 3:25:59 PM10/10/13
to duran...@googlegroups.com, Gary Robinson, r...@bluespire.com
Gary, any chance of posting a complete version to Github?

Will be useful to point people to from the documentation. I'll fork and show how to use Squire.js then too.

Chris

Gary Robinson

unread,
Oct 10, 2013, 5:54:44 PM10/10/13
to duran...@googlegroups.com, Gary Robinson, r...@bluespire.com
Hi Chris,


I don't see that there's really anything for me to post in Github. All I'm really saying is that you can use Rob's "Durandal Testing Framework" for your own unit testing if you change a few paths in his spec.html. That's already on Github at https://github.com/BlueSpire/Durandal/tree/master/test.

If I'm misunderstanding what you're asking for, let me know.

Thanks,
Gary

Gary Robinson

unread,
Oct 11, 2013, 4:11:05 PM10/11/13
to duran...@googlegroups.com, Gary Robinson, r...@bluespire.com
In case it's of interest, I posted to my blog about this. My earlier post about my perspective on SPA (and Durandal) as a Python developer had a reach >1,300 people according to Feedburner. I expect to be posting more Durandal-specific posts as I figure out how to do things that other people might like help with. My blog's at  http://www.garyrobinson.net in case anyone wants to see it; I've set up a Durandal-specific RSS feed for this and future posts.


On Wednesday, October 9, 2013 2:46:47 PM UTC-4, EisenbergEffect wrote:

Rob Eisenberg

unread,
Oct 11, 2013, 4:16:45 PM10/11/13
to Gary Robinson, duran...@googlegroups.com
Awesome. Subscribed :)

Jonathan Curtis

unread,
Oct 15, 2013, 10:53:56 AM10/15/13
to duran...@googlegroups.com
Hi Gary,

I actually setup the test framework for Durandal. I think testing a framework is a bit different to how you'd want to test your application. If you just test the javascript, you are missing out on a whole layer in the HTML/CSS that is untested.

Our application UI tests exercise the entire UI stack. We use PhantomJS with Casper.js to drive the application and mock out the ajax requests using Sinon.js. This makes our tests lightning fast with no external dependencies. We have also built a CSS regression test framework that uses the PhantomJS screenshot capability to compare CSS changes. Other than that we create test data builder objects for the mocked ajax calls and objects that model the interaction with the UI, to isolate the tests from CSS selectors that Casper requires.

Before now we were working with a pre-durandal product, but are about to start work on a new project using Durandal. This will change the way we test; with Durandal you can easily test components in isolation, as we can just swap out the root composition view model.

Cheers,
Jon

Gary Robinson

unread,
Oct 18, 2013, 2:49:54 PM10/18/13
to duran...@googlegroups.com
Hi Jonathan,

Sorry for the slow reply, I was very busy with a project this week.

I want to be sure I understand what you're saying. You wrote

I actually setup the test framework for Durandal.

but the Durandal site lists EisenbergEffect as the author of the "Durandal Test Framework" that can be found there. Is that misleading, or are you talking about something else, like the internal framework for testing your own company's projects?

Sounds like you have a very nice test setup for your application -- I take it that you're not describing something that's publicly available, other than the PhantomCSS framework (which looks very cool!)

Regards,
Gary

Rob Eisenberg

unread,
Oct 18, 2013, 2:58:27 PM10/18/13
to Gary Robinson, duran...@googlegroups.com
Jonathan is the one who initially contributed the test setup and configuration for the Durandal project. It sounds like he has some other stuff he's worked out for his own projects as well. @Jonathan, if you want to write a little markdown file about that...I'd love to add it to the site along side Gary's article :)


--
You received this message because you are subscribed to the Google Groups "DurandalJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to durandaljs+...@googlegroups.com.
Visit this group at http://groups.google.com/group/durandaljs.

For more options, visit https://groups.google.com/groups/opt_out.

Tyrsius

unread,
Oct 18, 2013, 7:27:21 PM10/18/13
to duran...@googlegroups.com
So I have been working on getting the Unit Test Framework to work with some real app code, and I have had to make a lot of changes, so I figured I would share my findings with eveyrone.

The biggest issue I had was that singleton modules would only get loaded once, which means one test file could interfere with another test file by mucking with its dependencies. I modified the spec file to run each test file in a fresh page object. To get the tests to total up correctly, instead of each spitting out their own "finished" report, I had to modify the console-reporter. The changes to the console are probably pretty messy, but I didn't dig too deep into that stuff. The last change I had to make was to use jasmine.async for testing promises, since without it tests would finish before their promised "expects" would run. I also had to modify the way Durandal started itself, so that the plugins used by the modules I was testing got installed by Durandal.

I have attached a super-slimmed up project with these changes. The site won't run (I stripped out way to much stuff), but the Javascript tests will. I included a .bat file in the root that will execute the tests (if you aren't running it from inside visual studio, you will want to add a "pause" line to the end of it).

Rob Eisenberg

unread,
Oct 18, 2013, 7:42:23 PM10/18/13
to Tyrsius, duran...@googlegroups.com
If you feel so inclined....writing a markdown file that I can add to the official site docs to accompany Gary's article would be great ;)


--
You received this message because you are subscribed to the Google Groups "DurandalJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to durandaljs+...@googlegroups.com.
Visit this group at http://groups.google.com/group/durandaljs.

For more options, visit https://groups.google.com/groups/opt_out.

Arcie Ramos

unread,
Nov 1, 2013, 1:32:12 PM11/1/13
to duran...@googlegroups.com
Hello,

Do you have this post up anywhere?

This is exactly what I am trying to do (unit test my Durandal-based project) and I already have QUnit working, I just need any documentation I can get in regards to getting it working with Squire.

Thank you.

Gary Robinson

unread,
Nov 1, 2013, 2:16:05 PM11/1/13
to Arcie Ramos, duran...@googlegroups.com
--
You received this message because you are subscribed to a topic in the Google Groups "DurandalJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/durandaljs/xwxO5THIx_8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to durandaljs+...@googlegroups.com.

Jonathan Curtis

unread,
Nov 26, 2013, 11:03:23 AM11/26/13
to duran...@googlegroups.com, Arcie Ramos
We've recently started work on our first Durandal project, so I thought it would be good to contribute back a demonstration of how we test our application. I've created a test suite for the HTML starter kit, which you can see here:


To get it running, you just need to go to browse to /test.html in the HTML starter kit. If you are using firefox, you can do this from the file system. You should see a scenario HTML page that has been generated from a previous test run. It shows the status of all current scenario and steps, with stack traces for errors and allows you re-run any test in the browser (opens a new tab). The tests output to the console by default, so open dev tools/firebug and you can see the test running, insert breakpoints, etc.

Durandal's compositional approach gives a unique opportunity to test applications in a different way from most other frameworks. It makes it easy to test modules in isolation, which is key to creating a maintainable test suite. To facilitate this, I created a test framework that makes it easy to test durandal applications:


The main idea behind the test runner that comes with the test framework is that we should be able to run tests both in the browser and headless via a console runner using phantomjs. To setup testing for your own application, have a look at main-test.js. This shows how we add some extra paths for the tests, the test library and mocked modules (in this case the http module). You will notice on line 44, we call testRunner.run() rather than app.setRoot. This is so we can "hook" into the application and have the tests drive the app. The test runner uses window.location.hash to denote which test to run, which will be the id of the test module. Note this does not use routing module and you can still test the routes of you application. You should be able to see from an individual test what is going on, eg flickr page test

The ScenarioRunner.exe is a console app that allows you to run the tests in parallel, report to team city, output the scenario.html and take screenshots.

It's a bit rough around the edges, but hopefully is of some use. If there is any interest I can write a blog post with more detail.

Cheers,
Jon
Reply all
Reply to author
Forward
0 new messages