Skip to content

Commit

Permalink
Add a test for JUnitAmbiguousTestClassTest
Browse files Browse the repository at this point in the history
MOE_MIGRATED_REVID=125818292
  • Loading branch information
cushon committed Jun 25, 2016
1 parent f50c93f commit 8eef14c
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 24 deletions.
Expand Up @@ -32,35 +32,20 @@

import com.sun.source.tree.ClassTree;

/**
* @author mwacker@google.com (Mike Wacker)
*/
/** @author mwacker@google.com (Mike Wacker) */
@BugPattern(
name = "JUnitAmbiguousTestClass",
summary = "Test class inherits from JUnit 3's TestCase but has JUnit 4 @Test annotations.",
explanation = "For JUnit3-style tests, behavior is defined in junit.framework.TestCase and "
+ "tests add behavior by overriding methods. For JUnit4-style tests, special "
+ "behavior happens with fields and methods annotated with JUnit 4 annotations. Having "
+ "JUnit4-style tests extend from junit.framework.TestCase (directly or indirectly) "
+ "historically has been a source of test bugs and "
+ "unexpected behavior (e.g.: teardown logic and/or verification does not run because "
+ "JUnit doesn't call the inherited code). "
+ "Error Prone also cannot infer whether the test class runs with JUnit 3 or JUnit 4. "
+ "Thus, even if the test class runs with JUnit 4, Error Prone will not run "
+ "additional checks which can catch common errors with JUnit 4 test classes. "
+ "Either use only JUnit4 classes and annotations and remove the inheritance from "
+ "TestCase, or use only JUnit 3 and remove the @Test annotations. When looking for "
+ "replacements for base test classes, consider using Rules (see the @Rule annotation and "
+ "implementations of TestRule and MethodRule).",
category = JUNIT, maturity = MATURE, severity = WARNING)
name = "JUnitAmbiguousTestClass",
summary = "Test class inherits from JUnit 3's TestCase but has JUnit 4 @Test annotations.",
category = JUNIT,
maturity = MATURE,
severity = WARNING
)
public class JUnitAmbiguousTestClass extends BugChecker implements ClassTreeMatcher {

private static final Matcher<ClassTree> matcher = allOf(
isTestCaseDescendant,
hasJUnit4TestCases);
private static final Matcher<ClassTree> MATCHER = allOf(isTestCaseDescendant, hasJUnit4TestCases);

@Override
public Description matchClass(ClassTree classTree, VisitorState state) {
return matcher.matches(classTree, state) ? describeMatch(classTree) : NO_MATCH;
return MATCHER.matches(classTree, state) ? describeMatch(classTree) : NO_MATCH;
}
}
@@ -0,0 +1,71 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.errorprone.bugpatterns;

import com.google.errorprone.CompilationTestHelper;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** {@link JUnitAmbiguousTestClassTest}Test */
@RunWith(JUnit4.class)
public class JUnitAmbiguousTestClassTest {

private CompilationTestHelper compilationHelper =
CompilationTestHelper.newInstance(JUnitAmbiguousTestClass.class, getClass());

@Test
public void positive() {
compilationHelper
.addSourceLines(
"Positive.java",
"import org.junit.Test;",
"import junit.framework.TestCase;",
"// BUG: Diagnostic contains:",
"public class Positive extends TestCase {",
" @Test",
" public void testCase() {}",
"}")
.doTest();
}

@Test
public void negativeNoExtends() {
compilationHelper
.addSourceLines(
"Positive.java",
"import org.junit.Test;",
"public class Positive {",
" @Test",
" public void testCase() {}",
"}")
.doTest();
}

@Test
public void negativeNoAnnotations() {
compilationHelper
.addSourceLines(
"Positive.java",
"import junit.framework.TestCase;",
"public class Positive extends TestCase {",
" public void testCase() {}",
"}")
.doTest();
}
}
17 changes: 17 additions & 0 deletions docs/bugpattern/JUnitAmbiguousTestClass.md
@@ -0,0 +1,17 @@
For JUnit3-style tests, behavior is defined in `junit.framework.TestCase` and
tests add behavior by overriding methods. For JUnit4-style tests, special
behavior happens with fields and methods annotated with JUnit 4 annotations.
Having JUnit4-style tests extend from `junit.framework.TestCase` (directly or
indirectly) historically has been a source of test bugs and unexpected behavior
(e.g.: teardown logic and/or verification does not run because JUnit doesn't
call the inherited code).

Error Prone also cannot infer whether the test class runs with JUnit 3 or JUnit
4.

Thus, even if the test class runs with JUnit 4, Error Prone will not run
additional checks which can catch common errors with JUnit 4 test classes.
Either use only JUnit4 classes and annotations and remove the inheritance from
TestCase, or use only JUnit 3 and remove the `@Test` annotations. When looking
for replacements for base test classes, consider using Rules (see the `@Rule`
annotation and implementations of `TestRule` and `MethodRule`).

0 comments on commit 8eef14c

Please sign in to comment.