Menu

Unit Testing and E2E Testing an Aurelia SPA (CLI)

Testing an Aurelia SPA

Welcome to the seventh episode about writing an Aurelia SPA. This time we write some unit tests for our custom components.
We also set up E2E testing, something that most of the other Aurelia skeletons come pre packaged with, but that can be a bit messy for a CLI created project.

The “Aurelia SPA built with TypeScript and Sass on .NET Core” Series

These are the parts of this blog post series about building a SPA in Aurelia.

Aim of This Post

In this post we’ll take a look at testing the code for our Aurelia SPA (built with the Aurelia CLI).
We’ll look at unit testing, have a small word about testing private TypeScript methods. Something that’s missing in the basic CLI project setup, is E2E testing using Protractor, so we’ll set that up as well.

Unit Testing

For this article I rewrote the Network service to use TypeScript’s async/await. I’m going to use that for some unit tests.

There’s also tests where I use the Network service to call a Web Service. That is a mix between a unit and an integration test. I’m using
However it’s useful to see how to handle asynchronous tests.

Modifying the File Structure for Unit and End to End Tests

First of I’m going to move around the tests a bit in the folder structure.
Under the tests folder, create a new folder named unit. Under the unit folder I prefer to have folders for each resource type as well, so now I also created a folder named elements.

If you want to setup e2e testing, also create a folder for the end to end tests, name it e2e. Under the e2e folder, create another one named src.

Modifying the Test Setup in the Configuration

To support the new file structure, we need to change the aurelia.json config file.
Modify the unitTestRunner section like this:

Testing Web Components

Aurelia has a neat component tester that let’s us create our elements in isolation, and then run tests on them. Perfect for unit testing your custom components and making sure they render correct HTML.

Let’s write a test for the droid-tile element we created in a past article, to see how the component tester works.
First I added some new classes to the elements I wanted to test, making locating the elements easier:

So the, in my opinion ugly, added new classes is only used to find the element for the unit tests.

The alternative is to rely only on the structure of the entire custom element, to find the specific element that is to be tested. And in my opinion, relying on the structure of the element will just lead to a lot of refactoring of the tests. Therefore, as long as your team agrees not to put any kind of styling on the added classes, they are the lesser evil.

At least if the main parameter being considered is development velocity and not code terseness.

Testing Private Methods in TypeScript

Testing private methods is always messy. Often it comes down to special trickery when needing to access private methods. A problem that haven’t been about long for JavaScript, but has been prevalent for a long time for other languages.

As for testing private TypeScript methods you will boil down to either choosing to:

Forfeit using private as a scope modifier, to enable access to the methods you need to test

Expose the private methods you need to test in some kind of proxy

There is a school that says “you only need to write tests for the API of your classes”, aka the public surface.
But I sometimes prefer to create tests for small private methods as well, at least when they contain tricky logic that I really need to be sure about.

My preference is to create a public object that exposes the private methods that I want to test, and I place it below all other private methods in my files.
In the Network class it looks like this:

public __test = {
copyBase: this.copyBase
}

A simple object, exposing the method that needs to be tested. And we can use it from the test specs like this:

Adding a Better Karma Reporter

The default Karma test reporter only reports failed tests. But I prefer to see all the tests run, even the passing ones.

Let’s install another reporter, that present us with a little more information about our unit tests:

npm install karma-spec-reporter --save-dev

Then modify karma.conf.js, located in the root of the project.
Change the reporters property to be [‘spec’].

Running the Unit Tests

Start the tests with au test, and add a --watch on the end if you prefer to run them under a watcher.
The result looks something like the following.

End to End Testing (e2e)

A certain amount of code wrangling is required to get E2E testing setup with the CLI. In many of the Aurelia Skeleton apps it’s already setup, but if you like using the CLI there are a few extra steps we need to execute.

What’s needed to get e2e testing running n the CLI project is:

Add required dependencies

Create protractor.conf.js and aurelia.protractor.js in the root of the project

Add e2e.ts and e2e.json in the aurelia_project/tasks

Add a e2eTestRunner section in the aurelia_project/aurelia.json file

Add Dependencies

Install the needed dependencies:

npm install --save-dev del
npm install --save-dev gulp-protractor

Add the Protractor Configuration

The Protractor setup needs a config, create a new file and the following code:

Write a E2E Test Spec

Write a spec and put it under tests/e2e/src.

This is a sample spec that loads the Home page and checks the browser title and verifies that it has the correct name. The second test executes a click on the navigation element, waits for the browser to navigate, then checks the browser title and makes sure it has navigated.

Running the E2E Tests

During the execution you will see a browser start, and might even see the Aurelia SPA we built flicker for a bit:)
The result:

Conclusion

Setting up testing is one thing, but in my opinion, the hardest part about testing is actually writing good tests. The tests in this post was very simple, but hopefully proved to be a quick way to get started for you.