How to Learn Unit Testing Using Codewars
Many engineering teams value good software testing and there are a range of good testing suites available to full-stack engineers, but it can be difficult for entry-level engineers to get started on this and to work out ways to integrate this into their daily learning.
Let's start with a little background.
Test Driven Development (TDD)
Test Driven Development (or TDD) is a software development process designed by Kent Beck, the author and originator of "Extreme Programming", an agile software development style that aims to produce higher quality software and a better quality of life for dev teams.
The regular software development life cycle can look a little like this:
Identify > Plan > Design > Build > Test > Deploy
The premise of TDD is - you change your priorities.
Write Tests > Observe Fails > Code to pass > Refactor > Deploy (or repeat)
Benefits of Unit Testing.
Although it takes time to write the tests, this arguably replaces the time you may have spent debugging or error-checking.
After deployment, the test remains in place and can be run as part of a set before deployment each time something changes - this greatly increases the stability of your code.
The onus is on getting a solution, quickly - this can speed up your time to deploy code.
Refactoring is baked into the process, with a firm focus on delivering working software as a priority - time can be devoted to making it more efficient afterwards.
Testing with Codewars
Codewars actually already supports testing! You can get hints and tips on how to write tests by checking out that little box in the bottom right of the screen:
Codewars uses Mocha and occasionally Chai for tests. You can use whatever test-suite you want for your tests. Jest is a popular choice and puppeteer for more complex test needs, but let's stick to Mocha/Chai, Both are effective, responsive and easy to use - perfect for learning unit testing.
Installing Mocha and Chai
If you keep a codewars repository, install npm in it along with mocha/chai
Some developers prefer to write a single file per coding challenge, here's how I organise mine:
after installation, add a simple line to your package.json file to let you run testing using
npm run test
Now we're set up - lets code and test a codewars example using Unit Testing and practicing TDD.
How to add unit testing to your codewars solutions
Sentence Smash is an easy one to start with from the fundamentals 8th kyu track, lets use it as an example.
You'll notice that the tests are already written for you in the bottom right here!
You can either copy them to your test repository, or you can ignore them and try to write the tests yourself. If you're just starting out - type out the suggested test for practice, you can write your own later when you get some familiarity and practice.
1. Copy/Paste the codewars function into your .js file:
module.exports to allow that formula to be imported to your test file.
3. Configure your .test.js file
In your .test.js file, at the very top of the file - Import Chai assert and set up a variable for the path to your .js file.
4. Write your test!
Start with a
describe() function in the following syntax:
The describe function gets things started and lets you nest your tests under a contextual heading.
Next we add in:
it( ) functions for each test criteria, try and think of every possible output you might need and don't forget to include any edge cases.
We are using
assert.strictEqual here though we could have used
assert.equal - these both correspond to
In this case we need to take care of the possibility that there is an empty array in the input and a one word array:
Note we are using the variable
We then add our multiple word tests
Ok we're looking good, equal/strictEqual is just a function that compares the results of the function you're going to write - with the expected output returning a pass or a fail in the terminal as appropriate.
5. Run your tests
Time to run your tests, use
npm run test
As you can see - we're failing two tests and passing the empty string one - this is a good start, ideally we fail all tests to confirm they're working as planned.
As you can see from the test output, your contextual strings have been displayed to give you contextual information about your tests.
the expected actual
6. Write your code
7. Test the Code
npm run test once more
We passed all 3 tests! You can go ahead and submit at this point but there is one more thing we need to do.
8. Refactor your code
We need to refactor for readability and efficiency, we went for the fastest, most familiar solution but this may not be the best one.
Then we test one more time.
Success! and did you notice we reduced the time to run from 12ms to 8ms? a 33% increase in speed. It may sound small but when our code bases get bigger, these gains can add up.
Now that the work is done we can go ahead and post the solution on codewars, writing the tests was probably more difficult than writing the solution - but there was zero debugging and we learned about Unit Testing!
I hope that was helpful! I've started learning JEST and Puppeteer for more complex testing - but it's built on the back of the practice here, drop a comment if this was helpful or you have any suggestions.
Good luck with your unit tests!