it-swarm.com.de

Wie erstelle ich dynamisch eine Testsuite in JUnit 4?

Ich möchte eine Junit-Testsuite mit JUnit 4 erstellen, bei der die Namen der einzubeziehenden Testklassen erst bekannt sind, wenn die Testsuite ausgeführt wird.

In JUnit 3 könnte ich folgendes machen:

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;
  }
}

und lassen Sie die gatherTestClasses()-Methode damit umgehen, welche Testklassen ausgeführt werden sollen.

In JUnit 4 gibt die documentation an, eine Anmerkung zu verwenden: @SuiteClasses({TestClass1.class, TestClass2.class...}), um meine Testsuite aufzubauen. Es gibt zahlreiche SO Antworten , die zeigen, wie das geht. Leider lassen die Beispiele, die ich sehe, eine dynamisch generierte Liste von Testklassen nicht zulassen.

Diese SO - Antwort schlug vor, ich müsste BlockJUnit4ClassRunner subclass, was ich nicht tun möchte.

Dynamisch spezifizierte Testsuiten scheinen etwas zu sein, das irgendwo in JUnit 4 sein muss. Weiß jemand wo?

49
Tom Tresansky

Ich fand die Classpath-Suite sehr nützlich, wenn sie in meinen Testklassen mit einer Namenskonvention verwendet wird.

https://github.com/takari/takari-cpsuite

Hier ist ein Beispiel:

import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;

@RunWith(ClasspathSuite.class)
@ClassnameFilters({".*UnitTest"})
public class MySuite {
}
26
JavaRocky

Ich habe es mit JUnit 4.8 ausprobiert und es funktioniert:

@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;
     }
}
35
Andrejs

Um eine dynamische Testsuite zu erstellen, müssen Sie die Annotation @RunWith verwenden. Es gibt zwei gängige Möglichkeiten, es zu verwenden:

@RunWith(Suite.class)

Auf diese Weise können Sie angeben, welche Klassen die fragliche Testsuite bilden. Dies entspricht dem Stil von 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;
  }
}

Die entsprechende JUnit 4-Klasse ist:

import org.junit.runners.Suite;

@RunWith(Suite.class)
@SuiteClasses({TestClass1.class, TestClass2.class})
public final class MasterTester {

}

@RunWith(AllTests.class)

Auf diese Weise können Sie dynamisch die Tests angeben, aus denen die Testsuite besteht. Wenn Ihre Tests erst zur Laufzeit bekannt sind, können Sie sie nicht in den Anmerkungen angeben. Sie können diese Konstruktion stattdessen verwenden. Wenn also der JUnit 3-Code lautet:

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;
  }
}

Der äquivalente JUnit 4-Code lautet:

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;
  }
}
34
Danail Nachev

Ich bin nicht sicher, was gatherTestClasses () macht, aber es gibt einige Tests, wenn das Betriebssystem Linux ist, und verschiedene Tests, wenn das Betriebssystem Windows ist. Sie können das in JUnit 4.4 mit Annahmen replizieren:

@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(..)
}

Die Implementierung von getOS() und OperatingSystem ist Ihr benutzerdefinierter Code.

6
Brad Cupit

Hier ist ein vollständiges Beispiel, wie Sie das implementieren können. Es kombiniert zwei testCase-Klassen und eine Suite.

  1. ExampleInstrumentedTest:

    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 {
    
        }
    }
    
  2. ExampleInstrumentedTest2:

    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 {
    
        }
    }
    
  3. ExampleInstrumentedSuite:

    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;
        }
    }
    

Beachten Sie, dass Sie @RunWith(JUnit4.class) anstelle von default @RunWith(AndroidJUnit4.class) in testCase Class verwenden sollten

0
Maher Abuthraa