Consider a test suite like this:public class MyTestSuite {   @Test   public void test_something() {      testHelperMethod(value11, value12, value13);   }   @Test   public void test_something_else_meaningful_name() {      testHelperMethod(othervalue21, othervalue22, othervalue23);   }   // ...   private void testHelperMethod(String value1, String value2, String value3) {       // set up part (independent of value1, value2, value3)       // action part (dependent on values)       // assertion part (dependent on values)       // tear down part (independent of values)   }}In other words, all the test cases are executed via a single, parametrized helper method, which is structured according to the arrange-act-assert schema. The test cases just call this method with various parameters, according to what exactly needs to be tested.Question: what is the disadvantage, if any, of structuring the tests like this, and does this (anti?)-pattern have a common name?RemarksI tried to Google for it for a long time, including on SO andon the blog, but could not find anything useful till now.This question is the closest I found, but the answers there address other aspects/problems, namely:assertions/setup code intermixed (not the case here, as allassertions are at the end of the helper method) more assertions per test (also the case in my example, but I think this is an unrelated issue)responsibility of helper method is not clear: I think in mycase it is clear, just it is different from the 'traditional' oneTo be more precise, the assertion part in testHelperMethod is also a separate utility method (called with many-many parameters), but I guess that does not matter much for the question. (I.e.: why is it bad practice to delegate testing to helper methods, if at all?)In case this matters, this is an integration test, but I suspect that the answer would be the same for unit-tests as well.EDIT: Changed the names of the test cases to avoid confusion (Previously, they were called test1, test2. In fact, the tests in the project in questions do have meaningful names, I had just made this simplification myself.)
Test cases do all the work through helper method -- bad practice?
testing;anti patterns;integration tests;junit
As others have already stated: nothing wrong with breaking out a separate method to avoid duplication.However, as others have also stated: you do want each individual test to clearly indicate what it is setting up and what it is asserting.Test names will help with that enormously and I assume your actual code has more meaningful names than Test1 and Test2.To make the code of the individual tests more intelligible - ie make it clearer what each test is doing just by reading the code of that test, you can break up your helper method into its obvious parts.Yes, it will duplicate what would otherwise be confined to the single helper as you will now have a number of calls in each test when you could do it with one, but it allows you to give more meaningful names to each helper method.// ArrangesomeHelper = MakeSomeDependency(arg1, arg2, arg3);sut = MakeSomeObjectUnderTest(someHelper);// Actsut.DoSomething();// AssertAssertCommonAsserts(sut, expectedvalue1, expectedvalue2);Assert.AreEqual(sut.SomeProperty, expectedValue);Note: I am not a fan of multiple asserts in a single test, but there are cases when a single fact can only be checked by multiple asserts and I can also think of a number of scenarios in which having some guard asserts before the actual fact being asserted can help in debugging failures.If you use a language that supports named parameters, you can make your tests even more intelligible by using that feature so the method call doesn't just convey the values used, but also what those values are used for.// ArrangesomeHelper = MakeSomeDependency(    knownNames: arg1,     unknownNames: arg2,     lookingFor: arg3);sut = MakeSomeObjectUnderTest(someHelper);// Actsut.DoSomething();// AssertAssertCommonAsserts(    objectUnderTest: sut,     numberOfItemsFound: expectedvalue1,     nameOfItemFound: expectedvalue2);Assert.AreEqual(sut.SomeProperty, expectedValue);