I am trying to understand these three principles better.
My question is... How do I write tests without violating SRP, OCP, and DRY?
My current design violates DRY because of the similar code in the test files.
I can't merge the test files together because that will violate the Open/Closed principle. (There is a high probability of adding more modules later)
Is there something I'm missing here? If it helps I'm using Ruby and Minitest for this.
Module files
a.rb:
module A
# does an algorithm
end
b.rb:
module B
#does another algorithm
end
Test files
a_test.rb:
class ModuleATest
# tests the algorithm
end
b_test.rb:
class ModuleBTest
# tests the algorithm
end
Test code is quite different from regular code, so although all of those design principles are generally valid in test code, their importance is different there.
Regarding DRY, test code needs to be readable above all else, so it's normal to have a little more duplication in test code than in regular code. It sounds like testing each of your two algorithms requires duplication that you're not showing; address that by extracting the duplication into test helper methods. But do that only if it preserves the clarity of the tests.
Regarding OCP, a test needs to do whatever it needs to do to test the module it's testing. If you got your module design wrong at first and have to split a module into two or something, you'll have to do the same with the test. So don't worry about whether your tests follow OCP, worry about your regular code and the tests will follow.
Regarding SRP, again, a test needs to do whatever it needs to do to test the module it's testing. If a module has too many responsibilities then so will its test. That's a sign that the module needs refactoring to fix the issue for both the module and the test.
Also, there are different kinds of tests. Integration tests by their nature have more responsibilities than unit tests.