Test Driven Development: How and Why
Test Driven Development(TDD) is a very useful approach towards code development. It keeps the developer from having to second guess every piece of code he writes.
The TDD workflow goes like this:
First, you write a block of code. Next, write a unit test for that block of code and ensure it passes. If there are any issues, refactor.
This workflow also makes your design more intentional as it elucidates what the code is suppose to do.
Each unit test is a test case and a grouping of tests makes up a test suite
Unit tests should run on memory and not rely heavily on databases or even filesystems.
It comes down to this: the behavior of the code is serving the original purpose intended by the developer. If there is suppose to an exception then code should raise it.
Reduce risk
it is the manifestation of the DevOps concept of 'Shifting Left. By discovering any issues to the left side of the Software Development Lifecycle(SDLC), the cost of fixing it is reduced. Unit tests will guard against committing(and eventually pushing) a broken build unknowingly to a common code repository.
Maintenance
Prevents code regression. Unit tests protects code from slowly regressing as components are adding to it. The core functionality of that unit of code is protected by the tests. You can be assured fixes done elsewhere in the code have no side-effects. In the event that there are side-effects, it allows for quick detection and remediation.
Unit of Code under Test
Example: Simple function which takes user input and decides what to do with it - Let's check that behavior of code is consistent with the value it receives
Here we are testing a unit of code that is a function. It takes user input with Python's input command and should correctly locate a file as per the input.
Test Case with Test Double: Using mock to simulate user input
Here we have a test case written for the abovementioned function.
This test case is trying to assert the behavior of the function when it receives valid inputs, it should be able to reach a specific file within the inputs.
As unit tests should not be dependent on external resources, we are creating a test double - a mock to simulate user input. In this instance, we are generating a temporary file and folder which gets cleaned up after test.
The mock test double is created using the Python decorator @mock.patch.
The tests are passing. Indicating that the code is responding as intended to user inputs.
A mock is one type of test double. It has a behaviour of its own and has to be correctly implemented to run the test case. In this case, the mock_input.side_effect attribute had to be used for passing the test values to the overriden input functions in Startup.py.
There are other ways to create test doubles such as stubs, spies, fakes, dummies; what test double to use depends on needs of the test.
Conclusion
It might seem like there is more work initially, but its pay off is far exceeds the extra work. By testing as you build, you have a peace of mind that code written is working before moving on.
TDD is not a silver bullet to detecting issues in code. But it can really go a long way to helping the developer cope with process of development and testing; not just the primary developer, but anyone who is inheriting the source code.
Comments
Post a Comment