Merge branch 'pr-1256'

This commit is contained in:
Andreas Dangel
2018-08-17 19:12:53 +02:00
12 changed files with 241 additions and 22 deletions

View File

@@ -447,12 +447,13 @@ public class GoodTest {
<rule name="JUnit4TestShouldUseAfterAnnotation"
language="java"
since="4.0"
message="JUnit 4 tests that clean up tests should use the @After annotation"
message="JUnit 4 tests that clean up tests should use the @After annotation, JUnit5 tests should use @AfterEach or @AfterAll"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshoulduseafterannotation">
<description>
In JUnit 3, the tearDown method was used to clean up all data entities required in running tests.
JUnit 4 skips the tearDown method and executes all methods annotated with @After after running each test
JUnit 4 skips the tearDown method and executes all methods annotated with @After after running each test.
JUnit 5 introduced @AfterEach and @AfterAll annotations to execute methods after each test or after all tests in the class, respectively.
</description>
<priority>3</priority>
<properties>
@@ -461,7 +462,7 @@ JUnit 4 skips the tearDown method and executes all methods annotated with @After
<![CDATA[
//CompilationUnit[not(ImportDeclaration/Name[starts-with(@Image, "org.testng")])]
//ClassOrInterfaceBodyDeclaration[MethodDeclaration/MethodDeclarator[@Image='tearDown']]
[count(Annotation//Name[@Image='After'])=0]
[count(Annotation//Name[@Image='After' or @Image='AfterEach' or @Image='AfterAll'])=0]
]]>
</value>
</property>
@@ -485,12 +486,13 @@ public class MyTest2 {
<rule name="JUnit4TestShouldUseBeforeAnnotation"
language="java"
since="4.0"
message="JUnit 4 tests that set up tests should use the @Before annotation"
message="JUnit 4 tests that set up tests should use the @Before annotation, JUnit5 tests should use @BeforeEach or @BeforeAll"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshouldusebeforeannotation">
<description>
In JUnit 3, the setUp method was used to set up all data entities required in running tests.
JUnit 4 skips the setUp method and executes all methods annotated with @Before before all tests
JUnit 4 skips the setUp method and executes all methods annotated with @Before before all tests.
JUnit 5 introduced @BeforeEach and @BeforeAll annotations to execute methods before each test or before all tests in the class, respectively.
</description>
<priority>3</priority>
<properties>
@@ -499,7 +501,7 @@ JUnit 4 skips the setUp method and executes all methods annotated with @Before b
<![CDATA[
//CompilationUnit[not(ImportDeclaration/Name[starts-with(@Image, "org.testng")])]
//ClassOrInterfaceBodyDeclaration[MethodDeclaration/MethodDeclarator[@Image='setUp']]
[count(Annotation//Name[@Image='Before'])=0]
[count(Annotation//Name[@Image='Before' or @Image='BeforeEach' or @Image='BeforeAll'])=0]
]]>
</value>
</property>
@@ -523,13 +525,14 @@ public class MyTest2 {
<rule name="JUnit4TestShouldUseTestAnnotation"
language="java"
since="4.0"
message="JUnit 4 tests that execute tests should use the @Test annotation"
message="JUnit 4 tests that execute tests should use the @Test annotation, JUnit 5 tests should use @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshouldusetestannotation">
<description>
In JUnit 3, the framework executed all methods which started with the word test as a unit test.
In JUnit 4, only methods annotated with the @Test annotation are executed.
In JUnit 5, one of the following annotations should be used for tests: @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest.
</description>
<priority>3</priority>
<properties>
@@ -541,7 +544,12 @@ In JUnit 4, only methods annotated with the @Test annotation are executed.
or ExtendsList/ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]]
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration[MethodDeclaration[@Public=true()]/MethodDeclarator[starts-with(@Image, 'test')]]
[not(Annotation//Name[pmd-java:typeIs('org.junit.Test')])]
[not(Annotation//Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
])]
]]>
</value>
</property>
@@ -1213,8 +1221,14 @@ This rule detects JUnit assertions in object equality. These assertions should b
PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
[ends-with(@Image, '.equals')]
]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
@@ -1253,8 +1267,14 @@ more specific methods, like assertNull, assertNotNull.
Expression/EqualityExpression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral
]
]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
@@ -1295,8 +1315,14 @@ by more specific methods, like assertSame, assertNotSame.
[PrimarySuffix/Arguments
/ArgumentList/Expression
/EqualityExpression[count(.//NullLiteral) = 0]]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>

View File

@@ -1213,8 +1213,14 @@ PrimaryExpression/PrimarySuffix/Arguments/ArgumentList
/Expression/UnaryExpressionNotPlusMinus[@Image='!']
/PrimaryExpression/PrimaryPrefix
]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>

View File

@@ -2058,8 +2058,14 @@ Some JUnit framework methods are easy to misspell.
or (not(@Image = 'tearDown')
and translate(@Image, 'TEARdOWN', 'tearDown') = 'tearDown')]
[FormalParameters[count(*) = 0]]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
@@ -2092,8 +2098,14 @@ The suite() method in a JUnit test needs to be both public and static.
//MethodDeclaration[not(@Static='true') or not(@Public='true')]
[MethodDeclarator/@Image='suite']
[MethodDeclarator/FormalParameters/@ParameterCount=0]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
@@ -3054,8 +3066,14 @@ or
UnaryExpressionNotPlusMinus[@Image='!']
/PrimaryExpression/PrimaryPrefix[Literal/BooleanLiteral or Name[count(../../*)=1]]]
]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')] or //MarkerAnnotation/Name[pmd-java:typeIs('org.junit.Test')]]]
]]>
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>

View File

@@ -61,6 +61,34 @@ public class Foo {
public void tearDown(Method m) {
//...
}
}
]]></code>
</test-code>
<test-code>
<description>#940 False positive with JUnit4TestShouldUseAfterAnnotation when JUnit5's 'AfterEach' is used</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.AfterEach;
public class Foo {
@AfterEach
public void tearDown() {
//...
}
}
]]></code>
</test-code>
<test-code>
<description>#940 False positive with JUnit4TestShouldUseAfterAnnotation when JUnit5's 'AfterAll' is used</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.AfterAll;
public class Foo {
@AfterAll
public void tearDown() {
//...
}
}
]]></code>
</test-code>

View File

@@ -73,6 +73,34 @@ public class Foo {
public void setUp(Method m) {
//...
}
}
]]></code>
</test-code>
<test-code>
<description>#940 False positive with JUnit4TestShouldUseBeforeAnnotation when JUnit5's 'BeforeEach' is used</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.BeforeEach;
public class Foo {
@BeforeEach
public void setUp() {
//...
}
}
]]></code>
</test-code>
<test-code>
<description>#940 False positive with JUnit4TestShouldUseBeforeAnnotation when JUnit5's 'BeforeAll' is used</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.BeforeAll;
public class Foo {
@BeforeAll
public void setUp() {
//...
}
}
]]></code>
</test-code>

View File

@@ -151,6 +151,36 @@ public class TestForX {
<code><![CDATA[
public class MyTests {
public void testBad() { }
}
]]></code>
</test-code>
<test-code>
<description>#940 False positives with JUnit4TestShouldUseTestAnnotation when JUnit5 is used</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class MyTests {
@Test
public void testRegular() { }
@RepeatedTest(2)
public void testRepeated() { }
@TestFactory
public void testFactory() { }
@TestTemplate
public void testTemplate() { }
@ParameterizedTest
@ValueSource(strings = {"Hello", "World"})
public void testParameterized(final String value) { }
}
]]></code>
</test-code>

View File

@@ -65,6 +65,22 @@ JUnit4 - TEST2
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.Test;
public class Foo {
@Test
public void test1() {
assertTrue(a.equals(b));
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
JUnit5 - @Test
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class Foo {
@Test
public void test1() {

View File

@@ -65,6 +65,22 @@ JUnit 4 - assertTrue with null
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.Test;
public class Foo {
@Test
public void test1() {
assertTrue(a==null);
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
JUnit 5 - assertTrue with null - @Test
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class Foo {
@Test
public void test1() {

View File

@@ -108,6 +108,22 @@ JUnit 4 - assert true a == b
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.Test;
public class Foo {
@Test
public void test1() {
assertTrue(a==b);
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
JUnit 5 - assert true a == b - @Test
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class Foo {
@Test
public void test1() {

View File

@@ -70,6 +70,23 @@ JUnit 4 - assertFalse(!)
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.Test;
public class Foo {
@Test
void testBar() {
boolean bar;
assertFalse(!bar);
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
JUnit 5 - assertFalse(!)
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
public class Foo {
@Test
void testBar() {

View File

@@ -110,6 +110,22 @@ JUnit 4 - failure case
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.Test;
public class Foo {
@Test
void bar() {
assertTrue(true);
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
JUnit 5 - failure case - @Test
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class Foo {
@Test
void bar() {