Coding standards are something both automating testers and developers should adhere to. Pretty obvious right? Maybe not that obvious might be some of the rules you should follow when writing the code for your tests. Checkstyle is here to help in standardizing your code, so that you can get an early feedback regarding code improvements (earlier than the code review step anyway). It allows you to define a set of basic coding rules that must be followed in your project, and it gives you the opportunity to make your builds fail if someone breaks those rules. This post addresses using checkstyle from a Maven project, by means of the dedicated Maven plugin that you need to declare in your project.
For better understanding of the topic, the checkstyle plugin has been added to my GitHub project too, so make sure you take a look at the pom.xml file ( https://github.com/iamalittletester/learning-project/blob/master/pom.xml ) and the checkstyle.xml file ( https://github.com/iamalittletester/learning-project/blob/master/src/test/resources/checkstyle.xml ). I have used a smaller set of checks for my own project, by removing the ones i did not need from the Maven style configuration.
Checkstyle, what is this?
Checkstyle is a useful plugin that can fail your build when you are trying to compile it, if errors that it was configured to look for are encountered. All the errors encountered are displayed to the console, with a path to the location where they are found (the path to the class and the line and column number from that class). Whenever you want to push code to your repository, you first need to pull the latest code, compile the project, and only if this passes, push the code with your changes. By use of checkstyle, you can make sure, at the compile step, that your project follows coding standards before pushing it into the repository. All you need to do for having this aid in your project is to update your pom.xml file to include the reference and configuration for the checkstyle plugin, and create an xml file that holds the list of checks that will be done. Read further for details.
Importing into your project
To use checkstyle in your project, you must enable this feature first. You will use the maven-checkstyle-plugin, which you will declare in your pom.xml file, in the build section. Where you defined profiles in your build section, you need to declare the plugin within the profile you want to apply it to. For example, if you have a profile that only builds your project and another one that runs the integration tests, you will want a failure to occur when running any of these profiles, if a code mishap has been found.
Importing the plugin means adding the following in your pom.xml, in your <profiles> --> desired <profile> entry --> <build> --> <plugins> section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
To find out which the latest version for this plugin is, of course, look for it in the Maven repository site: https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-checkstyle-plugin .
Configuring the checkstyle file
After importing the checkstyle dependency to your project, you must create a file that will hold the rules that will apply to your code. This is referenced in the pom.xml plugin inclusion, inside the configLocation tag. The file will be found inside your code project, so the path to this file, as defined in the pom.xml entry, must correspond to where the file is found in the project. For example, if you create the file in /src/test/resources, the configLocation entry must be /src/test/resources/checkstyle.xml.
This is the file that will be used to check for code integrity. The checkstyle plugin project has already defined a maximum set of possible checks, well documented, which you can find here: http://checkstyle.sourceforge.net/checks.html. Since not all of them will be useful in your project, you should define a file that will contain only checks relevant for you. There are some standards already defined which you can use, like the Maven checkstyle standard (https://maven.apache.org/shared/maven-shared-resources/maven_checks.html). You might find that some of the rules defined in this file are a bit too much. Therefore you can choose to remove some of the rules defined there, or add some others from the full list of available ones.
There are actually three predefined checkstyle files you can already use out of the box, defined as per Maven, Google and Sun standards. You can find all of these files right here: https://github.com/checkstyle/checkstyle/tree/396a285549e89f618bab45b987c350dd1326379c/src/main/resources.
Note: After creating a checkstyle file from the existing templates, upon compile you might see some errors that are strictly related to the checkstyle file. Some of the things defined in this file might appear as broken. What i do is i simply remove those entries that cause the failures and leave everything else.
For example, in my case, when using the Maven predefined checkstyle file, i would get this error: "Failed during checkstyle configuration: unable to parse configuration stream: Property ${checkstyle.header.file} has not been set". So i will just go into the file, and remove the entire module that uses this property.
The checkstyle.xml file As i mentioned earlier, this is the file that defines what checks will be made. It is a very simple file, which mostly holds an enumeration of 'modules'. Each module corresponds to a check that is performed on the code upon compile time. In order to understand what each check does, just take a look at the name of a module, and look it up in http://checkstyle.sourceforge.net/checks.html.
Some of the checks included in the Maven checkstyle
naming conventions: there are dedicated modules that check that naming conventions are followed, for things like method names, parameter names, constant names, and so on.
import checks: dedicated modules that look for unused imports, imports made with * instead of specific classes/methods, or redundant imports
modifier checks: making sure that modifiers are applied correctly (modifiers meaning public, private, etc)
block checks: making sure you are using the {} braces where they are needed, and that there are no empty blocks in the code
Example - a useful check
One of the most useful checks done as per the 'checkstyle.xml' file is the one for unused imports. Whenever you are building the project, and a class contains an import declaration for an item that is not used in that class, the following kind of exceptions is thrown.
PathToClassAndClassName.java:3:8: error: Unused import - org.eclipse.jetty.io.RuntimeIOException.
PathToClassAndClassName.java:6:8: error: Unused import - org.openqa.selenium.support.ui.SystemClock.
Once the import declaration is removed from the classes mentioned in the checkstyle output, upon a new build, these exceptions will not be thrown again.
Example - removing a check
In this example i used the predefined Maven checkstyle file for performing the checks. One of the checks defined in this file will cause failures described in the next code snippet.
PathToClassAndClassName.java:13:13: error: '(' is not followed by whitespace.
PathToClassAndClassName.java:13:52: error: ')' is not preceded with whitespace.
What this check does is that wherever it sees a '(' character it would expect to see a white space character between this character and the one written right before it; also the check looks for a white space right after the ')' character, before any further text that comes after it.
However i am not interested in these kinds of checks and i would like to remove them. In order to do that, i need to identify which of the modules declared in the 'checkstyle.xml' file are the ones doing the checks. The word 'whitespace' is a hint. So in the checkstyle.xml file i am looking for the 'whitespace' word, and i find a section with a comment:
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
By going to that page, where the explanation of modules is located, i can see that there are a few modules that do all kinds of checks for whitespaces. Because i am not interested in having these as part of my build process, i will comment out all the whitespace modules. Upon doing a new build, the check for whitespaces is not done anymore and this exception is not thrown. Hope this helps, enjoy :)