Update your package.json file for better tests

By default Angular gives you a couple of commands to run:

npm run start
npm run build
npm run watch
npm run test

These commands get you up and running, you can run the app in the browser, build the final version and run tests in run once.

I like to add a few more commands to my package.json file, these extra ones are:

npm run test:watch
npm run test:coverage
npm run test:ci
npm run lint

These commands give me more options for running my tests, in watch mode, with code coverage and in both watch mode with code coverage. There is also a linting check, which is always helpful for code quality checks.

The full commands in package.json look like this:

"test:watch": "ng test --watch",
"test:coverage": "ng test --code-coverage",
"lint": "ng lint",
"test:ci": "ng test --watch=true --browsers=ChromeHeadless --code-coverage"

Out of all four new commands the most essential one is the test:ci one, which runs my tests in headless mode (which is great as I don’t want to have the Karma runner opening the browser all the time) gives me an overview of all the code covered by tests.

While something like NX will give you more options and use Jest, being able to run these commands in a Angular CLI based project does make running tests easier leaving no reason not to write tests.

Show Some Love for the Angular CLI

I’ve recently listened to the latest episode of Adventures in Angular, a great podcast. In this episode they were discussing the merits of the Angular CLI, what it does for us as Angular developers, how much is saves a company on time and money.

The Angular CLI makes writing Angular applications so fast and easy. Before the CLI we had to handle all the build steps ourselves, using tools like Grunt than Gulp. Both fantastic build tools, but having to fight our way through JSON config files was not easy, especially if you wanted to create the ideal setup for your project. It would take days of tweaking the config settings working on the ideal build process.
Then you had to share this build setup with your other team members, and if one thing was different on their system, then the build would fail for them, it was a nightmare.
Thankfully the CLI has taken all that away from us, now there is one universal way of building and running an Angular application locally, which works the same for all members of a team.

Another great benefit of having a CLI is that we no longer have to worry about what build system a project is using. Whether it’s Grunt, Gulp, Bazel or Rollup, this is all handled behind the scenes by the CLI. So as new build systems are coming out, the CLI team can add them to the CLI and we as Angular developers can either accept the new build system the team have added to the CLI or make some changes to our angular.json file and choose the build system we want for our projects.

I think one of the greatest benefits of the CLI is how easy it makes running Unit Tests. Before Angular, in AngularJS, setting up Karma and Jasmine was a painful experience. Again, tackling JSON files, making sure all the paths were correct, spending hours searching for answers to errors when we finally tried running the tests. Reading blog posts where someone showed us a few ‘simple’ steps to making it all work first time, and finding that after following these ‘simple’ steps Karma still didn’t work for us, then trying to figure out where we went wrong. Setting up Unit Tests was a painful and long process, but now with the CLI it’s all handled for us. All we do is run a simple command, and boom all our Tests are run.

The Adventures in Angular episode really did show how much time and effort the CLI now saves us, not only as developers, but the costs it saves companies. No longer do companies have to pay developers for setting up their local build systems, now an Angular developer can be up and running in no time.

If, as an Angular developer, you’ve gotten use to having the CLI around, take a minute to think about all the benefits it brings us. The CLI is really an amazing tool, it really helps separate Angular from the other front-end frameworks out there.

Why you should allow developers to write tests for existing code

Is it possible to add Unit Tests to an existing application and if you do decide to add tests to a project, what benefit will this have to an existing application?

I’ve worked on a few projects where the application has been started, the first few features of the app come to life and before the developers realise the application is nearly delivered to the end user, without any Unit Test coverage.
One of the main reasons for this is when an application is started there is usually a tight deadline, or a push to get something out to the end user within the first sprint and there isn’t time considered for the writing of tests. The unit test theory is that a test should be written before any code is written, but with time pressures writing tests is always something ‘we can do later’.

But can unit tests be added to existing code? And what benefit will this bring?

It is possible to write tests for existing code, it is, in fact, a good practice to go through this process for a number of reasons.

It provides confidence that new changes do not break what is already there

First, it stabilises the codebase of the application, providing confidence that any further changes are not going to break the existing code. Once tests have been written for the existing code, developers know that there is a quick way to check if the new feature they are adding is not breaking what is there already. As they go through developing this new feature having the test runner going in the background running all the tests the developer will see straight away if the change they are making is stopping existing code from working as it did before. They will get a red warning, telling them exactly what is no longer work and why.

It highlights areas to developers where code can be improved

The second reason is when writing tests for existing code developers will notice areas where the code can be improved, optimised. When writing a test you need to know exactly what the code you are testing is doing and how it works. Through this investigation, developers will see ways it can be refactored to make improvements. Once this code has been refactored and improved the test will ensure that any further changes don’t break this improved codebase.

Its a great way to onboard new developers to a team

Another reason that allowing your developers to write tests on existing code is it is an excellent way for new developers to a project really understand how an application works. If for example, you have a large enterprise business application, that has many business rules. It can take a new developer to the team to both understand the business rules, but also understand how the application currently supports these rules. If for their first few weeks on a project they are given the task to write the tests for a certain section of the application, maybe an API the application provides or a set of services that the application uses to process user orders. Through writing tests, the new team member will learn, in depth, how the current application works. They will also be involved in how the application is built, deployed, how the processes the team has for committing code, what rules there are in place for writing code. All this they can do through writing tests without affecting the code of the application.

How can tests be added to your existing project?

If you are a project manager or the business owner of an application and your team have said that the Unit Test coverage for the application needs to be improved. There are some things you can do to help this.

Writing tests should be defined as Sprint stories

You don’t need to stop development on new features just to have your team write all the unit tests for the application. This can still continue, but you need to add time to each sprint (if that’s the method you use) to allow the developers time to write tests for part of the application. When it comes to sprint planning have a few stories for writing tests. Prioritise areas of the application where test coverage is low, maybe focus on areas that are more stable, an existing API for example or the data model which isn’t going to change for a while. Assign these write tests user stories to the newer members of the team, so all they can go through all the development processes the team uses.

Improving test coverage can be a gradual process

The existing application doesn’t need to have 100% code coverage straight away. It’s better to add tests gradually as the project progresses, tests can be bought in for existing code. This does mean there is a risk that changes could break another piece of existing code, but if the tests are being written this risk will get less and less the more coverage your application has.

Allow your developers to write tests

When you are planning some work with the team, a new feature to be added. Allow time in estimates for the developers to write tests. If this time is not in the estimates developers will find that they don’t have enough time to not only write the new feature and write the tests. So the tests will start to be left, this will cause the test coverage to reduce over time and you’ll be back to where you were before, with an application that has a lot of functionality and existing code, that isn’t covered by tests.

Your QA team and clients will thank you

Finally, an application that has a higher test coverage, will have fewer bugs. New features won’t cause new bugs to appear in the existing application.
This makes the QA team happy, for them it means that they can be confident that what is already in the application still works as before. They don’t need to thoroughly test the entire application every time there is a release. They can quickly test the existing application and then focus on testing the new features. Any bugs that crop up should be caught by the developers during the development phase when they have their test runner quietly running along as they write code and then warning them as soon as any issues come up. Instead of the QA team raising a new bug.
Having the QA team raise these minor bugs which could have been caught by unit tests, takes time. It adds delays to the latest release of the code being allowed out to the end user.
So if your end users are waiting for a new feature that will greatly improve their experience of an application and this new feature is delayed due to the release not getting past QA because they have to raise a bug for something that has broken in an existing part of the application. The end user will be disappointed, and a happy end user is what we all want.

Unit test coverage is important, it vastly improves the quality of an application, but if due to time constraints an application has been delivered without a high level of test coverage, it’s not the end of the world. By allowing developers to write tests for the existing code, the coverage will grow over time and the quality of the application can be guaranteed when a new feature is released to your happy users.

Principles of Writing Testable code

I’ve recently been spending time researching into how to write unit tests for an existing codebase. One thing that keeps coming up in the research I’m doing is how important it is to write testable code from the start, but what is testable code?

Well from the research I’ve been doing I found that to write testable code a good approach is following the SOLID principles.

  • S – Single Responsibility Principle
  • O – Open/Close Principle
  • L –  Liskov Substitution Principle
  • I –  Interface Segregation Principle
  • D – Dependency Inversion Principle

So what do these principles mean and how do they apply to Angular?

Single Responsibility Principle is where an Object should do one thing and one thing only. For example in a controller or component you might have a function that loads some data, updates a local array then loads some more data from another source and finally displays this data in the UI. Well, that is four different things this one function is doing. To make this more testable it would be better to have one function that loads and returns data. One function that binds data passed into it to a local array, then another function which loads data from the second source and then finally allowing Angulars data binding to bind the data to the UI.

This means that you have only three separate functions, which can all be tested separately. One test to check the first function loads data correctly, a second test to check that the second function binds any data passed into it to the local array and finally the third test to check that the third function loads the data from the second source as expected.

Open/Close Principle is where a class is Open to extension, but Closed to changed. An example could be a function loads and returns some data. Then as the project continues the requirement for that data is changed as it is now ordered alphabetically. So you go back and amend the function to order the returned data after it has loaded. By doing this you’ve broken this principle. What you should really do it add a new function that calls the first function, then takes the returned data and then the second function performs the ordering of the returned data. This way you have two separate functions, both performing smaller tasks and the first function, which is already tested, has not been changed.

To write a function with this principle in mind, it needs to (in this loading data example) be able to return the loaded data and not just simply bind the returned data to a local variable or array. If the load data function returns the data as it loads it, then this allows other functions to take this returned data and extend what can be done with it.

Liskov Substitution Principle is where a class that uses another class, should be able to accept using another class without it knowing the difference. Within Angular, this means a controller or component may be using a service to load data, but the controller/component knows so little about the service that another service could replace the original one, without any changes needed to the controller/component.

This is an extremely important principle for writing testable code because adhering to this means that external services can be mocked in tests in order to write tests for just the function that uses this service. Through the use of mocking we can write tests that test different scenarios to see how our original function handles various responses from the mocked service.

Interface Segregation Principle this is important because it forces you to write smaller interfaces/classes which are easier to mock in tests. For example having a service that does loading data, aggregating data and ordering data, means that you will need to mock all three different functions in order to test something that is just using the loading data function. Separating it into three separate services means it is easy to mock just the one you need in order to test your code.

Dependency Inversion Principle is where your concretions (the act or process of concreting or becoming substantial; coalescence; solidification) or classes that are set out. Should only depend on classes that are abstractions of functionality. This means if you have a class that does something, like filtering an array. Then anything other classes it needs in order to perform this filtering should be an abstraction of the implementation. For example, with your class/function that filters an array, you may use something like Underscore or  Lodash to help with the filtering. When you use Underscore or Lodash’s function you aren’t using the inner workings of the library, but an exposed function that abstracts away the inner workings of the library. So if in a new version of the library the helper function you are using is re-written to make it faster, as far as you are concerned you are still calling the helper function in the same way.

So by writing your code using this principle, you are writing more loosely coupled code, which is easier to test, because you test the individual parts. Parts that know nothing or need to know nothing about the inner workings of each other. This makes mocking for tests easier to do.

Following these principles will help make your code more modular, separated and therefore easier to mock for the tests you are going to write. From the research I’ve been doing the main concept to get in order to write more testable code is, in isolation, meaning writing code that can run in isolation is easier to test. It is easier to mock any dependencies (which there shouldn’t be many) it’s easier to write tests just for that single piece of code. Therefore writing more and more tests leads to an application which has more test coverage going forward.

Here are some links to articles, blog posts I’ve found during my research:

Theory of Uniting Testing in Angular

I recently finished reading through an article on Unit Testing in Angular. The article was from the Infragistics website and in 3 parts it tried to demystify Unit Tests in Angular:

In this article, the author, Jared Fineman, really goes into how to setup your tests, how to structure tests and some of the great new features of Angular, that help with testing. One great point Jared makes is *In the world of development, unit tests have long been viewed as second-class citizens. * This is very true, it is something I have been guilty of too, forgetting that Unit Tests are an extremely important part of the development process. As part of my drive this year to improve the quality of my work, I’m focusing on both Unit Testing and readability, so I need to make writing test a core part of my development process.

In the first part of the article, Jared shows how to set up tests for your project. Though at the time of writing this version 6 of Angular was not released yet. So there is a section about updating the .angular-cli.json file, which has now been replaced by the angular.json file. Then in the other two parts of the article, Jared goes through structuring unit tests and some of the great features that Angular has that allow you to really explore the inner workings of your components. So you can write tests that examine all parts of the component.

The one that struck me in the second part of this article was the approach he mentions for structuring your unit tests. He mentions this AAA approach, which stands for Arrange, Act and Assert. The idea is that you first setup everything needed to run the component that is going to be tested, you basically arrange all the parts needed for the component. This could be modules that need to initialised, other parent components or mock data.
Next is the Act section, this is where you call the method or the component to be tested and from that call, the result can be examined. Finally, there is the Assert phase, where our assertions or expectations are tested.

This AAA methodology is great for learning how to set up tests, it is definitely something that isn’t documented enough in the official Angular docs. If a developer is new to Angular and they want to start writing tests for their app, the Angular docs do give a detailed overview of how to write a test for different scenarios. The new Angular docs really give a lot of examples, how to test components, how to test the DOM, how to test services and providers, but the theory of unit testing is not discussed enough in the documentation (but the Angular docs is open source, so maybe that can be changed).

There is, of course, articles about AAA outside of Angular, here are a few I found, though they are C# based the theory still applies:

There are a lot of articles about the Theory of Unit Testing, just not all Angular specific. It is worth searching around for them. This article from Jared Fineman is a great start.

Unit Testing and tight timescales

I’ve worked on a number of projects, where we’ve started the project with the idea to have 100% coverage with unit tests, but as soon as deadlines start to get closer, unit tests are the first to go.

What are the reasons for this?

There are several reasons why this happens, as the deadline for a project gets closer, you’re developers are put under more pressure to get all the features completed. So they need to focus on that, the time spent on updating or creating new Unit Tests is then spent on getting these features delivered.

If the project being developed in an internal project, and the stakeholder sees that the release deadline is getting closer, they are probably wondering why their developers are spending time writing tests and not being that new feature they have just asked for. I’ve seen this several times, the project manager or business owner, is under pressure to deliver and they hear a lot of talk from developers saying they need to write the tests for a feature, but to the PM that seems a waste of time. On one project we were asked to stop developing unit tests as we needed to get a version of the website ‘out the door’.

I’ve also been on projects where, as a team, it was decided to ‘come back and write the tests later’. As an approach to getting this high level of quality that the project needed. This wasn’t a good idea, as we never went back to write the tests and eventually the code coverage on the project was very poor.

Unit tests and test coverage are sometimes seen as nice things to have. We know as good developers we should have them, we should have tests for every line of code we write. There are many talks, books, podcasts, where ‘experts’ are telling us, developers, that you should be writing tests. It’s like when you are trying to eat healthily, you know you should make a salad for lunch, but those crisps and cheese rolls are just so much easier and quicker to make.

How can this problem be solved?

The central cause of this problem is time, projects basically run out of time to get all the features of a project completed and still write the tests. One solution to this problem is better planning up front. When scoping out a feature, developers need to see unit testing as an integral part of the development process. If they are using the points system in scrum to say what the effort involved in creating a new feature. Writing the unit tests needs to be considered as part of this effort and it is up to the senior members of the team to remind all the developers to include this unit test development as part of their estimates of effort.

Developers need to also show the Project Managers and stakeholders the importance of maintaining good test coverage is to not only to the project as it is now, but a year or two down the line, when a new feature of the site/app is going to be added to the project. When these new changes start to be developed for the project, the PM/stakeholder needs to know how important it is to have good tests during this ‘adding a new feature’ development phase is, in order to make sure the existing site/app doesn’t have bugs introduced.

As well as developers not adding the effort required to their scrum estimates, and PMs not aware of the importance of keeping tests up to date in a project, another issue is that writing test does take a long time, especially if you are just starting out writing tests.  I’ve worked on projects where when I was writing my unit tests I wasn’t convinced that the tests I was writing were actually ‘testing’ my code, but was probably just checking that a value is present. The quality of the tests was not very good..

As developers, we are shown all about the features of a new framework or library, how it does the new latest thing, how fast it runs and how it is better than framework X, but it is very little in the framework documentation on how to plan your tests? What approach should developers take when writing tests? We see many examples where a test suite is set up, and the test checks the value of a <span> in a template, or a test for an HTTP request of a static file, but there isn’t much information about the ‘theory’ of writing good unit tests. Have you tried writing tests for AngularJS directives? It’s easy to check the HTML of a directive, but testing the inner workings of your directive? Nearly impossible.

If developers spend the time learning about writing tests, and if the authors of these frameworks/libraries show others how to write good tests for their framework based apps. The time developers spend writing tests will be reduced. The more we practice something, the quicker and better we get.

If PMs and stakeholders can see unit tests and coverage as an investment into ensuring the quality of a project and the providing long-term support to a project, they will allow the developers to spend this extra time need to write tests.