In this post, I’ll show a glimpse of software testing and how test-driven development works in a nutshell.
Why Do We Test
Every little software grows big, trying to solve more problem regarding its particular domain. It faces bugs in the way which also needs to be taken care of.
As software grows big. It becomes harder to go and test if every part of the software is behaving the way it should. Take the example of a Django application. If the manual path is taken, one is supposed to test every layer of the application, including Model and Views against each if and else in the control flow.
This approach is fine until we have a smaller codebase. But imagine if the codebase inflates, we’ll be spending more time testing than implementing the actual code.
Some developers even tend to first write the test and then write the software logic according to that. Then the software is improved to pass the new tests, only. The process goes like, Add a test > Run test and see if the test fails > Write the code > Run tests > Refactor code > Repeat.
Types of Testing
Now we know how test-driven development works. But the tests are itself classified into multiple variations. There are numerous types, levels, and classifications of tests and testing approaches. The most important automated tests are:
Unit Tests
Verify the functional behavior of individual components, often to class and function level. You give a test case and check if the program the same results every time. This path is so common, major language has some implementation of unittest. Python has inbuilt unittest. JavaScript has their own. Even golang.
Regression Tests
You fix a bug, which unconsciously results in another one. Regression tests are the tests that reproduce historic bugs. Each test is initially run to verify that the bug has been fixed, and then re-run to ensure that it has not been reintroduced following later changes to the code.
Even if you send some project pull request, your patch is most likely will be first going through a test before request is merged into main codebase. If the test fails, maintainer might ask for the changes.
Integration Tests
Verify how groupings of components work when used together. Integration tests are aware of the required interactions between components, but not necessarily of the internal operations of each component. They may cover simple groupings of components through to the whole website.
Code Coverage
When a code is tested. It might or might not go into every conditional branch.
Code coverage is a metric which measures how much test covers the whole codebase. Tests are supposed to go through every each and else condition for a higher code coverage count. Higher is this measure, lower is the chance of encountering undetected software bugs.
Related readings
- https://en.wikipedia.org/wiki/Test-driven_development
- https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing
Did you like the post? Is something missing? Please let me know in the comments. Also subscribe to this blog below.