If you are a non-techie working with software developers, dev ops and other techies, you might have heard so much about the brouhaha among your techie and software developer friends about this thing called "Test Driven Development" and "Unit Testing".
What does that all mean really? And what does that mean in terms of the quality of the software you own and pay for when hiring developers?
In this post, I will attempt to explain in simpler terms what unit testing and test driven development is all about. To do so, I will break down the concept of test driven development into 3 different sections
- Unit testing
- Integration testing
- System testing
Unit testing
Unit testing is automating the execution of a test run of the smallest possible piece of a program. This often refers to individual functions (or "methods") written in the software. For example, if I want to automate a check that a user with the correct password is able to login to my application and be redirected to a specific url, I would have a specific function that looks something like this:
# ... various setup code above ...
def test_login(self, user, password):
# now check the login process
post_data = {'username': user.email, 'password': password}
login_url = reverse('login')
response = self.client.post(login_url, post_data)
self.assertRedirects(response, reverse('home'))
The last statement checks that upon a successful login, the response from our web application will be redirected to the "home page" url.
Because this
specific unit test, together with other unit tests, is located in a "module" (a directory containing functions and other code relating to that module) called "userprofile", I can now simply run "./manage.py test userprofile" in my terminal:
calvin$ ./manage.py test userprofile
Creating test database for alias 'default'...
.......
----------------------------------------------------------------------
Ran 7 tests in 4.588s
OK
Destroying test database for alias 'default'...
If for some reason we modify our code so that a user who has logged in no longer gets redirected to the home page url, this unit test will fail and running ./manage.py test userprofile will tell us that our unit test has failed.
These individual functions is a "unit of test" because there's no other meaningful way to divide it up further.
Unit tests are used to test a single unit in isolation, verifying that our application works as expected, without considering what the rest of the program would do. This protects each unit from inheriting bugs from mistakes made elsewhere, and makes it easy to narrow down on the actual problem if one should occur.
In itself, unit testing isn't actually sufficient to confirm that a complete program works correctly as intended. But unit tests are the foundation upon which everything else is based. Just as we cannot build a house without solid unit-size materials (like a single brick or a single steel rod encased on concrete), building a non-trivial software without unit tests is simply asking for trouble.
Integration testing
Now that we have a good idea on what it means to be writing (automated) unit tests in your software, we can explore the next level of testing. In integration testing, tests now begin to encompass interactions between related units. While each tests should still be run in isolation (using "./manage.py test userprofile" as explained earlier), we now care about whether the tested units behave correctly as a group.
Integration testing can be performed with the exact same tools as unit testing. So for new developers who are just getting acquainted with the practice of "Test Driven Development", they might make the mistake of ignoring the distinction between the two. Ignoring this distinction is dangerous because multipurpose tests often make assumptions about the correctness of some of the units that they involve and if test functions are written without having defined distinct/standalone functions or methods in the first place, we lose much of the benefits which automated testing should have granted.
Understanding these nuances and knowing when to write a "unit test function" versus an "integrated test function" and taking a disciplined approach towards software development is what differentiates between a well-oiled, professional software team and a
cowboy software team.
System testing
System tests check parts of the program after all modules are plugged together. In practical terms, the automation is executed by running a command such as
instead of
./manage.py test [module]
So if your application comprises of many "modules" (representing groups of functionalities) worked on by different developers, running "./manage.py test" and seeing that all the tests are passing gives you confidence that your team of software developers is working well together and writing code that integrates seamlessly.
System tests are very important but they are not very useful without integration tests and unit tests. If individual unit functions are built well, integration tests are well written and a good foundation has been laid out for your custom software, watching your system tests go all green ("OK") is a wonderful feeling that even a non-techie would appreciate.
Here's an example of a user-friendly interface from buildbot (a continuous integration application) that shows you what has passed and what has failed so even a non-technical business/product owner or stakeholder can understand at a glance.

Now you know why writing software is so much fun! :-)
Writing unit tests, integration tests and passing system tests is an interactive, dynamic and
really fun team sports for professional software teams - well, almost.
Fun and "cool" factor aside, including continuous, automated test systems in your software projects imply that as a Software Product Owner/Business Owner, you reduce the costs and time required to manually test out your software whenever you launch a new feature.
Test driven development is a long-term investment that ultimately results in a more robust software - and a higher quality software experience leads to happier users and customers of your software product!
Category:
Product Management
Tagged as:
testing
unit
Leave a Comment