<!-- this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.-->
<h1class="post-title-main">Testing your rules</h1>
</div>
<divclass="post-content">
<divclass="summary">Learn how to use PMD's simple test framework for unit testing rules.</div>
<!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. -->
<divclass="alert alert-success"role="alert"><iclass="fa fa-check-square-o"></i><b>Tip:</b> This convention allows you to quickly find the test cases for a given rule:
Just search in the project for a file <codeclass="highlighter-rouge"><RuleName>.xml</code>. Looking at the path of the file, you can figure
out the category. Searching for a class <codeclass="highlighter-rouge"><Category Name>RulesTest</code> gives you the test class.</div>
<p>This test class overrides the method <codeclass="highlighter-rouge">setUp</code> in order to register test cases for the two rules. If there
are more rules, just add additional <codeclass="highlighter-rouge">addRule(...)</code> calls.</p>
<divclass="alert alert-info"role="alert"><iclass="fa fa-info-circle"></i><b>Note:</b> You can also add additionally standard JUnit test methods annotated with <codeclass="highlighter-rouge">@Test</code> to
<p>Each test case is in an own <codeclass="highlighter-rouge"><test-code></code> element. The first defines 0 expected problems, means this code doesn’t
trigger the rule. The second test case expects 1 problem. Since the rule violations also report the exact AST node,
you can verify the line number, too.</p>
<h2id="test-xml-reference">Test XML Reference</h2>
<p>The root element is <codeclass="highlighter-rouge"><test-data></code>. It can contain one or more <codeclass="highlighter-rouge"><test-code></code> and <codeclass="highlighter-rouge"><code-fragment></code> elements.
Each <codeclass="highlighter-rouge"><test-code></code> element defines a single test case. <codeclass="highlighter-rouge"><code-fragment></code> elements are used to share code snippets
between different test cases.</p>
<divclass="alert alert-info"role="alert"><iclass="fa fa-info-circle"></i><b>Note:</b> The XML schema is available at <ahref="https://github.com/pmd/pmd/blob/master/pmd-test/src/main/resources/rule-tests_1_0_0.xsd">rule-tests.xsd</a>.</div>
<p>The <codeclass="highlighter-rouge"><test-code></code> elements understands three optional attributes:</p>
<ul>
<li>
<p><strong>reinitializeRule</strong>: By default, it’s <codeclass="highlighter-rouge">true</code>, so each test case starts with a fresh instantiated rule. Set it
to <codeclass="highlighter-rouge">false</code> to reproduce cases, where the previous run has influences.</p>
</li>
<li>
<p><strong>regressionTest</strong>: By default, it’s <codeclass="highlighter-rouge">true</code>. Set it to <codeclass="highlighter-rouge">false</code>, to ignore and skip a test case.</p>
</li>
<li>
<p><strong>useAuxClasspath</strong>: By default, it’s <codeclass="highlighter-rouge">true</code>. Set it to <codeclass="highlighter-rouge">false</code> to reproduce issues which only
<p><strong><codeclass="highlighter-rouge"><description></code></strong>: Short description of the test case. This will be the JUnit test name in the report.
If applicable, this description should contain a reference to the bug number, this test case reproduces.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><rule-property></code></strong>: Optional rule properties, if the rule is configurable. Just add multiple elements, to
set multiple properties for one test case. For an example, see below.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><expected-problems></code></strong>: The the raw number of expected rule violations, that this rule is expected to report.
For false-positive test cases, this is always “0”. For false-negative test cases, it can be any positive number.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><expected-linenumbers></code></strong>: Optional element. It’s a comma separated list of line numbers.
If there are rule violations reported, then this allows you to
assert the line numbers. Useful if multiple violations should be detected and to be sure that
false positives and negatives don’t erase each other.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><expected-messages></code></strong>: Optional element, with <codeclass="highlighter-rouge"><message></code> elements as children.
Can be used to validate the correct error message, e.g. if the error message references a variable name.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><code></code></strong>: Either the <codeclass="highlighter-rouge"><code></code> element or the <codeclass="highlighter-rouge"><code-ref></code> element is required. It provides the actual code
snippet on which the rule is executed. The code itself is usually wrapped in a “CDATA” section, so that no
further XML escapes (entity references such as &lt;) are necessary.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><code-ref id=...></code></strong>: Alternative to <codeclass="highlighter-rouge"><code></code>. References a <codeclass="highlighter-rouge"><code-fragment></code> defined earlier in the file.
This allows you to share the same code snippet with several test cases. The attribute <codeclass="highlighter-rouge">id</code> must match the
id of the references code fragment.</p>
</li>
<li>
<p><strong><codeclass="highlighter-rouge"><source-type></code></strong>: Optional element that specifies the source code language. This defines the parser that
is used for parsing the code snippet. If not given, <strong>java</strong> is used as default.</p>
<p>The code fragment has just one required attribute: <strong>id</strong>. This is used to reference it via a <codeclass="highlighter-rouge"><code-ref></code> element
inside a <codeclass="highlighter-rouge"><test-code></code>. Similar like the <codeclass="highlighter-rouge"><code></code> element, the content of <codeclass="highlighter-rouge"><code-fragment></code> is usually wrapped
in a “CDATA” section, so that no further XML escapes (entity references such as &lt;) are necessary.</p>
<h3id="complete-xml-example">Complete XML example</h3>
<spanclass="nt"><description></span>Just a description, will be used as the test name for JUnit in the reports<spanclass="nt"></description></span>
<p>Then proceed as described earlier: create your test class, create your test cases and run the unit test.</p>
<h2id="how-the-test-framework-is-implemented">How the test framework is implemented</h2>
<p>The framework uses a custom JUnit test runner under the hood, among a couple of utility classes:</p>
<ul>
<li>
<p><codeclass="highlighter-rouge">SimpleAggregatorTst</code>: This is the base class for the test classes and defines the custom JUnit test runner.
It itself is a subclass of <codeclass="highlighter-rouge">RuleTst</code>.</p>
</li>
<li>
<p><codeclass="highlighter-rouge">RuleTst</code>: contains the logic to parse the XML files and provide a list of <codeclass="highlighter-rouge">TestDescriptor</code>s. Each test descriptor
describes a single test case. It also contains the logic to execute such a test descriptor and assert the results.</p>
</li>
<li>
<p><codeclass="highlighter-rouge">PMDTestRunner</code>: A custom JUnit test runner, that combines two separate test runners: The custom <codeclass="highlighter-rouge">RuleTestRunner</code>
and the standard <codeclass="highlighter-rouge">JUnit4</code> test runner. This combination allows you to add additional standard unit test methods
annotated with <codeclass="highlighter-rouge">@Test</code> to your test class.</p>
<p><em>Note:</em> Since the test class is executed through two test runners, it is actually instantiated twice. Be aware
of this, if you do any initialization in the constructor. Also, the static hooks <codeclass="highlighter-rouge">@BeforeClass</code> and <codeclass="highlighter-rouge">@AfterClass</code>
will be executed twice.</p>
</li>
<li>
<p><codeclass="highlighter-rouge">RuleTestRunner</code>: This test runner executes the test descriptors with the help of <codeclass="highlighter-rouge">RuleTst</code>.</p>