Does someone has guidelines/ articles/ resources on how to write good unit tests?
Audience would be developers (Java & Python) who don’t have any experience with unit testing.
My youngest son is into computers, last year we sent him off to uni to study CS. Last weekend over the whatsApp call he asks me, “Dad, how do I unit test a class with Private methods?” And suddenly I am in my element. This is why I exist.
It’s a university group project, and the usual is happening, at least one kid can program well, another can do artwork, and the rest are learning C# .NET . And nobody is really managing things, but they all agree they need unit tests.
Code itself needs to be written to “be testable”, and as we talk on the phone I have to dig up my rusty C# programming knowledge and explain how to write testable C# even though my forte really is C/C++ not C#. Eventually we work out how to clean up the class interface so that ‘private’ is used to hide implementations, but ‘public’ is still used to expose for testing at a fine grained level. Turns out some classes are really doing multiple things and hence lots of private methods which unit tests cannot touch.
Know the language you are testing incredibly well, that’s another myth in unit testing, that you only have to test the inputs and outputs of each method or unit. Unit testing asks you to treat the unit as opaque, but what happens when the unit is subclassed incorrectly, can your unit testing activity highlight semantic and language errors in the calling conventions or hooks the unit has? A bit like my son and the University project full of clunky classes with private methods. Unit tests will actually tell you if your class is not applying SOLID (What is SOLID? Principles for Better Software Design)
Far too much messing about happens when people start unit testing, it’s too easy to think it will be a once-off activity. Unit testing is not a once-off activity, to treat it as a one-off task that actually completes will make the cost of getting product out of the door inhibitive. Testing of all kinds is a social and co-operative activity.
Try to write your own framework first - don’t just grab the first off-the-shelf unit test framework for your target language. To write robust unit tests, you need to be using unit tests for their ALL of their purposes, not just to Verify results. Sure unit testing is best done using AAA (Arrange, Act, Assert) but unit testing is also a code-review and coding skill activity as well. To write very good unit tests, you have to know the language under test, how the language pre-processor may change in future, and about subtle ways that pre-processor options (aka compiler flags) may cause the code to break in future. You have to understand that unit tests are really like watchdogs, they need to be able to sleep very well, and only spring into action much later. And not require regular watering or maintenance. Then, once you know how the language works, you can grab an off-the-shelf tool.
Writing unit tests as part of a TDD (Test Driven Development) activity is a fun way to learn to unit test, and even if you don’t TDD, unit test writing really needs to be fun. It needs to be a thing you will come back to easily, when you have to update a test after an interface changes and breaks a few of them. I think the main reason people hate unit testing is that it requires hard thinking. You really have to see unit testing as a way to improve your coding skill, not as a way to just assert program correctness.