DEV Community

Discussion on: Add unit tests on a project already in progress

Collapse
 
eljayadobe profile image
Eljay-Adobe

Adding unit tests to an existing legacy code base is difficult.

Adding unit tests to new code being added to an existing legacy code base as you go, that's achievable. And laudable!

CAUTION: I strongly caution against throwing out the old legacy code base and starting over greenfield. Despite how appealing that may seem, it's highly risky. Our industry has few examples of success, and many examples of failure doing that.

In my previous project, when we ran into a bug we'd write a bug regression test that exercised the code so as to reproduce the bug. Usually that test was written after the problem was discovered, but often (but not always) before the fix was made.

The bug regression tests, user acceptance tests, integration tests, and system tests were run as a big batch process farmed out over many machines. If run serially, they'd take about 660 hours to run, but since they were farmed out they ran in about 6 hours.

We also had about 70% code coverage for unit tests. (If excluding all the UI code -- since that code isn't amenable to unit testing -- then the code coverage was about 95%, I'd guestimate.) The unit tests took about 10 seconds to run, including spin up time. We were diligent to make sure no integration tests snuck into our unit tests, since that would devalue the unit test suite and likely make the unit tests take much longer than desired.

Code that was written with unit tests almost invariably had properties such as actually being unit testable, actually being tested, often adhered diligently to SOLID principles, adhered to DRY for the code and WET for the tests, often had referential transparency (i.e., no global dependencies), much more robust than code without (because the unit tests provided a guarantee of basic correctness), high level of maintainability, much more malleable, used inversion-of-control pattern extensively (because that's necessary to make things unit testable with mocks or fakes), and was refactor-able with confidence.

Code that was not written with unit tests (e.g., the entirety of the prior code base, two projects back) was typically highly intractable to adding unit tests, and lacked the above properties. Adding unit tests to code designed without unit testing in mind was poor ROI because the code was often highly entangled, tightly coupled, low cohesion, poor encapsulation, dependent on global state, and overly mutable.

Also, unit tests are only run in debug. The other tests are only run in release.

The QEs write the user acceptance tests, integration tests, and system tests.

The developers write the unit tests. And usually also wrote the bug regression tests, since although the QE often discovered the problem or worked with the customer who filed an incident and reproduced the problem, the real cause of the problem was not always obvious by the repro steps.

Collapse
 
anwar_nairi profile image
Anwar • Edited

Thank you so much for sharing your experience! Very instructive, I am getting this testimonial in mind when pursuing my unit test journey.

I absolutely agree with you on the part when you say that poor code, with low to no code principles, even for new projects, will not benefit from unit tests. Very true.