JaCoCo has long-standing issues with covering calls of methods that throw exceptions. When such methods are called inside of, if/else branches for example, the result is partial coverage reported for those branches.
However, there is a JaCoCo idiom (https://github.com/jacoco/jacoco/issues/370#issuecomment-267854179) that we can use to avoid uncovered code in those cases. The basic idea is to create and return an exception from a called method and throw that exception from a caller, like in: void fail() { throw create(); } RuntimeException create() { return new RuntimeException(); } How this relates to the Groovy assert statement? For example, for a simple assert statement like assert firstName != null Groovy generates something like ValueRecorder var1 = new ValueRecorder(); try { String var10000 = this.firstName; var1.record(var10000, 8); var1.record(var10000, 8); if (var10000 != null) { var1.clear(); } else { ScriptBytecodeAdapter.assertFailed(AssertionRenderer.render("assert firstName != null", var1), (Object)null); } } catch (Throwable var3) { var1.clear(); throw var3; } The problem with generated code is a ScriptBytecodeAdapter.assertFailed(AssertionRenderer.render("assert firstName != null", var1), (Object)null); method call. Inside that method, an exception is created and thrown. Since JaCoCo cannot cover that line completely, the branch if (var10000 != null) will be reported as partially covered. To avoid those issues, ScriptBytecodeAdapter.assertFailed() can be adapted (or a new method can be introduced) to return the exception instead of throwing it. And then, the calling generated code can throw that returned exception. I have a small project demonstrating the issue and a possible solution here: https://github.com/dmurat/groovy-assert-jacoco-coverage-problem What do you think? Tnx