Maven plugins which improve quality of your tests
Creating new Selenium test framework is quite long process which depends on application size and complexity. Such framework can have hundreds of files, thousands lines of code and many dependencies. The framework should be treated as a separate project not just set of tests. When quality of your code is poor then maintenance become hard work and can be very time consuming. Project dependencies have also an impact on your framework quality. If we want to have it done right then everyone working on tests and the framework have to keep the code in the right shape. In this article I will describe how we can use maven plugins to control project dependencies and force everyone to keep java code clean and written in consistent style.
The first plugin I want to discuss is versions-maven-plugin which gives possibility to monitor the versions of your dependencies. It is very important when you use Selenium Web Driver. This project is dynamically changing and keeping it up to date can prevent situation that you are several versions behind the actual one and after updating to the latest a lot of your tests are failing (even if the latest version solves some other issues). The versions-maven-plugin gives possibility to easy monitor what is the versions status of your dependencies. It is not forcing you to update them, so you can decide whether you want to do that or not based on your criteria. To run it automatically by Maven you just need to add the code listed below to your plugins section in the pom.xml.
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> <version>${dependency.updates.plugin.version}</version> <executions> <execution> <phase>validate</phase> <goals> <goal>display-dependency-updates</goal> </goals> </execution> </executions> </plugin>
When you add this plugin to your project and run 'mvn validate' (or Maven with any
subsequent phase) then you can expect the information in your logs. The information
should contains the list of all your dependencies that has lower versions then the
version available in remote repository. The listing should be similar to that shown below:
[INFO] The following dependencies in Dependencies have newer versions: [INFO] com.amazonaws:aws-java-sdk ...................... 1.11.333 -> 1.11.343 [INFO] com.amazonaws:aws-java-sdk-ssm .................. 1.11.333 -> 1.11.343 [INFO] javax.mail:mail ..................................... 1.4 -> 1.5.0-b01 [INFO] org.assertj:assertj-core ............................. 3.9.1 -> 3.10.0 [INFO] org.projectlombok:lombok ........................... 1.16.20 -> 1.18.0 [INFO] org.seleniumhq.selenium:selenium-chrome-driver ....... 3.9.1 -> 3.12.0 [INFO] org.seleniumhq.selenium:selenium-firefox-driver ...... 3.9.1 -> 3.12.0 [INFO] org.slf4j:slf4j-api ............................ 1.7.25 -> 1.8.0-beta2 [INFO] org.slf4j:slf4j-simple ......................... 1.7.25 -> 1.8.0-beta2 [INFO] org.testng:testng ...................................... 6.8 -> 6.14.3
The next plugin I want to talk about is 'maven-dependency-versions-check-plugin' which
verifies that the resolved versions of dependencies are mutually compatible with each other.
It can prevent some problems you are not aware of. My strategy is to always have the project
without dependency conflicts that's why I set the failBuildInCaseOfConflict flag to true so
in case of conflict build is failing.
To make this plugin check your dependencies just add the plugin below with goal check
to your plugins section.
<plugin> <groupId>com.ning.maven.plugins</groupId> <artifactId>maven-dependency-versions-check-plugin</artifactId> <version>${dependency.check.plugin.version}</version> <configuration> <failBuildInCaseOfConflict>true</failBuildInCaseOfConflict> </configuration> <executions> <execution> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin>
When the plugin finds any conflict then you can expect error reported in the Maven
logs. In the description you can find what dependency causing the conflict and what
versions are expected by your dependencies. Example error log is shown below:
[ERROR] Found a problem with the dependency net.bytebuddy:byte-buddy: Resolved version is 1.7.9 Version 1.7.9 was expected by artifacts: org.fluentlenium:fluentlenium-core Version 1.8.3 was expected by artifact: org.seleniumhq.selenium:selenium-ie-driver
The last but not the least plugin worth mentioning is maven-checkstyle-plugin. This
one is much different then those described above. Checkstyle plugin perform static analysis
of your code based on the rules defined in configuration file. List of all checks can
be find here. When any of defined checks
fails then the Maven fails as well. Code listed below has to be added to your plugins
section if you want checkstyle plugin to analyse your code.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>${checkstyle.plugin.version}</version> <executions> <execution> <id>checkstyle</id> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <configLocation>config/checkstyle/check-style-config.xml</configLocation> </configuration> </plugin>
Please note that configuration tag contains link to the configuration file. Example
configuration file that checks the Google coding conventions from Google Java Style
can be found here.
Example maven report with issues found in the code is shown below:
[INFO] There are 3 errors reported by Checkstyle 6.18 with config/checkstyle/check-style-config.xml ruleset. [ERROR] src\main\java\com\testcraftsmanship\e2e\config\Config.java:[17] (sizes) LineLength: Line is longer than 130 characters (found 184). [ERROR] src\main\java\com\testcraftsmanship\e2e\model\pages\MonitoringPage.java:[12,5] (blocks) LeftCurly: '{' at column 5 should be on the previous line. [ERROR] src\main\java\com\testcraftsmanship\e2e\utils\iot\IoTGatewayMock.java:[4,8] (imports) UnusedImports: Unused import - lombok.Setter.
To sum up if you create any java project (e.g. test framework) I suggest you to use
at least those plugins to keep control over your dependencies and consistent style of
the code. If you are in the maintenance phase then after applying them your build can
failed - but still I think that is worth to introduce them and constantly fix found issues.