{"id":11713,"date":"2013-12-02T09:45:00","date_gmt":"2013-12-02T08:45:00","guid":{"rendered":"http:\/\/touk.pl\/blog\/?guid=ec5ead4843d82670a14d41c5703be64a"},"modified":"2022-07-29T11:16:39","modified_gmt":"2022-07-29T09:16:39","slug":"custom-sonarqube-rules-for-unit-tests","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2013\/12\/02\/custom-sonarqube-rules-for-unit-tests\/","title":{"rendered":"Custom SonarQube rules for Unit Tests"},"content":{"rendered":"<h1 id=\"i-need-a-new-rule\">I need a new rule<\/h1>\n<p>In our project we use <a href=\"http:\/\/www.sonarqube.org\/\"><img decoding=\"async\" style=\"border: none;vertical-align: bottom;padding: 0 5px 0 5px\" src=\"http:\/\/2.bp.blogspot.com\/-fIyiv77Yv3E\/UpxBMk5HqvI\/AAAAAAAAAtA\/C6ODvfURZ1c\/s1600\/sonar.png\" \/><\/a> (formely Sonar) to manage our code quality. It is a great tool and I recommend everyone to set it up and read its reports.<\/p>\n<p>Recently, we&#8217;ve agreed that it&#8217;s better to use <a href=\"https:\/\/github.com\/joel-costigliola\/assertj-core\">assertj<\/a> assertions in our unit tests than JUnit&#8217;s. So I&#8217;ve decided to write a simple rule that checks if some of JUnit asserts <code>assertTrue<\/code>, <code>assertFalse<\/code>, <code>assertNull<\/code> and others are used. Then, I&#8217;ve discovered it&#8217;s not so easy to do it with Sonar:<\/p>\n<ul>\n<li>only 10 code quality rules are applied to unit tests &#8211; they are in special repository PMD Unit Tests (<a href=\"http:\/\/jira.codehaus.org\/browse\/SONAR-1076?focusedCommentId=297506&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-297506\">source<\/a>)<\/li>\n<li>these 10 rules are disabled by default, you have to enable them by hand<\/li>\n<li>you cannot add new rules to this group<\/li>\n<\/ul>\n<p>However, it turned out it is doable with a small tricks.<\/p>\n<h1 id=\"custom-pmd-unit-tests-rule-tutorial\">Custom PMD Unit Tests rule tutorial<\/h1>\n<p>Create your XPath expression by following this tutorial on <a href=\"http:\/\/pmd.sourceforge.net\/pmd-5.0.5\/howtowritearule.html\">how to create custom PMD rule<\/a>. There is a visual editor to test your rules as you develop them &#8211; that&#8217;s great. My XPath expression to avoid all JUnit assertions looks like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/\/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']\r\n<\/pre>\n<p>Go to your Sonar installation, log in as an Administrator, head to Quality Profiles and select a profile that you use. Search for &#8220;xpath&#8221; and change Activation to <em>Any<\/em>. You should see two results like this:<\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a style=\"margin-left: 1em;margin-right: 1em\" href=\"http:\/\/1.bp.blogspot.com\/-JQ-N0Dr7kvY\/UpizTMua-II\/AAAAAAAAAsc\/cJkodS8J1tQ\/s1600\/sonar1.jpg\"><img decoding=\"async\" src=\"http:\/\/1.bp.blogspot.com\/-JQ-N0Dr7kvY\/UpizTMua-II\/AAAAAAAAAsc\/cJkodS8J1tQ\/s1600\/sonar1.jpg\" border=\"0\" \/><\/a><\/div>\n<p>Expand <strong>XPath rule template<\/strong> (dont&#8217; worry that it says it&#8217;s deprecated) and then click <em>Copy rule<\/em>. Fill a form with message and XPath and save it. Then take a look at the bottom &#8211; you need an identifier of this rule:<\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a style=\"margin-left: 1em;margin-right: 1em\" href=\"http:\/\/1.bp.blogspot.com\/-cCSx6eM-mFw\/UpkFEf3c-zI\/AAAAAAAAAss\/mbQ7xWuvcUg\/s1600\/sonar3.jpg\"><img decoding=\"async\" src=\"http:\/\/1.bp.blogspot.com\/-cCSx6eM-mFw\/UpkFEf3c-zI\/AAAAAAAAAss\/mbQ7xWuvcUg\/s1600\/sonar3.jpg\" border=\"0\" \/><\/a><\/div>\n<p>You have created a PMD rule, now you need to move it to PMD Unit Tests group. Connect to Sonar&#8217;s MySQL database. Search for your rule by key:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">mysql&gt; select id, plugin_rule_key, plugin_name, parent_id, status from rules where plugin_rule_key='XPathRule_1385721910';\r\n+-----+----------------------+----------------+-----------+-------------+\r\n| id  | plugin_rule_key      | plugin_name    | parent_id | status      |\r\n+-----+----------------------+----------------+-----------+-------------+\r\n| 903 | XPathRule_1385721910 | pmd            | NULL      | DEPRECATED  |\r\n+-----+----------------------+----------------+-----------+-------------+\r\n1 row in set (0.00 sec)<\/pre>\n<p>Update <code>plugin_name<\/code> and <code>status<\/code> (remember to use appropiate primary key for <code>id<\/code> column):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">mysql&gt; update rules set plugin_name='pmd-unit-tests', status='READY' where id=903;\r\nQuery OK, 1 row affected (0.00 sec)\r\nRows matched: 1 Changed: 1 Warnings: 0<\/pre>\n<p>There is one step left. Sonar will change this rule&#8217;s status to <code>REMOVED<\/code> on restart due to his boot checks. You need to trick him and change <code>parent_id<\/code> to other&#8217;s PMD Unit Tests rule. List all these rules and choose one&#8217;s identifier.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">mysql&gt; select id, plugin_name, status from rules where plugin_name='pmd-unit-tests';\r\n+-----+----------------+---------+\r\n| id  | plugin_name    | status  |\r\n+-----+----------------+---------+\r\n| 775 | pmd-unit-tests | READY   |\r\n| 776 | pmd-unit-tests | READY   |\r\n| 777 | pmd-unit-tests | READY   |\r\n| 778 | pmd-unit-tests | READY   |\r\n| 779 | pmd-unit-tests | READY   |\r\n| 780 | pmd-unit-tests | READY   |\r\n| 781 | pmd-unit-tests | READY   |\r\n| 782 | pmd-unit-tests | READY   |\r\n| 783 | pmd-unit-tests | READY   |\r\n| 784 | pmd-unit-tests | READY   |\r\n| 903 | pmd-unit-tests | READY   |\r\n+-----+----------------+---------+\r\n11 rows in set (0.00 sec)\\<\/pre>\n<p>Choose any <code>id<\/code> you like, let&#8217;s say 775 and apply it as <code>parent_id<\/code> to your newly created rule:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">mysql&gt; update rules set parent_id=775 where id=903;\r\nQuery OK, 1 row affected (0.00 sec)\r\nRows matched: 1 Changed: 1 Warnings: 0<\/pre>\n<p>Go to your Quality profile and make sure your rule is active! Check it twice, it&#8217;s easy to forget that step. It&#8217;s all set up, enjoy your analysis!<\/p>\n","protected":false},"excerpt":{"rendered":"It&#8217;s a tutorial about creating new rules for SonarQube analysis to be applied to Unit Tests. It is not trivial and involves a few tricky database steps, so I want to share my tutorial about it.It&#8217;s a tutorial about creating new rules for SonarQube analysis to be applied to Unit Tests. It is not trivial and involves a few tricky database steps, so I want to share my tutorial about it.\n","protected":false},"author":37,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[353,68,482,30],"class_list":{"0":"post-11713","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-code-review","8":"tag-java","9":"tag-quality","10":"tag-testing"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/11713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=11713"}],"version-history":[{"count":7,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/11713\/revisions"}],"predecessor-version":[{"id":14705,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/11713\/revisions\/14705"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=11713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=11713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=11713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}