What is Unit Testing?
In computer programming, unit testing is a software testing method by which individual units of source code are tested to determine whether they are fit for use. A unit is the smallest possible testable software component. A unit is small, so it is easier to design, execute, record, and analyze test results for than larger chunks of code are. Defects revealed by a unit test are easy to locate and relatively easy to repair.
Some developers underestimate the importance of writing unit tests. What follows are the benefits of unit testing that you may want to consider before forming your own opinion.
Benefits of Unit Testing
Unit testing provides numerous benefits including finding software bugs early, facilitating change, simplifying integration, providing a source of documentation, and many others, which we will look right now.
- Unit testing reduces the number of bugs very quickly and easily.
- programmers following the Test-Driven Development (TDD) process claim that unit testing helps them achieve their goals faster, solving problems with less code and better code architecture.
- It is important to improves the code design and make the code easy to understand by development teams in future.
- If issues found in unit testing then it is easy to debug that issue because there is a small module in which the developer have to fine the exact code which is defected and fix it.
- Development is faster. How? If you do not have unit testing in place, you write your code and perform that fuzzy ‘developer test’.
- Tests can be started at an earlier stage. You don’t have to wait until the GUI is available.
Angular Unit Testing Introduction
It’s easy to get started with unit testing for Angular 2+ apps. If your projects was setup using the Angular CLI, everything will be ready for you to start writing tests using Jasmine as the testing framework and Karma as the test runner. Angular also provides utilities like TestBed and async to make testing asynchronous code, components, directives or services easier.
Let’s see how to start unit testing your angular app.
Creating your Angular App with Karma and Jasmine
Let’s first create your angular app using this command.
|
|
Once your project is setup, all the dependencies related to Karma and Jasmine have been installed in. your package.json
file automatically. Open your package.json
file, and notice these dependencies.
package.json
If you notice, there are two things mentioned in the above pic, one is Karma and another is Jasmine. Let’s have a brief look into these two keywords.
-
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it’s suited for websites, Node.js projects, or anywhere that JavaScript can run.
-
Karma is a simple tool that allows you to execute JavaScript code in multiple real browsers. Karma is not a testing framework, nor an assertion library. Karma just launches an HTTP server, and generates the test runner HTML file you probably already know from your favourite testing framework. So for testing purposes you can use pretty much anything you like.
Karma Configuration File
Angular-Cli create one Karma configuration file karma.conf.js
in your src
directory, Take a look at this config file.
karma.conf.js
Let’s have a brief introduction of this file to better understand this testing stuff.
frameworks
: this is where your app testing framework is set. If you want to change to any other testing framework, you can change it here.autoWatch
: if this is set to true, the tests run in watch mode. If you change any test and save the file the tests are re-build and re-run.browsers
: this is for browser launcher. By default, it is set to Chrome, and you can change it to your preferred browser.
test.ts - Test Entry File
There is a test.ts
file generated by Angular-Cli in your project folder. This file is required by karma.conf.js
and loads recursively all the .spec and framework files.
test.ts
There are a lot of things mentioned in this file, which we don’t need to change. So, I am not going into the detail of this file. Just remember that, this is the entry file for performing unit tests by Angular Cli.
Writing Angular Unit Tests
Once your angular-testing app is created, you can now run this simple command to test your freshly created app.
|
|
Karma will spin up and run all available tests. This will show following message in your terminal window
And open the Karma test screen on the browser.
Before start writing your test cases, let’s first understand the basics of writing the tests in Jasmine framework. You can read more about writing test cases syntax by clicking here.
|
|
- describe function is used to describe the test specs. You can create a group of specs, often called a suite.
- it is global Jasmine function to define specs, which takes a string and function. A spec should contain one or more expectations that test the state of the code. A spec whose expectations all succeed will be passing and a spec with any failures will fail.
- expect creates an expectation for a spec. This takes a value, which is called
actual
.
|
|
- matcher implements a boolean comparison between the actual value and the expected value. It is responsible for reporting to Jasmine if the expectation is true or false. Jasmine will then pass or fail the spec.
toBe()
(line 3) matcher expect the actual value to be === to the expected value.not.toBe()
(line 6) invert the matcher following this expect.
Setup And Teardown
- Sometimes in the real-world application before performing or after performed our test case we need to insert some mock data or we need to do some cleaning activity, for these purposes we have
- beforeAll - This function is called once before all the specs in the test suite are run.
- afterAll - This function is called once after all the specs in a test suite are finished.
- beforeEach - This function is called before each test specs.
- afterEach - This function is called after each test specs.
Now, let’s start with writing our tests.
Testing a component or app.component
Let’s review our default test file of app component, which is app.component.spec.ts
in the app folder.
|
|
The above tests three things:-
- app should be created. (line 13-17)
- app should have title ‘angular-testing’ (line 19-23)
- should render title in a h1 tag. (line 25-30)
In the beforeEach()
function, we’re using the TestBed.configureTestingModule
function to create a module environment for testing the component. It’s similar to NgModules, except that in this case we’re creating a module for testing.
Now, we have created our first spec using it()
function to test whether our component is created or not.
Next, we are defining spec for testing our app title using the below it()
function.
In the last spec, we are testing whether title is rendering in h1 tag or not.
In the above code, you have noticed these keywords like TestBed
and fixture
. Let’s me explain them briefly here.
Angular Testing Utilities
TestBed
is used to configures and initializes environment for unit testing and provides methods for creating components and services in unit tests. TestBed
is the primary api for writing unit tests for Angular applications and libraries.
fixture
is a wrapper for a component and its template. We can create an instance of a component fixture through the TestBed. Fixture
is used for debugging and testing a component.
fixture.detectChanges()
triggers a change detection cycle for the component. detectChanges()
is used to tell the TestBed
to perform data binding. Then the will have the expected title.
fixture.debugElement.nativeElement
provides the component’s element. Because the tests are running in a browser, a nativeElement
in these tests is always an HTMLElement
whose familiar methods and properties you can explore within a test.
Summary
Hopefully this has been a useful introduction to Angular testing for you. If you want to learn more, I recommend you stick first to the official Angular documentation.