Sunday, February 7, 2016

Running Grails 3 JUnit Tests 3-4 Times Faster with Intellij

Grails 3 uses Gradle for the build and most development tasks such as running unit tests.  This is great, but during the edit/compile/test cycle, it adds a good bit of overhead.  When you make a change and want to test it with a unit test, the Gradle process takes much longer than the Intellij/IDEA JUnit test runner (30sec vs. 7sec).

Why is this?  When you make a small change to your code under test, Gradle will recompile the entire groovy codebase.  This takes time.  Also, the Gradle process is much less efficient at detecting code changes than IDEA.  Gradle can take 25sec to compile the code while IDEA takes 3sec.

To make this work, you need to run the unit test using IDEA's JUnit test runner and use the built-in make logic:



Note: This uses the really nice action 'Run context configuration from editor' (Ctrl+Shift+F10 on Windows).  I have also set the JUnit default in the Run Configuration to set the VM Options to '-ea -Dserver.port=8091 -Dgrails.env=test'.  This is not needed for JUnit tests, but I use it for Integration and GUI tests (a future blog).

Also, the IDEA and Gradle compilers tend to step on each other's output class files.  This causes a lot of trouble when the classes are used together.  You need to set the test output path on the project settings to a directory that is different from the Gradle build directory ('.../testi' below):



This avoids the problem, but the output path is overwritten when IDEA updates the project settings from the build.gradle file.  So, if you get weird errors when testing, do a Gradle clean and then check the output settings above.

Update for IDEA 2016.1 (March 2016).  When upgrading, you will need to refresh the gradle project.  This changes the project structure in IDEA significantly, but it makes sure the JUnit tests are run correctly:


If you don't do this, then you get a lot of Spring DEBUG/INFO trace messages like this:

DEBUG o.s.w.c.s.StandardServletEnvironment - Initializing new StandardServletEnvironment

Welcome

Welcome.

This blog is meant to document some of my experiences in producing complex applications/plugins using Grails, Groovy and various tools.  This includes how to use Jetbrains Intellij/IDEA with Grails.

Grails is a very opinionated framework.  If you follow its conventions, then it is one of the most productive environments I know of for developing complex database-oriented web applications.  While Grails is very powerful and concise, if you stray outside of the lines, it can be difficult to diagnose problems.

This blog is meant to help others with these problems.  I considered just logging these on stackoverflow.com, but they don't like it when you post the question and answer together.

I hope others will benefit from my mistakes :).