Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I change code to make it more testable?

I often find myself changing my code to make it more testable, I always wonder whether this is a good idea or not. Some of the things I find myself doing are:

  1. Adding setters just so I can set an internal object to a mock.
  2. Adding getters for internal maps/lists so I can check the internal state of the object has changed after performing some external action.
  3. Wrapping concrete system classes and creating a new interface so I can mock them. For example, File classes can be hard to mock - so I'll create a new interface FileInterface and WrappedFile which extends it and then use the FileInterface instead of File.
like image 989
DLauer Avatar asked Aug 13 '09 00:08

DLauer


People also ask

What is a good testable code?

Testable code is code of high quality. It's cohesive and loosely coupled. It's well encapsulated and in charge of its own state. In short, it's singularly defined in its own proper place so that it's straightforward to maintain and extend.

What are some techniques to improve testability?

Improving testability. Below the system level in the testing hierarchy, improving software testability is largely about improving your code. This will involve things like adding explicit unit tests, utilizing tools that measure test coverage, code reviews, and the use of consistent code style.

Why is a testable code important?

Developers write unit tests for their code to make sure that the code works correctly. This helps to detect and protect against bugs in the future. Sometimes developers write unit tests first, then write the code. This approach is also known as test-driven development (TDD).


2 Answers

Changing your code to make it more testable can be a good thing, but only if it makes your code itself better. Refactoring for testability can make your code better independent of the test suite's needs. Those are good changes.

Of your three examples only #3 is a really good one; often those new interfaces will make your code more flexible for regular use later. #1 is usually addressed for testing via dependency injection, which in my mind makes code needlessly more complicated but does at least make it easier to test. #2 sounds like a bad idea in general.

like image 96
Nelson Avatar answered Oct 13 '22 08:10

Nelson


It is perfectly fine and even recommended to change your code to make it more testable. Here is a list of 10 things that make code hard to test.

I think your third is really ok, but I'm not too fond of the first and the second. If you just open your class internals with getters and setters, then you're giving up encapsulation completely. Depending on your language, there are ways to open visibility of some parameters to test. But what I actually do (which opens encapsulation a little less) is to make the fields I want to check protected (when dependency injection doesn't solve the problem).

Then, on the test project, I inherit the class, and create a "more powerful one", where I can check the internals, but I change nothing on the implementation, and use this class in the tests.

Finally, changing your code to have dependency injection and inversion of control is also highly recommended, as it makes your code easier to test AND more readable and maintainable.

Though changing is ok, the best things to do is to TDD. It produces testable code naturally, once the tests are written first.

like image 44
Samuel Carrijo Avatar answered Oct 13 '22 08:10

Samuel Carrijo