Splitting a test to a set of smaller tests

Posted by mkorpela on Stack Overflow See other posts from Stack Overflow or by mkorpela
Published on 2010-04-19T18:34:08Z Indexed on 2010/04/20 2:23 UTC
Read the original article Hit count: 438

I want to be able to split a big test to smaller tests so that when the smaller tests pass they imply that the big test would also pass (so there is no reason to run the original big test). I want to do this because smaller tests usually take less time, less effort and are less fragile. I would like to know if there are test design patterns or verification tools that can help me to achieve this test splitting in a robust way.

I fear that the connection between the smaller tests and the original test is lost when someone changes something in the set of smaller tests. Another fear is that the set of smaller tests doesn't really cover the big test.

An example of what I am aiming at:

//Class under test
class A {

  public void setB(B b){ this.b = b; }

  public Output process(Input i){
    return b.process(doMyProcessing(i));
  }

  private InputFromA doMyProcessing(Input i){ ..  }

  ..

}

//Another class under test
class B {

   public Output process(InputFromA i){ .. }

  ..

}

//The Big Test
@Test
public void theBigTest(){
 A systemUnderTest = createSystemUnderTest(); // <-- expect that this is expensive

 Input i = createInput();

 Output o = systemUnderTest.process(i); // <-- .. or expect that this is expensive

 assertEquals(o, expectedOutput());
}

//The splitted tests

@PartlyDefines("theBigTest") // <-- so something like this should come from the tool..
@Test
public void smallerTest1(){
  // this method is a bit too long but its just an example..
  Input i = createInput();
  InputFromA x = expectedInputFromA(); // this should be the same in both tests and it should be ensured somehow
  Output expected = expectedOutput();  // this should be the same in both tests and it should be ensured somehow

  B b = mock(B.class);
  when(b.process(x)).thenReturn(expected);

  A classUnderTest = createInstanceOfClassA();
  classUnderTest.setB(b);

  Output o = classUnderTest.process(i);

  assertEquals(o, expected);
  verify(b).process(x);
  verifyNoMoreInteractions(b);
}

@PartlyDefines("theBigTest") // <-- so something like this should come from the tool..
@Test
public void smallerTest2(){
  InputFromA x = expectedInputFromA(); // this should be the same in both tests and it should be ensured somehow
  Output expected = expectedOutput();  // this should be the same in both tests and it should be ensured somehow

  B classUnderTest = createInstanceOfClassB();

  Output o = classUnderTest.process(x);

  assertEquals(o, expected);
}

© Stack Overflow or respective owner

Related posts about testing

Related posts about automated-tests