Sequel to the Modelling a Polling System with Prototype Oriented Programming in Javascript, I am going to explain Test Driven Development in Javascript using that same model.
But before we get in that, let's explain testing.
Testing basically is a method by which software codes (either individual units or sets) are tested to determine if they are fit for use.
Test Driven Development, on the other hand, is a system of software development that requires a repetition a simple development of a cycle
There are many types of testing, unit testing, integration testing, regression testing and so on, as a matter of fact, there is a whole lot of testing type.
- Unit Testing: Testing every single unit (function) of software against the functional requirements
- Integration Testing: Testing integrated units of the software
- End-to-End Testing: Testing to check the flow of software from beginning to end as a single application.
But this article is not going in-depth into the types of testing but would introduce you to testing (basically unit testing) in Javascript.
Testing Framework
In Javascript, they are various testing frameworks available in Javascript some of which are JSUnit, Unit.js, QUnit, Jasmin, Karma, Mocha, AVA, Jest. In this article, we are going to be using Jest which is a testing framework by Facebook.
Jest is a testing framework that provides a zero-configuration testing experience (all you need to do is run a command to install), does not require any library or external dependencies to work, and of course, can work without internet.
Let’s get started. We are going to test all functionality in our Polling System Model but first, we would need to set up our environment for testing.
Prerequisites
To set up our environment for test, we would need to run these commands in our terminal or command prompt for windows
- Install node if you haven’t and initialize project for node
npm init
This would require you to input some information but to get default values you can run
npm init -y
A package.json
file containing the following would be generated.
- Install jest
npm install --save-dev jest
This would generate a node_modules
directory, package-lock.json
, and update package.json
to have jest
as a dependency. But we need our functions to be tested with Jest
so we change our test in package.json
to use jest
How Test Works
Before we get into testing our Polling System, let’s write a test a simple function so you get a feel on how testing works
We are going to create a simple function that returns a users username. The usual Test Driven Development practice is to write the test before the function or method we are testing so let’s get into that.
First, we have to think of all possible scenarios that a user would do, like, errors in the form of entering integers or not entering anything at all, to entering the right details for username.
We create a file for our test but the file extension used to save this file is sort of different. Here is how we save our test file, filename.test.js
.
After doing all that, we write a test to cater for those scenarios.
Let’s talk about what’s happening in the test code above.
First, the describe keyword. The describe simply describes the suite of test cases enumerated by the “it” functions (in other words it tells us what the code in the describe block is trying to test). That brings us to the “it” keyword which is used to explain what the test should check for.
The expect there returns an expectation object (returns the response gotten from calling the function) which we call a matcher on.
Matchers — toBe, toEqual, toBeUndefined …
Matchers are used for checking if what we expect()
from calling our functions with certain values correspond to what should be actually returned by the function.
Running the test
After writing our test code, we run on our terminal to see if it actually works. We run our test by using a command on the terminal
npm test
When we run this command, jest
looks through our working directory for any file having the .test.js
extension (the reason for saving test files as filename.test.js
). It is expected that all test cases should fail because we have not written our function. We get a response on the terminal that looks like
If you look at the ReferenceError you see we have a response saying the function we expect our response from is not defined. So, let’s write the function.
If we run our code we still get the same error because we have not required our getUsername function in the test file.
If we run our test again, we should get the following
Now, let’s change one of our test cases to expect something else, you can change anyone you like
Our test case for test integers failed. Why? If we look closely at the responsejest
is giving. It says that the expected value and the received values are not the same.
They seem to be the same but they are not, I changed the uppercase “K” in the toBe()
to a lowercase “k”. This just shows that the expected values are case sensitive. If we change back to uppercase “K” it would pass. Congratulations! You just tested your code.
Code Coverage
Jest also has a way of checking code coverage. This simply means check what part of your code has been tested.
To do this, we have to run a command
npx jest --coverage
This would add a coverage
folder to the project directory and give a different response than our normal jest command
Jest gave the response with a table showing how many percents of our statements (if/else), function, lines of codes were covered (tested). We can get a better view of this in the browser by open the coverage folder, then the lcov-report, then open the index.html
file.
We get a good view o four test coverage. Something that looks like
Say we remove a test case from username.test.js
and run our test coverage, we should get something like
We only have one function so it tells us we tested 100% of our function but 50% of branches (basically code parts in our function block). Now let open our test by clicking on the arts.js
.
The part highlighted in red tells us what part of our code was not tested. So let’s return the test case and run again
100% of our function was tested.
Understand that getting 100% test coverage is nice but not a must. The moment you begin to adjust the code to get 100% (removing statements) it becomes bad practice. So, think of all possible scenarios before writing the test.
Testing The Polling System Model
You can clone the GitHub repo and try to write a test for it, Should be fairly easy cause we already have written code for it and know what to expect, or you could just create another simple function to test.
Finally, we tested our Polling System model.
All code can be found on my github repo. Thanks.