diff --git a/README.md b/README.md index 5d67704bc..a0235b791 100644 --- a/README.md +++ b/README.md @@ -401,6 +401,10 @@ constraints, not given by ```tuple```. validated. And it might be re-desinged based on findings from the optimization and validation. +### Limitations +* If you have multiple test methods in your test class, you cannot run only one of them. + JCUnit has a helper class to work around the situation. Please refer to [Issue-125](https://github.com/dakusui/jcunit/issues/125). + ### TODOs * Validations * Default value of '@ConfigureWith' annotation: If the test class is implementing @@ -410,7 +414,6 @@ and validation. * FSM feature has already been implemented, but not yet tested in 0.8.x line. * Make the pipeline execute its internal processes where possible. - # References * [JCUnit wiki](https://github.com/dakusui/jcunit/wiki) diff --git a/src/main/java/com/github/dakusui/jcunit8/runners/junit4/JUnit4Runner.java b/src/main/java/com/github/dakusui/jcunit8/runners/junit4/JUnit4Runner.java new file mode 100644 index 000000000..4a481d240 --- /dev/null +++ b/src/main/java/com/github/dakusui/jcunit8/runners/junit4/JUnit4Runner.java @@ -0,0 +1,115 @@ +package com.github.dakusui.jcunit8.runners.junit4; + +import com.github.dakusui.jcunit.core.utils.Checks; +import org.junit.runner.Description; +import org.junit.runner.JUnitCore; +import org.junit.runner.Request; +import org.junit.runner.Result; +import org.junit.runner.manipulation.Filter; + +import java.util.Objects; +import java.util.function.Predicate; + +public class JUnit4Runner { + static final int ALL_TESTCASES = -1; + static final String ANY_METHOD = null; + private final Request request; + + public Result run() { + return new JUnitCore().run(this.getRequest()); + } + + public Request getRequest() { + return this.request; + } + + private JUnit4Runner(Class clazz, String methodName, int testCaseId) { + this.request = Request.classes(clazz).filterWith(createFilter(methodName, testCaseId)); + } + + private Filter createFilter(String methodName, int testCaseId) { + Predicate predicate = createPredicate(methodName, testCaseId); + return new Filter() { + @Override + public boolean shouldRun(Description description) { + if (description.isTest()) { + return predicate.test(description); + } + + // explicitly check if any children want to run + for (Description each : description.getChildren()) { + if (shouldRun(each)) { + return true; + } + } + return false; + } + + @Override + public String describe() { + return String.format( + "Method %s[%s]", + methodName, + testCaseId == ALL_TESTCASES ? + "*" : + Integer.toString(testCaseId) + ); + } + }; + } + + private Predicate createPredicate(String methodName, int testCaseId) { + return description -> description.getMethodName().matches( + (methodName == ANY_METHOD ? + ".*" : + methodName) + + "\\[" + + (testCaseId == ALL_TESTCASES ? + "[0-9]+" : + Integer.toString(testCaseId) + ) + + "\\]" + + ); + } + + public static class Builder { + + private final Class clazz; + private String methodName = ANY_METHOD; + private int testCaseId = ALL_TESTCASES; + + public Builder(Class clazz) { + this.clazz = Objects.requireNonNull(clazz); + } + + public Builder methodName(String methodName) { + this.methodName = Objects.requireNonNull(methodName); + return this; + } + + public Builder allMethods() { + this.methodName = ANY_METHOD; + return this; + } + + public Builder testCase(int testCaseId) { + Checks.checkcond(testCaseId >= 0); + this.testCaseId = testCaseId; + return this; + } + + public Builder allTestCases() { + this.testCaseId = ALL_TESTCASES; + return this; + } + + public JUnit4Runner build() { + return new JUnit4Runner( + this.clazz, + this.methodName, + this.testCaseId + ); + } + } +} diff --git a/src/test/java/com/github/dakusui/jcunit8/examples/quadraticequation/QuadraticEquationExample.java b/src/test/java/com/github/dakusui/jcunit8/examples/quadraticequation/QuadraticEquationExample.java index 12a2ccf00..a1cc5ca93 100644 --- a/src/test/java/com/github/dakusui/jcunit8/examples/quadraticequation/QuadraticEquationExample.java +++ b/src/test/java/com/github/dakusui/jcunit8/examples/quadraticequation/QuadraticEquationExample.java @@ -62,6 +62,7 @@ public void performScenario1( @From("b") int b, @From("c") int c ) { + System.out.println("-------performScenario1"); double x1 = sut1(a, b, c); assertThat(Math.abs(a * x1 * x1 + b * x1 + c), new LessThan<>(0.01)); } @@ -74,6 +75,7 @@ public void performScenario2( @From("b") int b, @From("c") int c ) { + System.out.println("------performScenario2"); double x2 = sut2(a, b, c); assertThat(Math.abs(a * x2 * x2 + b * x2 + c), new LessThan<>(0.01)); } diff --git a/src/test/java/com/github/dakusui/jcunit8/tests/components/utils/JUnit4RunnerTest.java b/src/test/java/com/github/dakusui/jcunit8/tests/components/utils/JUnit4RunnerTest.java new file mode 100644 index 000000000..f193ada2a --- /dev/null +++ b/src/test/java/com/github/dakusui/jcunit8/tests/components/utils/JUnit4RunnerTest.java @@ -0,0 +1,63 @@ +package com.github.dakusui.jcunit8.tests.components.utils; + +import com.github.dakusui.crest.Crest; +import com.github.dakusui.jcunit8.examples.quadraticequation.QuadraticEquationExample; +import com.github.dakusui.jcunit8.runners.junit4.JUnit4Runner; +import com.github.dakusui.jcunit8.testutils.UTUtils; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.Result; + +import static com.github.dakusui.crest.Crest.allOf; +import static com.github.dakusui.crest.Crest.assertThat; + +public class JUnit4RunnerTest { + @BeforeClass + public static void beforeClass() { + UTUtils.configureStdIOs(); + } + + @Test + public void whenRunSpecificMethodForSpecificTestCase$thenOnlyTheMethodIsExecutedForTheTestCase() { + assertThat( + new JUnit4Runner.Builder(QuadraticEquationExample.class).testCase(1).methodName("performScenario2").build().run(), + allOf( + Crest.asBoolean(Result::wasSuccessful).isTrue().$(), + Crest.asInteger(Result::getRunCount).eq(1).$() + ) + ); + } + + @Test + public void whenRunSpecificMethodForAnyTestCase$thenOnlyTheMethodIsExecutedForAllTestCases() { + assertThat( + new JUnit4Runner.Builder(QuadraticEquationExample.class).allTestCases().methodName("performScenario2").build().run(), + allOf( + Crest.asBoolean(Result::wasSuccessful).isTrue().$(), + Crest.asInteger(Result::getRunCount).eq(46).$() + ) + ); + } + + @Test + public void whenRunAllMethodsForSpecificTestCase$thenAllMethodsAreExecutedForTheTestCase() { + assertThat( + new JUnit4Runner.Builder(QuadraticEquationExample.class).testCase(1).allMethods().build().run(), + allOf( + Crest.asBoolean(Result::wasSuccessful).isTrue().$(), + Crest.asInteger(Result::getRunCount).eq(2).$() + ) + ); + } + + @Test + public void whenRunAllMethodsForAnyTestCase$thenAllMethodsAreExecutedForAllTestCases() { + assertThat( + new JUnit4Runner.Builder(QuadraticEquationExample.class).allTestCases().allTestCases().build().run(), + allOf( + Crest.asBoolean(Result::wasSuccessful).isTrue().$(), + Crest.asInteger(Result::getRunCount).eq(92).$() + ) + ); + } +} diff --git a/src/test/java/com/github/dakusui/jcunit8/testutils/testsuitequality/CoveringArrayGenerationUtils.java b/src/test/java/com/github/dakusui/jcunit8/testutils/testsuitequality/CoveringArrayGenerationUtils.java index cab718a75..04434bea0 100644 --- a/src/test/java/com/github/dakusui/jcunit8/testutils/testsuitequality/CoveringArrayGenerationUtils.java +++ b/src/test/java/com/github/dakusui/jcunit8/testutils/testsuitequality/CoveringArrayGenerationUtils.java @@ -49,7 +49,7 @@ public static FactorSpace createFactorSpace(String prefix, int numLevels, int nu IntStream.range(0, numFactors).mapToObj( i -> String.format("%s-%02d", prefix, i) ).map( - name -> p(name, IntStream.range(0, numLevels).mapToObj(i -> i).collect(toList()).toArray()) + name -> p(name, IntStream.range(0, numLevels).boxed().collect(toList()).toArray()) ).collect(toList()), Collections.emptyList() ) @@ -215,7 +215,7 @@ public static List constraints(Constraint... constraints) { } public static Constraint c(Predicate constraint, String... involvedKeys) { - return Constraint.create(String.format("c%s", involvedKeys), constraint, involvedKeys); + return Constraint.create(String.format("c%s", Arrays.toString(involvedKeys)), constraint, involvedKeys); } public static List parameters(Parameter... parameters) { @@ -256,7 +256,7 @@ public static class TestSuiteBuilder { private int strength; - public TestSuiteBuilder() { + TestSuiteBuilder() { this.setStrength(2); } @@ -265,22 +265,22 @@ public TestSuiteBuilder setStrength(int strength) { return this; } - public TestSuiteBuilder addSeed(Tuple tuple) { + TestSuiteBuilder addSeed(Tuple tuple) { this.seeds.add(tuple); return this; } - public TestSuiteBuilder addConstraint(String name, Predicate constraint, String... args) { + TestSuiteBuilder addConstraint(String name, Predicate constraint, String... args) { this.constraints.add(Constraint.create(name, constraint, args)); return this; } - public TestSuiteBuilder addParameter(String name, Object... levels) { + TestSuiteBuilder addParameter(String name, Object... levels) { this.parameters.add(p(name, levels)); return this; } - public TestSuite buildTestSuite() { + TestSuite buildTestSuite() { return new Pipeline.Standard().execute( new Config.Builder( new Requirement.Builder(