# 06-30 Unit tests

Today I spent the whole day writing unit tests for the codebase. Though rather time-consuming, it is a pretty good way of being absolutely sure that everything works. A large problem that I have with interpreted languages like Python and PHP is that you often times only can catch syntax and logical errors at runtime. For some reason (copy paste error etc.) a variable is a an array and not a StdClass. I often find myself writing logs to console at runtime as a way of overseeing the state of the code. That means that I had to startup the raspberry pis and the backend just to watch the log files. Then I fixed something and upload the rebuilt code to the devices again.

What I really should have been doing is to write a unit test first, detailing what I want the new class to do. Then I write code that passes the test and all other ones. This checks all the typing at "test time" like in a compiled language would do at compile time. Furthermore, it guarantees the functionality of older code that otherwise wouldn't have been covered by a rudimentary console log test. Writing unit tests is an upfront time-investment that pays off later when one can add to or refactor the codebase knowing that everything works.

Unit tests also exposes flaws in the architecture when something about a test seems to convoluted. For example I refactored the entire cache read / write process because the tests of RSSI calculations ended up being concerned with getting data from Redis and testing this as well. These two tasks should be decoupled, since a calculation method that gets a rolling average on RSSI should not have to worry about how to decode measurements from JSON and interface with Redis. Imagine what would happen if I didn't want to use Redis anymore. Then I would have to rewrite an averaging function (and many more) that doesn't even need to know what cache is being used. Writing a clean unit test that focuses on what I expect of the averaging function and nothing else exposed the coupling of two unrelated concepts.

Another thing that was fixed by Unit Tests was the usage of very ugly helper functions. They are disgusting collections of random functions that should really be integrated inside a class. Often times I wrote a helper method to make a short block of code reusable. This is a good idea, but the mess of random functions then binds unrelated classes together and reduces the orthogonality of the codebase. Writing unit tests for helpers are difficult, which goes to show that something is trying to do more than it really should.

Last Updated: 11/23/2020, 8:10:00 AM