Software tests
Write them. Do not try to save time writing them poorly or even not at all. You and your coworkers and even often your future self will appreciate the work you put in.
Many many times I found probable issues, uncovered cases and bugs lurking in my code I wrote by testing the code step by step and covering most use cases of a class. Writing the code itself and tests for it happens with a little different mind set. When code I try to keep it as easy and understandable as possible. When writing tests for the same code I solely want to cover all sensible cases or all if possible with reasonable effort. This could be simplified to “What should be done” and “What could be done”.
With these two mindesets and both tasks accomplished, most of the time I feel already pretty good about the piece of software I just wrote as I can be sure that it does what it should – at least concernining the technicalities tested in the just written in the unit test. This covers only the class / module in an isolated environment, but your software module will most probably interact with others. In the unit test you will have mocked other services or modules and called the methods of you class within the tests directly.
In a real world scenario this will not happen like this as your app will interact with its modules with user input or external status changes for example. These interactions should also be covered with tests covering multiple or all your software modules in a repo. These tests are called medium test and they cover use cases of how the system as a whole works together. External sources are mocked, too, but often with some standard behavior and convenience methods to change system states within the test with few effort.
I won’t go in detail as this isn’t about which test framework I suggest or use, but some general personal recommendations and experiences with tests.
Don’t be so lazy to pack multiple use cases in your test. Keep them simple and everyone ever reading them again will thank you. If there’ only one thing tested, it will only fail at this mistake and you don’t have to dig into the code which of the multiple cases tested was the error causing it to fail. if / else in test code only means one thing imho: write a separate test for each branch.
Separate the test code in blocks for preparation, execution and verification. Don’t mock or verify thing you don’t really need in this test or you already have tested in another case. This complicates things and will take more time to understand.
Tests are documentation of intended behavior: give the a proper name and keep them as simple as possible to easily understand what is and should happen in this test case. Simple things like a code comment why this test was added and the corresponding ticket id help alot in the future.
Automated tests ensure the retention of the implementation: this helps to find bugs if something was changed unintentionally. Continuous build systems will remind you instantly.
Use parametrized tests to cover the same test case with different parameters: don’t just use a sample test for a group of possible combinations. In many cases it is pretty easy to test the rest of the possible parameter variations as 100% coverage doesn’t mean much if the code is just executed but not with all or at least the most possible combiations. I really like to write parametrized tests with generated possible parameter combinations which can occur in the code because it ensures the behavior of your code in all or most cases with few effort.
Have a nice day and keep testing – not only for Corona 😛
One Comment