package org.junit.tests.experimental.max; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.max.MaxCore; import org.junit.internal.runners.JUnit38ClassRunner; import org.junit.runner.Computer; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import org.junit.runner.Result; import org.junit.runner.Runner; import org.junit.runner.manipulation.Filter; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import org.junit.tests.AllTests; public class MaxStarterTest { private MaxCore fMax; private File fMaxFile; @Before public void createMax() { fMaxFile = new File("MaxCore.ser"); if (fMaxFile.exists()) { fMaxFile.delete(); } fMax = MaxCore.storedLocally(fMaxFile); } @After public void forgetMax() { fMaxFile.delete(); } public static class TwoTests { @Test public void succeed() { } @Test public void dontSucceed() { fail(); } } @Test public void twoTestsNotRunComeBackInRandomOrder() { Request request = Request.aClass(TwoTests.class); List<Description> things = fMax.sortedLeavesForTest(request); Description succeed = Description.createTestDescription(TwoTests.class, "succeed"); Description dontSucceed = Description.createTestDescription( TwoTests.class, "dontSucceed"); assertTrue(things.contains(succeed)); assertTrue(things.contains(dontSucceed)); assertEquals(2, things.size()); } @Test public void preferNewTests() { Request one = Request.method(TwoTests.class, "succeed"); fMax.run(one); Request two = Request.aClass(TwoTests.class); List<Description> things = fMax.sortedLeavesForTest(two); Description dontSucceed = Description.createTestDescription( TwoTests.class, "dontSucceed"); assertEquals(dontSucceed, things.get(0)); assertEquals(2, things.size()); } // This covers a seemingly-unlikely case, where you had a test that failed // on the // last run and you also introduced new tests. In such a case it pretty much // doesn't matter // which order they run, you just want them both to be early in the sequence @Test public void preferNewTestsOverTestsThatFailed() { Request one = Request.method(TwoTests.class, "dontSucceed"); fMax.run(one); Request two = Request.aClass(TwoTests.class); List<Description> things = fMax.sortedLeavesForTest(two); Description succeed = Description.createTestDescription(TwoTests.class, "succeed"); assertEquals(succeed, things.get(0)); assertEquals(2, things.size()); } @Test public void preferRecentlyFailed() { Request request = Request.aClass(TwoTests.class); fMax.run(request); List<Description> tests = fMax.sortedLeavesForTest(request); Description dontSucceed = Description.createTestDescription( TwoTests.class, "dontSucceed"); assertEquals(dontSucceed, tests.get(0)); } @Test public void sortTestsInMultipleClasses() { Request request = Request.classes(Computer.serial(), TwoTests.class, TwoTests.class); fMax.run(request); List<Description> tests = fMax.sortedLeavesForTest(request); Description dontSucceed = Description.createTestDescription( TwoTests.class, "dontSucceed"); assertEquals(dontSucceed, tests.get(0)); assertEquals(dontSucceed, tests.get(1)); } public static class TwoUnEqualTests { @Test public void slow() throws InterruptedException { Thread.sleep(100); fail(); } @Test public void fast() { fail(); } } @Test public void rememberOldRuns() { fMax.run(TwoUnEqualTests.class); MaxCore reincarnation = MaxCore.storedLocally(fMaxFile); List<Failure> failures = reincarnation.run(TwoUnEqualTests.class) .getFailures(); assertEquals("fast", failures.get(0).getDescription().getMethodName()); assertEquals("slow", failures.get(1).getDescription().getMethodName()); } @Test public void preferFast() { Request request = Request.aClass(TwoUnEqualTests.class); fMax.run(request); Description thing = fMax.sortedLeavesForTest(request).get(1); assertEquals(Description.createTestDescription(TwoUnEqualTests.class, "slow"), thing); } @Test public void listenersAreCalledCorrectlyInTheFaceOfFailures() throws Exception { JUnitCore core = new JUnitCore(); final List<Failure> failures = new ArrayList<Failure>(); core.addListener(new RunListener() { @Override public void testRunFinished(Result result) throws Exception { failures.addAll(result.getFailures()); } }); fMax.run(Request.aClass(TwoTests.class), core); assertEquals(1, failures.size()); } @Test public void testsAreOnlyIncludedOnceWhenExpandingForSorting() throws Exception { Result result = fMax.run(Request.aClass(TwoTests.class)); assertEquals(2, result.getRunCount()); } public static class TwoOldTests extends TestCase { public void testOne() { } public void testTwo() { } } @Test public void junit3TestsAreRunOnce() throws Exception { Result result = fMax.run(Request.aClass(TwoOldTests.class), new JUnitCore()); assertEquals(2, result.getRunCount()); } @Test public void filterSingleMethodFromOldTestClass() throws Exception { final Description method = Description.createTestDescription( TwoOldTests.class, "testOne"); Filter filter = Filter.matchMethodDescription(method); JUnit38ClassRunner child = new JUnit38ClassRunner(TwoOldTests.class); child.filter(filter); assertEquals(1, child.testCount()); } @Test public void testCountsStandUpToFiltration() { assertFilterLeavesTestUnscathed(AllTests.class); } private void assertFilterLeavesTestUnscathed(Class<?> testClass) { Request oneClass = Request.aClass(testClass); Request filtered = oneClass.filterWith(new Filter() { @Override public boolean shouldRun(Description description) { return true; } @Override public String describe() { return "Everything"; } }); int filterCount = filtered.getRunner().testCount(); int coreCount = oneClass.getRunner().testCount(); assertEquals("Counts match up in " + testClass, coreCount, filterCount); } private static class MalformedJUnit38Test { private MalformedJUnit38Test() { } @SuppressWarnings("unused") public void testSucceeds() { } } @Test public void maxShouldSkipMalformedJUnit38Classes() { Request request = Request.aClass(MalformedJUnit38Test.class); fMax.run(request); } public static class MalformedJUnit38TestMethod extends TestCase { @SuppressWarnings("unused") private void testNothing() { } } @Test public void correctErrorFromMalformedTest() { Request request = Request.aClass(MalformedJUnit38TestMethod.class); JUnitCore core = new JUnitCore(); Request sorted = fMax.sortRequest(request); Runner runner = sorted.getRunner(); Result result = core.run(runner); Failure failure = result.getFailures().get(0); assertThat(failure.toString(), containsString("MalformedJUnit38TestMethod")); assertThat(failure.toString(), containsString("testNothing")); assertThat(failure.toString(), containsString("isn't public")); } public static class HalfMalformedJUnit38TestMethod extends TestCase { public void testSomething() { } @SuppressWarnings("unused") private void testNothing() { } } @Test public void halfMalformed() { assertThat(JUnitCore.runClasses(HalfMalformedJUnit38TestMethod.class) .getFailureCount(), is(1)); } @Test public void correctErrorFromHalfMalformedTest() { Request request = Request.aClass(HalfMalformedJUnit38TestMethod.class); JUnitCore core = new JUnitCore(); Request sorted = fMax.sortRequest(request); Runner runner = sorted.getRunner(); Result result = core.run(runner); Failure failure = result.getFailures().get(0); assertThat(failure.toString(), containsString("MalformedJUnit38TestMethod")); assertThat(failure.toString(), containsString("testNothing")); assertThat(failure.toString(), containsString("isn't public")); } }