An introduction to unit testing
Unit testing is the process of isolating and testing a small, specific piece, or unit, of code, to ensure each piece is running as expected. In object-oriented programming, an entire class is considered a unit, while functional programming considers an individual method or function. Unit tests are generally differentiated from integration tests, which verify that the units are working properly as a whole.
As a fundamental part of the Test-Driven Development (TDD) methodology, unit tests are written before the actual code is written (the “test-first” approach). These tests drive the creation and design of the code and program, making it an integral and iterative element within the larger development process. TDD allows the developer to avoid being concerned with getting all the logic correct at first. At a high-level, the order of TDD flows as follows:
1. Write a unit test (designating an aspect of the program)
2. Run the test, which will fail because the code does not yet exist
3. Write ‘just-enough’ code so that the test passes
4. Re-factor the code
5. Repeat and accrue multiple tests
In TDD, unit tests are automated with the use of a Unit Testing Framework, which helps the developer create, carry out, and manage test scenarios. This process must be automated and executed often as the program becomes larger and small changes are made to the codebase.
- JEST — maintained by Facebook and preferred for applications powered on React, but also compatible with NodeJS, Angular, Vue, and other Babel-based apps; fast and great for preventing UI bugs because it saves screenshots of the rendered component and compares it to later renditions of the same component
- Mocha — one of the oldest JS unit testing frameworks, there is a lot of documentation provided online, but takes time to configure
- Ava — performs tests asynchronously/concurrently and contains simple syntax.
- Jasmine — compatible across every JS framework and especially beneficial for frontend testing and checking that the app is responsive and corrects depending on device. Best for larger applications that integrate with multiple external libraries.
- Puppeteer — developed by Google and supports ES6 features like async, etc. Tests are browser-specific, so it provides a lot of support for responsive testing as well.
For early developers, understanding the rationale for implementing unit tests is critical as these tests will decrease the overall time spent on debugging. These tests make the testing phase easier, as they will help identify bugs earlier in the process and any new logic written will not break the previously tested code. Testing frameworks will make the debugging process much less costly in the long run, and as many agree, make building programs much more enjoyable.