Testing Kotlin with Spock Part 2 – Enum instance method
The enum class with instance method in Kotlin is quite similar to its Java version, but they are look a bit different Read more
The enum class with instance method in Kotlin is quite similar to its Java version, but they are look a bit different Read more
In our project we use (formely Sonar) to manage our code quality. It is a great tool and I recommend everyone to set it up and read its reports.
Recently, we've agreed that it's better to use assertj assertions in our unit tests than JUnit's. So I've decided to write a simple rule that checks if some of JUnit asserts assertTrue
, assertFalse
, assertNull
and others are used. Then, I've discovered it's not so easy to do it with Sonar:
However, it turned out it is doable with a small tricks.
Create your XPath expression by following this tutorial on how to create custom PMD rule. There is a visual editor to test your rules as you develop them - that's great. My XPath expression to avoid all JUnit assertions looks like this:
//PrimaryPrefix/Name[@Image='assertEquals' or @Image='assertNull' or @Image='assertNotNull' or @Image='assertSame' or @Image='assertNotSame' or @Image='assertArrayEquals' or @Image='assertTrue' or @Image='assertFalse']
Go to your Sonar installation, log in as an Administrator, head to Quality Profiles and select a profile that you use. Search for "xpath" and change Activation to Any. You should see two results like this:
Expand XPath rule template (dont' worry that it says it's deprecated) and then click Copy rule. Fill a form with message and XPath and save it. Then take a look at the bottom - you need an identifier of this rule:
You have created a PMD rule, now you need to move it to PMD Unit Tests group. Connect to Sonar's MySQL database. Search for your rule by key:
mysql> select id, plugin_rule_key, plugin_name, parent_id, status from rules where plugin_rule_key='XPathRule_1385721910';
+-----+----------------------+----------------+-----------+-------------+
| id | plugin_rule_key | plugin_name | parent_id | status |
+-----+----------------------+----------------+-----------+-------------+
| 903 | XPathRule_1385721910 | pmd | NULL | DEPRECATED |
+-----+----------------------+----------------+-----------+-------------+
1 row in set (0.00 sec)
Update plugin_name
and status
(remember to use appropiate primary key for id
column):
mysql> update rules set plugin_name='pmd-unit-tests', status='READY' where id=903;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
There is one step left. Sonar will change this rule's status to REMOVED
on restart due to his boot checks. You need to trick him and change parent_id
to other's PMD Unit Tests rule. List all these rules and choose one's identifier.
mysql> select id, plugin_name, status from rules where plugin_name='pmd-unit-tests';
+-----+----------------+---------+
| id | plugin_name | status |
+-----+----------------+---------+
| 775 | pmd-unit-tests | READY |
| 776 | pmd-unit-tests | READY |
| 777 | pmd-unit-tests | READY |
| 778 | pmd-unit-tests | READY |
| 779 | pmd-unit-tests | READY |
| 780 | pmd-unit-tests | READY |
| 781 | pmd-unit-tests | READY |
| 782 | pmd-unit-tests | READY |
| 783 | pmd-unit-tests | READY |
| 784 | pmd-unit-tests | READY |
| 903 | pmd-unit-tests | READY |
+-----+----------------+---------+
11 rows in set (0.00 sec)
Choose any id
you like, let's say 775 and apply it as parent_id
to your newly created rule:
mysql> update rules set parent_id=775 where id=903;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Go to your Quality profile and make sure your rule is active! Check it twice, it's easy to forget that step. It's all set up, enjoy your analysis!
In our project we use (formely Sonar) to manage our code quality. It is a great tool and I recommend everyone to set it up and read its reports.
Recently, we've agreed that it's better to use assertj assertions in our unit tests than JUnit's. So I've decided to write a simple rule that checks if some of JUnit asserts assertTrue
, assertFalse
, assertNull
and others are used. Then, I've discovered it's not so easy to do it with Sonar:
However, it turned out it is doable with a small tricks.
Create your XPath expression by following this tutorial on how to create custom PMD rule. There is a visual editor to test your rules as you develop them - that's great. My XPath expression to avoid all JUnit assertions looks like this:
//PrimaryPrefix/Name[@Image='assertEquals' or @Image='assertNull' or @Image='assertNotNull' or @Image='assertSame' or @Image='assertNotSame' or @Image='assertArrayEquals' or @Image='assertTrue' or @Image='assertFalse']
Go to your Sonar installation, log in as an Administrator, head to Quality Profiles and select a profile that you use. Search for "xpath" and change Activation to Any. You should see two results like this:
Expand XPath rule template (dont' worry that it says it's deprecated) and then click Copy rule. Fill a form with message and XPath and save it. Then take a look at the bottom - you need an identifier of this rule:
You have created a PMD rule, now you need to move it to PMD Unit Tests group. Connect to Sonar's MySQL database. Search for your rule by key:
mysql> select id, plugin_rule_key, plugin_name, parent_id, status from rules where plugin_rule_key='XPathRule_1385721910';
+-----+----------------------+----------------+-----------+-------------+
| id | plugin_rule_key | plugin_name | parent_id | status |
+-----+----------------------+----------------+-----------+-------------+
| 903 | XPathRule_1385721910 | pmd | NULL | DEPRECATED |
+-----+----------------------+----------------+-----------+-------------+
1 row in set (0.00 sec)
Update plugin_name
and status
(remember to use appropiate primary key for id
column):
mysql> update rules set plugin_name='pmd-unit-tests', status='READY' where id=903;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
There is one step left. Sonar will change this rule's status to REMOVED
on restart due to his boot checks. You need to trick him and change parent_id
to other's PMD Unit Tests rule. List all these rules and choose one's identifier.
mysql> select id, plugin_name, status from rules where plugin_name='pmd-unit-tests';
+-----+----------------+---------+
| id | plugin_name | status |
+-----+----------------+---------+
| 775 | pmd-unit-tests | READY |
| 776 | pmd-unit-tests | READY |
| 777 | pmd-unit-tests | READY |
| 778 | pmd-unit-tests | READY |
| 779 | pmd-unit-tests | READY |
| 780 | pmd-unit-tests | READY |
| 781 | pmd-unit-tests | READY |
| 782 | pmd-unit-tests | READY |
| 783 | pmd-unit-tests | READY |
| 784 | pmd-unit-tests | READY |
| 903 | pmd-unit-tests | READY |
+-----+----------------+---------+
11 rows in set (0.00 sec)
Choose any id
you like, let's say 775 and apply it as parent_id
to your newly created rule:
mysql> update rules set parent_id=775 where id=903;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Go to your Quality profile and make sure your rule is active! Check it twice, it's easy to forget that step. It's all set up, enjoy your analysis!
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
What I did here is forcing maven to skip default test phase. Instead of that, I will configure two separate executions (just below the <configuration> section):
<executions>
<execution>
<id>unit-tests</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<includes>
<include>**/*Test.class</include>
<include>**/*Spec.class</include>
</includes>
<excludes>
<exclude>**/*IntegrationTest.class</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<includes>
<include>**/*IntegrationTest.class</include>
</includes>
</configuration>
</execution>
</executions>
In unit test execution I include all test that match naming convention for unit tests (both JUnit and spock ones) and exclude files matching integration test pattern and in integration test execution I did something opposite ;)
package info.rnowak.webtex.common.test;
public interface IntegrationTest {
}
Then we can mark our integration test class with:
@Category(IntegrationTest.class)
Next thing is changing of surefire plugin configuration to omit integration test:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<includes>
<include>**/*Test.class</include>
<include>**/*Spec.class</include>
</includes>
<excludedGroups>info.rnowak.webtex.common.test.IntegrationTest</excludedGroups>
</configuration>
</plugin>
What has changed here is new <excludedGroups> tag with name of interface which marks our integration tests.
Next, we need to add and configure maven-failsafe plugin in order to run test from out integration test group:
<plugin><plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.15</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<groups>info.rnowak.webtex.common.test.IntegrationTest</groups>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
With this configuration failsafe will run only test marked with @Category(IntegrationTest.class) annotation, no matter what their names are.
„Spock, czyli czemu zrezygnowaliśmy z JUnita i Mockito” oraz „Geb” – to tematy, które przedstawili Jakub Nabradalik i Tomasz Kalkosiński z TouK podczas ostatniego Read more