Unit testing has become a standard in most application development teams. If you are familiar with unit testing, then you’ll already know how confident a developer feels when refactoring tested code. If you are not familiar, then imagine getting rid of deployment stress, a “code-and-pray” coding style and never-ending feature development. The best part of it? It’s automatic.
Unit testing, as the name implies, is about testing individual units of code. Unit tests try to answer questions such as “Did I think about the logic correctly?” or “Does the sort function order the list in the right order?”
Unit tests greatly improve codes twofold by forcing you to write modular logic units, instead of large code chunks.
Unit testing also provides you with documentation that is always up to date and informs you about the code’s intentions and functional behavior. Even if a method has a cryptic name — which is bad, but we won’t get into that here — you’ll instantly know what it does by reading its test.
Recently I have been involved in writing a lot of unit tests for our Angular application, which is why I have written this blog.
It was just a few hours into the process that I realized it had been a big mistake ignoring the unit tests for such a long time. The code base had been growing, and as is usually the case, was getting more complicated with every new feature or modification. Fortunately, we did have another task(s), to clean some portions of our code and to ensure they are testable. What I learnt from this is that it’s never too late to write tests!
We adopted Jasmine+Karma for our unit testing from the get go. That was my initial choice because after researching Angular Testing frameworks I realised that it was what all the ‘cool kids on the block’ use. The best place to look for testing documentation was the Developer Guide of Angular (https://angular.io/guide/testing)
describe : This method is used to represent a group with related test blocks. This method needs two arguments to execute –
- Test name
- A function
beforeEach : This method is fired before each test block.
it : This method executes a function to perform a test operation.
expect : This method evaluates the result from the test block and performs the assertion statements.
toEqual : This method is used to compare the expected result and the actual result.
beforeAll : This method is executed only once in the test block to provide the description of the test suites.
On evaluation, the recommended test runner here was Karma and I will detail the advantages and disadvantages from working in a highly scalable application:
- Jasmine is a BDD (Behavior Driven Development) framework
- One single unit test framework. Don’t need extra assertion library or anything for test doubles
- Easy to read and learn
- Angular has a developer guide for unit testing Angular applications using Jasmine and Karma
- Lesser issues open in github and has more watchers as compared to Mocha and chai
- Integrates well with Visual Studio Code and Webstorm
- Runs for both Node.js and browser
- Assertion library is not as rich as chai
- Less flexibility. Especially when it comes to making assertion and mocking utilities richer. (in Mocha, you can use any assertion library that is suitable for the project)
- A specific file suffix is expected (*.spec.js)
- Asynchronous testing is not that great (though in Jasmine 2.x it is similar to Mocha, but before that it is extremely terrible). Working with promises and async code is not as good as mocha/chai-as-promised
So why Is Unit Testing Required in Angular you may ask?
- It protects the existing code, which can be broken due to any changes.
- Integrates an automatic build process to automate the pipeline of resource publishing at any time.
- Clarifies what the code does, both when used as intended, and when faced with deviant conditions. Serves as a form of documentation for your code.
- Reveals mistakes in design and implementation. When a part of the application seems hard to test, the root cause is often a design flaw, something to cure now rather than later when it becomes expensive to fix.
- It allows us to test the interaction of directives or components with its template URL.
- It allows us to easily track change detection.
- It also allows us to use and test the Angular Dependency Integration framework.
Developing a UI in Angular? Invest in Unit Testing with Jasmine and Karma for peace of mind!