Why do we do SPAs (Single Page Applications)? For glory, gold and girls! Yea, sure, in the end it’s all of those things, BUT what are the low level, basic, crude and atomic reasons? There are few:
- because we don’t like to mix server tech with client-side tech
- because we want to truly separate presentation from business logic
- because we desire our front-end being TESTABLE
Yes, SPAs are more testable than traditional approach to server-generated web apps. Same applies to my beloved angular.js - it supports automated testing by design and it promotes two different approaches:
- Unit tests - you test particular app element(s): filters, directives, controllers, services, etc. These tests are purely technical and are aimed to test particular components regardless of their context.
- E2E (scenario) tests - you test your application end-to-end: it means that all your interactions are on the user interface (browser) level and tests are mimicking actual usage scenarios. These tests are more BDD-like and are more easily understandable by non-technical people.
This blog post will about the second category of these tests, because there were some recent changes worth mentioning. If you want a full-fledged post about the differences, here’s your place: http://www.yearofmoo.com/2013/09/advanced-testing-and-debugging-in-angularjs.html
Until recently, if you wanted to do E2E tests for angular.js you were pretty much limited to using the library named ‘angular-scenario.js' within Karma. This library was very helpful (because it was aware of $digest cycle, so it knew how long 'to wait' until screen is fully rendered (and values are bound), but unfortunately:
- it’s API was VERY limited (it was aiming to dupe Jasmine, but it was far from that)
- if you wanted more time / event control - it was very hard to achieve
That’s why ‘old’ library is now in maintenance mode (gets deprecated) and a ‘new player’ appeared - a mechanism named Protractor (https://github.com/angular/protractor/blob/master/docs/getting-started.md). So, why is it better and what’s the true benefit for using it?
- It runs on packaged components: Selenium & Jasmine, so authors of Protractor don’t have to duplicate other solutions - they can focus only on what’s specific for angular.js.
- *Full* Jasmine API is available - that’s SIGNIFICANTLY more than what was published in E2E scenario API.
- In front-end tests you _will_ have to refer to DOM - that’s unavoidable, but in old library you were doing that using CSS selectors -> they work indeed, but they are barely readable (and maintainable). Protractor is _much_ better, because it is able to do querying DOM by angular.js specific domain entities - for instance model properties, bindings, repeat phrases, etc. It makes tests much more readable, even without creating intermediate DSL layer.
- Much better input (keyboard) control - I had to hack faking keyboard short-cuts in E2E scenario tests, in Protractor I’ve managed to do well with out-of-the-box solution.
- Same applies for conditional assertions - now you can treat every check as a promise and use then() function to set up a conditional check (it was far less convenient using query() in E2E scenario tests in angular-scenario).
- Protractor is far more rigorous about validating actions - if you were not careful enough, you could have asked for 'click' event on disabled DOM element in angular-scenario and there was no error reported: Protractor is much more cautious about such validations.
- It has some absolutely killer features, because it’s aware of angular.js syntax set in data annotations on the web page - it can evaluate something (function, symbol) in scope of given element (!) or for instance grab your console logs :)
Keeping all that in mind - IMHO Protractor is the best option for someone who wants to do solid E2E tests in Angular.js apps - highly recommended.