Testability Affects Code Quality
If you want your code to be truly CLEAN, testability and code quality are key essentials to keep in mind. And they can save you time and money in the long run.
Join the DZone community and get the full member experience.Join For Free
Why is it that if we all agree that CLEAN code is good to strive for that the vast majority of software, as written, lacks these qualities? The only answer I can come up with is that we're so focused on short-term gains that we forget about the long-term consequences. I have to point out that by being a little lazy today, we're making much, much more work for ourselves tomorrow. But there's more than one kind of lazy.
Writing CLEAN code really doesn't take that much more effort up front, and, on the back end, it can save us a lot of time. This is another reason it's so clear to me that testability is a fundamental virtue in software development. If we value testability then, clearly, CLEAN code is the most cost-effective code to write.
As the responsibilities of a class increases so does the possibility of those responsibilities interacting in unintended ways. The number of tests we need in order to verify that this doesn't happen grows exponentially in proportion to the number of responsibilities. For example, if a class has five different responsibilities then we would need 2^n tests (32 tests) to assure that those responsibilities don't interact with each other in unintended ways. By contrast, if we have five encapsulated classes, each with only one responsibility, then those responsibilities can't interact with each other in unintended ways and we would only need five tests to cover the code. There is a huge difference between writing five tests and writing 32 tests. So if we value testability then clearly the most cohesive classes are the most testable and therefore testability tells us to value cohesion.
Code that is tightly coupled is impossible to test in isolation. Code that is loosely coupled requires us to mock out dependencies in order to test in isolation. The more coupling an object has, the more mocking we have to do in order to test that object. If we need to use ephemeral external services then we have to mock it out in order to run automated tests against our code that uses the service.
But there are many situations in which people use mocks when they don't have to. You typically don't have to mock out your own code. Designing a system with a good layered architecture often gives us the level of testability we need without having to resort to using mocks.
Encapsulated code is more straightforward to test. Assertive code is also easier to test because the results can be observed from the code being tested whereas unassertive code requires the use of spies, objects to interrogate other objects in order to validate that they were called correctly.
Finally, redundancy in code means redundancy in tests. These things can add up quickly and turn into major headaches that make both the code and the test hard to maintain.
This is what I love about testability. It's the best teacher. It tells me all the good stuff. I don't expect you to take me on my word that testability is so valuable. But think about it for a while and I'm sure you'll see how valuable it is to evaluate designs in terms of testability.
BY ALL MEANS, BE A LAZY PROGRAMMER.
But be this kind of lazy: too lazy to make a mess, too lazy to make poor code that requires a lot of extra effort in testing. If you're this kind of lazy, you will actually make less work for yourself and your colleagues. The best developers I know are this kind of lazy.
Published at DZone with permission of David Bernstein, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.