Testing my patience

As promised, I’m trying to get into automated testing with Javascript (as a start).  It was a tough sell for me- the idea of writing tests to cover every aspect of your code, as well as writing the code itself, seemed like doubling my workload.  Not to mention the complexities of testing in a browser-based environment.  After some reading, basic testing seemed to make sense- check that a function returns what it should- but what about a bunch of jQuery DOM manipulation functions.  They don’t return anything, but have multiple side effects- how do I test those?

Of course, wiser folks are shaking their heads and telling me that tests are a great way of catching errors before they become bugs- or eliminating the need for manually testing every edit/addition, then adding console.log statements all over your code when you can’t figure out what’s going wrong.

But what really got me to dig in and start testing was the idea of regression.  A code base starts out small, but eventually, it will likely get very large.  The goal is modularity- one aspect not necessarily altering another- but that doesn’t always work, and sometimes. modules have to interact with each other.

A code base is also a living thing- it has to be updated frequently: bugs squished, features added, etc.  And, frequently, when you edit or add to that code base, you’re at risk of breaking something somewhere else- or something right there in the feature you’re editing.  Automated testing really makes sense for this.  Cover your code with enough tests as you go, and any future edits/additions that break something deep inside (or in the same feature) will break those tests- you’ll know right away.

With my main project- a brand new Angular 2 application, I’ve started writing tests using Jasmine.  And it’s really great so far.  The hardest part (as with any Javascript framework these days) was setup.  Configuring Jasmine to run tests on Angular services (still working on components) and getting systemjs to play along was a bit tricky.  The docs at angular.io (and the docs at jasmine.github.io are great, but I did run into one ‘gotcha’.

As a total test newbie, I wanted to do a couple basic ones just to make sure everything was linked up properly.  So I threw in a couple:

it('should add correctly', () => {
    expect(2+2).toEqual(4);
});

But for some reason, in the Angular 2 template test environment, all my tests were running twice. They correctly passed or failed, but everything was duplicated.

The dual culprits were my stupidity and my inexperience.  In the template test env, Angular has you do a system.js config in  your main test index .html page (where Jasmine will show your results).  After that, you use system.import(‘your-test-file-here’), then chain a .then(window.onload) command.  Import returns a promise that resolves when your test file is found and loaded.  Then it fires a window refresh to recognize your new file (Jasmine doesn’t have a ‘fire’ method).

I took out .then(window.onload) and it worked great- each test ran once.  But then I went further.  I wrote some basic tests for an actual Angular service (showing/hiding a loader component).  And the test broke again- it couldn’t load any Angular.  So I added .then(window.onload) back in- and it worked great!  Because I wanted to test the tests, I stumbled into a bug that no one had probably even noticed (probably can’t really call it a bug- everything worked as it was supposed to, technically).

So, the moral is: if you’re testing Angular, use the window.onload call- it’s necessary.  If you’re just running tests to test your test setup, leave it out.

Test (had to say it one more time).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s