##### Overview

- Download PMD 3.7
- What's new in PMD 3.7
- PMD in the news
- PMD-related products and books
- Best practices
- Future directions
- Similar projects
- Credits
- License
- What does 'PMD' mean?

##### Usage

- Installation
- Command line usage
- Ant task usage
- Maven plugin usage
- IDE plugin usage
- Suppressing warnings
- Finding duplicated code
- JSP support

##### Customizing PMD

- Compiling PMD
- How to write a rule
- Writing XPath rules
- How to make a rule set
- How it works

##### For example

- Run PMD on a Sourceforge project

##### Rule Sets

- Index
- Basic
- Braces
- Code Size
- Clone
- Controversial
- Coupling
- Design
- Finalizers
- Import Statements
- J2EE
- Javabeans
- JUnit Tests
- Logging (Java)
- Logging (Jakarta)
- Migrating
- Naming
- Optimizations
- Strict Exceptions
- Strings
- Sun Security
- Unused Code
- Java Server Pages
- Java Server Faces

##### Project Documentation

- About PMD
- Project Info
- Project Reports
- Development Process

## JUnit Rules

These rules deal with different problems that can occur with JUnit tests.

### JUnitStaticSuite

The suite() method in a JUnit test needs to be both public and static.

This rule is defined by the following XPath expression:

    //MethodDeclaration[not(@Static='true') or not(@Public='true')]
    [MethodDeclarator/@Image='suite']
    [MethodDeclarator/FormalParameters/@ParameterCount=0]

Here's an example of code that would trigger this rule:

    import junit.framework.*;
    public class Foo extends TestCase {
     public void suite() {} // oops, should be static
     private static void suite() {} // oops, should be public
    }

### JUnitSpelling

Some JUnit framework methods are easy to misspell.

This rule is defined by the following XPath expression:

    //MethodDeclarator[(not(@Image = 'setUp')
     and translate(@Image, 'SETuP', 'setUp') = 'setUp')
     or (not(@Image = 'tearDown')
     and translate(@Image, 'TEARdOWN', 'tearDown') = 'tearDown')]
     [FormalParameters[count(*) = 0]]

Here's an example of code that would trigger this rule:

    import junit.framework.*;
    public class Foo extends TestCase {
     public void setup() {} // oops, should be setUp
     public void TearDown() {} // oops, should be tearDown
    }

### JUnitAssertionsShouldIncludeMessage

JUnit assertions should include a message - i.e., use the three argument version of assertEquals(), not the two argument version.

This rule is defined by the following Java class: net.sourceforge.pmd.rules.junit.JUnitAssertionsShouldIncludeMessage

Here's an example of code that would trigger this rule:

    public class Foo extends TestCase {
     public void testSomething() {
      assertEquals("foo", "bar");
      // Use the form:
      // assertEquals("Foo does not equals bar", "foo", "bar");
      // instead
     }
    }

### JUnitTestsShouldIncludeAssert

JUnit tests should include at least one assertion. This makes the tests more robust, and using assert with messages provide the developer a clearer idea of what the test does.

This rule is defined by the following Java class: net.sourceforge.pmd.rules.junit.JUnitTestsShouldContainAsserts

Here's an example of code that would trigger this rule:

    public class Foo extends TestCase {
      public void testSomething() {
          Bar b = findBar();
      // This is better than having a NullPointerException
      // assertNotNull("bar not found", b);
      b.work();
      }
    }

### TestClassWithoutTestCases

Test classes end with the suffix Test. Having a non-test class with that name is not a good practice, since most people will assume it is a test case. Test classes have test methods named testXXX.

This rule is defined by the following Java class: net.sourceforge.pmd.rules.junit.TestClassWithoutTestCases

Here's an example of code that would trigger this rule:

    //Consider changing the name of the class if it is not a test
    //Consider adding test methods if it is a test
    public class CarTest {
       public static void main(String[] args) {
        // do something
       }
       // code
    }

### UnnecessaryBooleanAssertion

A JUnit test assertion with a boolean literal is unnecessary since it always will eval to the same thing. Consider using flow control (in case of assertTrue(false) or similar) or simply removing statements like assertTrue(true) and assertFalse(false). If you just want a test to halt, use the fail method.

This rule is defined by the following XPath expression:

    //StatementExpression
    [
    .//Name[@Image='assertTrue' or  @Image='assertFalse']
    and
    PrimaryExpression/PrimarySuffix/Arguments/ArgumentList
     /Expression/PrimaryExpression/PrimaryPrefix
      /Literal/BooleanLiteral
    or
    (
    .//Name[@Image='assertTrue' or  @Image='assertFalse']
    and
    PrimaryExpression/PrimarySuffix/Arguments/ArgumentList
     /Expression/UnaryExpressionNotPlusMinus[@Image='!']
    /PrimaryExpression/PrimaryPrefix[Literal/BooleanLiteral or Name[count(../../*)=1]])
    ]

Here's an example of code that would trigger this rule:

    public class SimpleTest extends TestCase {
     public void testX() {
      // Why on earth would you write this?
      assertTrue(true);
     }
    }

### UseAssertEqualsInsteadOfAssertTrue

This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.

This rule is defined by the following XPath expression:

    //PrimaryExpression[
        PrimaryPrefix/Name[@Image = 'assertTrue']
    ][
        PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
        [ends-with(@Image, '.equals')]
    ]

Here's an example of code that would trigger this rule:

    public class FooTest extends TestCase {
     void testCode() {
      Object a, b;
      assertTrue(a.equals(b)); // bad usage
      assertEquals(?a should equals b?, a, b); // good usage
     }
    }

### UseAssertSameInsteadOfAssertTrue

This rule detects JUnit assertions in object references equality. These assertions should be made by more specific methods, like assertSame, assertNotSame.

This rule is defined by the following XPath expression:

    //PrimaryExpression [
        PrimaryPrefix/Name
         [@Image = 'assertTrue' or @Image = 'assertFalse']
    ]
    [PrimarySuffix/Arguments
     /ArgumentList/Expression
     /EqualityExpression[count(//NullLiteral) = 0]]

Here's an example of code that would trigger this rule:

    public class FooTest extends TestCase {
     void testCode() {
      Object a, b;
      assertTrue(a==b); // bad usage
      assertSame(a, b);  // good usage
     }
    }

### UseAssertNullInsteadOfAssertTrue

This rule detects JUnit assertions in object references equality. These assertions should be made by more specific methods, like assertNull, assertNotNull.

This rule is defined by the following XPath expression:

    //PrimaryExpression[
     PrimaryPrefix/Name[@Image = 'assertTrue' or @Image = 'assertFalse']
    ][
     PrimarySuffix/Arguments/ArgumentList[
      Expression/EqualityExpression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral
     ]
    ]

Here's an example of code that would trigger this rule:

     public class FooTest extends TestCase {
      void testCode() {
       Object a = doSomething();
       assertTrue(a==null); // bad usage
       assertNull(a);  // good usage
       assertTrue(a != null); // bad usage
       assertNotNull(a);  // good usage
      }
     }

### SimplifyBooleanAssertion

Avoid negation in an assertTrue or assertFalse test. For example, rephrase: assertTrue(!expr); as: assertFalse(expr);

This rule is defined by the following XPath expression:

    //StatementExpression
    [
    .//Name[@Image='assertTrue' or  @Image='assertFalse']
    and
    PrimaryExpression/PrimarySuffix/Arguments/ArgumentList
     /Expression/UnaryExpressionNotPlusMinus[@Image='!']
    /PrimaryExpression/PrimaryPrefix
    ]

Here's an example of code that would trigger this rule:

    public class SimpleTest extends TestCase {
     public void testX() {
      assertTrue("not empty", !r.isEmpty()); // replace with assertFalse("not empty", r.isEmpty())
      assertFalse(!r.isEmpty()); // replace with assertTrue(r.isEmpty())
     }
    }