Ich möchte einen großen Test auf kleinere Tests aufteilen, so dass, wenn die kleineren Tests bestanden haben, sie auch bedeuten, dass der große Test bestanden wird (also gibt es keinen Grund, das zu testen) ursprünglicher großer Test). Ich möchte dies tun, weil kleinere Tests normalerweise weniger Zeit, weniger Aufwand und weniger anfällig sind. Ich würde gerne wissen, ob es Testdesignmuster oder Verifikationswerkzeuge gibt, die mir helfen können, diese Testspaltung auf eine robuste Art und Weise zu erreichen.Einen Test auf eine Reihe kleinerer Tests aufteilen
Ich befürchte, dass die Verbindung zwischen den kleineren Tests und dem ursprünglichen Test verloren geht, wenn jemand etwas in den kleineren Tests ändert. Eine weitere Befürchtung ist, dass der Satz kleinerer Tests den großen Test nicht wirklich abdeckt.
Ein Beispiel dessen, was ich bin mit dem Ziel:
//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);
}
+1 die Tests in der gleichen Klasse zu halten (und die Testklasse zu benennen, wie Sie getan haben) wird es weniger wahrscheinlich machen, dass jemand würde versehentlich Bremse der Verbindung zwischen dem Original-Test und kleineren Tests. Danke dafür. Ich vermisse immer noch automatisch, dass die kleineren Tests bedeuten, dass der große Test bestanden wird. – mkorpela
@mkorpela, können Sie ein wenig darauf eingehen, warum es wichtig ist, dass die kleineren Tests bedeuten, dass der große Test bestehen würde? Wenn einer der kleineren Tests fehlschlägt, reicht das nicht aus, um anzuzeigen, dass ein Problem vorliegt? In jedem Fall haben die meisten Testläufer eine Statusanzeige für die gesamte Testklasse. Zum Beispiel markieren die NUnit- und Eclipse-JUnit-Testläufer die Testklasse als "grün", wenn alle Tests in der Klasse bestanden werden, und "rot", wenn ein weiterer Test fehlschlägt. "TheBigTest" würde als bestanden gekennzeichnet werden, wenn alle kleineren Tests bestanden werden. –
@Hurme, ich kann den Originaltest nicht entfernen, wenn er in einer Situation fehlschlägt, in der die kleineren Tests bestanden werden. – mkorpela