Skip to main content

When writing a JUnit test for non-covered legacy code - how important is it to understand the origi [Resolved]

A Tech Lead in my team said:

We're going to use sonar on our (500KLoc) codebase so that everytime you do a commit, it will check the classes you've touched against the coverage goals. If you don't meet the coverage goals for your commit, the build will break.

Another developer responded:

No that has no value. The classes were written against a specification with particular test scenarios in mind. It's not possible to discover what those test scenarios were from the code. You can't write a useful JUnit test on legacy code because you don't understand the original intent.

The first tech lead responded:

You can infer the requirements from the codebase, and the user experience of the software. All the JUnit test does, even if it does capture the original test scenarios, is demonstrate that a working path exists in the code. You can't say that JUnit tests represent a proof, but providing coverage of the code is extremely valuable.

My question is: When writing a JUnit test for non-covered legacy code - how important is it to understand the original scenarios?

EDIT: Note that this is different to the linked question because it is about intent or inferred requirements as input to the JUnit tests on the legacy code.

Asked January 11, 2017
Posted Under: Programming
2 Answers

It is true that you cannot write useful tests if you don't understand the requirements for the code.

But you can learn about the requirements while writing tests - either by reading documentation, or by trying to extract them from the code itself and documenting them through the tests themselves.

And you'll have to do that anyway - you really cannot do any substantial changes at all on existing code without understanding the requirements.

Answered January 11, 2017

So as a consequence, if I make a trivial change in some legacy class, in addition to the trivial change, and the code reviews, and any manual testing done, I also have to write a gazillion of unit tests for twenty year old code.

It's easy enough. The effect is that my estimate for doing the task goes up from half a day to three weeks. If my team leader's boss thinks that this is good value for money for the company, so be it. If my team leader's boss it is a waste of three weeks of working time, then not.

You can also ask me for an estimate to write useful unit tests, which means I must understand what the code is supposed to do, which means my estimate goes up even more.

Answered January 11, 2017
@RichardTingle unless, of course, one of those hundreds of classes (or rather more likely, a class that isn't even automatically touched by such a change) used reflection to call this method "Do"... but otherwise, you are right - there are some refactorings that have lower risk than others and are unlikely to break anything. – Hulk yesterday
 CanDoerz  1 month ago
@Michael Refactor method name "Do" to "usefulName", that could touch hundreds of classes (probably done automatically by an IDE) and (unless something really nasty is happening) you don't really need to understand any of those hundred classes to do this work – Richard Tingle yesterday
 CanDoerz  1 month ago
I would add : you could write a JUnit test for a non-working scenario that pass because of the fact you don't understand what it's supposed to do. – Walfrat yesterday
 CanDoerz  1 month ago
The problem is that if you have legacy code and don't understand the requirements, you probably can't make many, even trivial, changes without breaking things. – Michael Borgwardt yesterday
 CanDoerz  1 month ago
Your Answer