java - unitaria - sintaxis junit
¿Cómo creo dinámicamente un conjunto de pruebas en JUnit 4? (5)
Me gustaría crear un conjunto de pruebas junit utilizando JUnit 4, donde los nombres de las clases de prueba que se incluirán no se conocerán hasta que se ejecute el conjunto de pruebas.
En JUnit 3 podría hacer esto:
public final class MasterTester extends TestCase
{
/**
* Used by junit to specify what TestCases to run.
*
* @return a suite containing what TestCases to run
*/
public static TestSuite suite() {
TestSuite suite = new TestSuite();
for(Class<?> klass : gatherTestClasses()) {
suite.addTestSuite(klass);
}
return suite;
}
}
y deje que el método gatherTestClasses()
se ocupe de averiguar qué clases de prueba ejecutar.
En JUnit 4, la documentation dice que use una anotación: @SuiteClasses({TestClass1.class, TestClass2.class...})
para construir mi suite de pruebas. Hay numerosas respuestas SO que muestran cómo hacer esto. Desafortunadamente, los ejemplos que veo no parecen permitir pasar una lista generada dinámicamente de TestClasses.
Esta respuesta SO sugirió que tendría que subclase BlockJUnit4ClassRunner
que no quiero hacer.
Las suites de prueba dinámicamente especificadas parecen algo que debe estar en JUnit 4 en alguna parte. ¿Alguien sabe dónde?
Aquí hay un ejemplo completo de cómo implementar eso. combina dos clases testCase y una suite.
EjemploInstrumentedTest:
import android.support.test.rule.ActivityTestRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class ExampleInstrumentedTest { @Rule public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class); @Test public void checkInputs() throws Exception { } }
EjemploInstrumentedTest2:
import android.support.test.rule.ActivityTestRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class ExampleInstrumentedTest2 { @Rule public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class); @Test public void checkInputs() throws Exception { } }
EjemploInstrumentedSuite:
import junit.framework.TestSuite; import org.junit.runner.RunWith; import org.junit.runners.AllTests; @RunWith(AllTests.class) public class ExampleInstrumentedSuite { public static TestSuite suite() { TestSuite suite = new TestSuite(); suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest.class)); suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest2.class)); return suite; } }
Tenga en cuenta que debe usar @RunWith(JUnit4.class)
lugar de @RunWith(AndroidJUnit4.class)
predeterminado en testCase Class
Encontré la suite Classpath bastante útil cuando se usa con una convención de nomenclatura en mis clases de prueba.
https://github.com/takari/takari-cpsuite
Aquí hay un ejemplo:
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;
@RunWith(ClasspathSuite.class)
@ClassnameFilters({".*UnitTest"})
public class MySuite {
}
Lo he intentado con JUnit 4.8 y funciona:
@RunWith(AllTests.class)
public class SomeTests
{
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new JUnit4TestAdapter(Test1.class));
suite.addTest(new JUnit4TestAdapter(Test2.class));
return suite;
}
}
No estoy seguro de lo que gatherTestClasses () hace, pero digamos que devuelve algunas pruebas cuando el sistema operativo es Linux y diferentes pruebas cuando el sistema operativo es Windows. Puede replicar eso en JUnit 4.4 con assumptions :
@Test
public void onlyOnLinux() {
assumeThat(getOS(), is(OperatingSystem.LINUX));
// rest of test
}
@Test
public void onlyOnWindows() {
assumeThat(getOS(), is(OperatingSystem.WINDOWS));
// rest of test
}
@Test
public void anyOperatingSystem() {
// just don''t call assumeThat(..)
}
La implementación de getOS()
y OperatingSystem
es su código personalizado.
Para crear un conjunto de pruebas dinámicas, debe usar la anotación @RunWith
. Hay dos formas comunes de usarlo:
@RunWith(Suite.class)
Esto le permite especificar qué clases componen el conjunto de pruebas en cuestión. Esto es equivalente al estilo JUnit 3:
import junit.framework.TestSuite;
import junit.framework.TestCase;
public final class MasterTester extends TestCase {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(TestClass1.class);
suite.addTestSuite(TestClass2.class);
// etc...
return suite;
}
}
La clase equivalente de JUnit 4 será:
import org.junit.runners.Suite;
@RunWith(Suite.class)
@SuiteClasses({TestClass1.class, TestClass2.class})
public final class MasterTester {
}
@RunWith(AllTests.class)
Esto le permite especificar dinámicamente las pruebas, que componen el conjunto de pruebas. Si sus pruebas no son conocidas hasta el tiempo de ejecución, no puede especificarlas en las anotaciones. Puedes usar esta construcción en su lugar. Entonces, si el código JUnit 3 es:
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.framework.Test;
public final class MasterTester extends TestCase {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
for (Test test : findAllTestCasesRuntime()) {
suite.addTest(test);
}
return suite;
}
}
El código JUnit 4 equivalente será:
import org.junit.runners.AllTests;
import junit.framework.TestSuite;
import junit.framework.Test;
@RunWith(AllTests.class)
public final class MasterTester {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
for (Test test : findAllTestCasesRuntime()) {
suite.addTest(test);
}
return suite;
}
}