Skip to content

Commit

Permalink
#40: Do not discover plain classes without tests
Browse files Browse the repository at this point in the history
------------------------------------------------------------------------
On behalf of the community, the JUnit Lambda Team thanks
msg systems ag (http://www.msg-systems.com) for supporting
the JUnit crowdfunding campaign!
------------------------------------------------------------------------
  • Loading branch information
marcphilipp committed Jan 3, 2016
1 parent 0fd7630 commit 9a57fa3
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 60 deletions.
Expand Up @@ -145,6 +145,16 @@ void resolvesJUnit3Suites() {
assertThat(testMethodDescriptor.getChildren()).isEmpty(); assertThat(testMethodDescriptor.getChildren()).isEmpty();
} }


@Test
void doesNotResolvePlainOldJavaClassesWithoutAnyTest() {
Class<?> testClass = PlainOldJavaClassWithoutAnyTest.class;
TestPlanSpecification specification = build(forClass(testClass));

TestDescriptor engineDescriptor = engine.discoverTests(specification);

assertThat(engineDescriptor.getChildren()).isEmpty();
}

public static class PlainJUnit4TestCaseWithSingleTestWhichFails { public static class PlainJUnit4TestCaseWithSingleTestWhichFails {


@org.junit.Test @org.junit.Test
Expand Down Expand Up @@ -192,6 +202,14 @@ public static junit.framework.Test suite() {


} }


public static class PlainOldJavaClassWithoutAnyTest {

public void doSomething() {
// no-op
}

}

private static <T> T getOnlyElement(Iterable<T> iterable) { private static <T> T getOnlyElement(Iterable<T> iterable) {
Iterator<T> iterator = iterable.iterator(); Iterator<T> iterator = iterable.iterator();
Preconditions.condition(iterator.hasNext(), () -> "iterable must not be empty: " + iterable); Preconditions.condition(iterator.hasNext(), () -> "iterable must not be empty: " + iterable);
Expand Down

This file was deleted.

@@ -0,0 +1,52 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.junit.gen5.engine.junit4.discovery;

import java.lang.reflect.Method;
import java.util.List;
import java.util.function.Predicate;

import org.junit.gen5.commons.util.ReflectionUtils;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import org.junit.internal.builders.JUnit4Builder;
import org.junit.runner.Runner;

class DefensiveAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBuilder {

private final DefensiveJUnit4Builder defensiveJUnit4Builder = new DefensiveJUnit4Builder();

DefensiveAllDefaultPossibilitiesBuilder() {
super(true);
}

@Override
protected JUnit4Builder junit4Builder() {
return defensiveJUnit4Builder;
}

private static class DefensiveJUnit4Builder extends JUnit4Builder {

private final Predicate<Method> hasTestAnnotation = new IsPotentialJUnit4TestMethod();

@Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
if (containsTestMethods(testClass)) {
return super.runnerForClass(testClass);
}
return null;
}

private boolean containsTestMethods(Class<?> testClass) {
List<Method> testMethods = ReflectionUtils.findMethods(testClass, hasTestAnnotation);
return !testMethods.isEmpty();
}
}
}
Expand Up @@ -8,7 +8,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
*/ */


package org.junit.gen5.engine.junit4; package org.junit.gen5.engine.junit4.discovery;


import static org.junit.gen5.commons.util.ReflectionUtils.MethodSortOrder.HierarchyDown; import static org.junit.gen5.commons.util.ReflectionUtils.MethodSortOrder.HierarchyDown;


Expand All @@ -20,17 +20,18 @@
/** /**
* @since 5.0 * @since 5.0
*/ */
public class IsJUnit4TestClassWithTests implements Predicate<Class<?>> { class IsJUnit4TestClassWithTests implements Predicate<Class<?>> {


private static final IsJUnit4TestMethod isTestMethod = new IsJUnit4TestMethod(); private static final IsPotentialJUnit4TestMethod isTestMethod = new IsPotentialJUnit4TestMethod();


private static final IsPotentialJUnit4TestClass isPotentialTestClass = new IsPotentialJUnit4TestClass(); private static final IsPotentialJUnit4TestClass isPotentialTestClass = new IsPotentialJUnit4TestClass();


@Override @Override
public boolean test(Class<?> testClassCandidate) { public boolean test(Class<?> testClassCandidate) {
if (!isPotentialTestClass.test(testClassCandidate)) if (!isPotentialTestClass.test(testClassCandidate))
return false; return false;
// Do not use AnnotationUtils.hasAnnotation since JUnit4 does not support meta annotations. // Do not use AnnotationUtils.hasAnnotation since JUnit4 does not support meta
// annotations.
return testClassCandidate.isAnnotationPresent(RunWith.class) || hasTestMethods(testClassCandidate); return testClassCandidate.isAnnotationPresent(RunWith.class) || hasTestMethods(testClassCandidate);
} }


Expand Down
Expand Up @@ -8,17 +8,16 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
*/ */


package org.junit.gen5.engine.junit4; package org.junit.gen5.engine.junit4.discovery;


import static org.junit.gen5.commons.util.ReflectionUtils.isAbstract; import static org.junit.gen5.commons.util.ReflectionUtils.*;
import static org.junit.gen5.commons.util.ReflectionUtils.isPublic;


import java.util.function.Predicate; import java.util.function.Predicate;


/** /**
* @since 5.0 * @since 5.0
*/ */
public class IsPotentialJUnit4TestClass implements Predicate<Class<?>> { class IsPotentialJUnit4TestClass implements Predicate<Class<?>> {


@Override @Override
public boolean test(Class<?> candidate) { public boolean test(Class<?> candidate) {
Expand Down
@@ -0,0 +1,30 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.junit.gen5.engine.junit4.discovery;

import java.lang.reflect.Method;
import java.util.function.Predicate;

import org.junit.Test;

/**
* @since 5.0
*/
class IsPotentialJUnit4TestMethod implements Predicate<Method> {

@Override
public boolean test(Method method) {
// Don't use AnnotationUtils.hasAnnotation since JUnit 4 does not support
// meta-annotations
return method.isAnnotationPresent(Test.class);
}

}
Expand Up @@ -15,39 +15,44 @@
import org.junit.gen5.engine.TestPlanSpecificationElementVisitor; import org.junit.gen5.engine.TestPlanSpecificationElementVisitor;
import org.junit.gen5.engine.junit4.descriptor.JUnit4TestDescriptor; import org.junit.gen5.engine.junit4.descriptor.JUnit4TestDescriptor;
import org.junit.gen5.engine.junit4.descriptor.RunnerTestDescriptor; import org.junit.gen5.engine.junit4.descriptor.RunnerTestDescriptor;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.junit.runner.Runner; import org.junit.runner.Runner;
import org.junit.runners.model.RunnerBuilder;


public class JUnit4TestPlanSpecificationResolver { public class JUnit4TestPlanSpecificationResolver {


private EngineDescriptor engineDescriptor; private final EngineDescriptor engineDescriptor;


public JUnit4TestPlanSpecificationResolver(EngineDescriptor engineDescriptor) { public JUnit4TestPlanSpecificationResolver(EngineDescriptor engineDescriptor) {
this.engineDescriptor = engineDescriptor; this.engineDescriptor = engineDescriptor;
} }


public void resolve(TestPlanSpecification specification) { public void resolve(TestPlanSpecification specification) {
RunnerBuilder runnerBuilder = new DefensiveAllDefaultPossibilitiesBuilder();
specification.accept(new TestPlanSpecificationElementVisitor() { specification.accept(new TestPlanSpecificationElementVisitor() {


@Override @Override
public void visitClass(Class<?> testClass) { public void visitClass(Class<?> testClass) {
Runner runner = new AllDefaultPossibilitiesBuilder(true).safeRunnerForClass(testClass); Runner runner = runnerBuilder.safeRunnerForClass(testClass);

if (runner != null) {
RunnerTestDescriptor runnerDescriptor = new RunnerTestDescriptor(engineDescriptor, testClass, runner); engineDescriptor.addChild(createCompleteRunnerTestDescriptor(testClass, runner));
addChildrenRecursively(runnerDescriptor);

engineDescriptor.addChild(runnerDescriptor);
}

private void addChildrenRecursively(JUnit4TestDescriptor parent) {
for (Description description : parent.getDescription().getChildren()) {
JUnit4TestDescriptor child = new JUnit4TestDescriptor(parent, description);
parent.addChild(child);
addChildrenRecursively(child);
} }
} }
}); });
} }


private RunnerTestDescriptor createCompleteRunnerTestDescriptor(Class<?> testClass, Runner runner) {
RunnerTestDescriptor runnerTestDescriptor = new RunnerTestDescriptor(engineDescriptor, testClass, runner);
addChildrenRecursively(runnerTestDescriptor);
return runnerTestDescriptor;
}

private void addChildrenRecursively(JUnit4TestDescriptor parent) {
for (Description description : parent.getDescription().getChildren()) {
JUnit4TestDescriptor child = new JUnit4TestDescriptor(parent, description);
parent.addChild(child);
addChildrenRecursively(child);
}
}

} }

0 comments on commit 9a57fa3

Please sign in to comment.