Understanding Gradle #21 – Test and Code Coverage Reporting

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hey! Welcome to Understanding Gradle. In this  episode, we'll look a bit more at how test   reports are generated with Gradle and how  you can configure Gradle to also generate   code coverage reports. In our example project, I  have now added tests to both the data-model and   the business-logic project. As explained in the  videos on testing and configuring the Test task,   we can run the tests in each of these projects  using the Test task and then we'll get reports   in the corresponding build folder. So if  we run the :test task of the data-model,   we get a test report in the build/reports folder.   Showing us which tests were successful and  which failed and the corresponding failures. Running the test task in the business-logic  project, we get a similar report for the tests   in the business-logic project. Now, these  reports are directly generated by JUnit.   There's a binary version of the report  data that can be picked up by some tools,   like Jenkins for example, and there's an html  version rendered by Gradle. I've already shown,   when we talked about configuring the Test task,  how you can influence which reports are generated   and where these reports are placed. We perform  such configuration in our my-java-base convention   plugin. Now another report you might want  to generate is a code coverage report.   Such reports tell you, which parts of your  code have actually been touched by your tests.   For this, you need additional tools. A common  tool in the java world is JaCoCo - the Java   Code Coverage tool. Gradle core directly  supports this if you want this report,   as typical with Gradle, you apply another  plugin which in this case is called 'jacoco'. This plugin actually extends the  functionality of the Test task.   If applied, you get an extension where you could  configure some details. But you can also just   role with the defaults. So only applying this  plugin already gives you code coverage reports.   With the plugin applied, run the tests again -  in this example in the business-logic project.   We can see how an additional  report has been generated.   It shows us which parts of our code  have been touched by our tests. We could generate the same report  now in the data-model project. Imagine now, that you have a larger real project.  In these cases, especially the code coverage   report, is something that you often would like  to see aggregated. So you don't want to look   at like 50 different reports but want to have  one single report that shows you all the code   coverage of your complete code base. And similar,  also the normal test report, you might want to see   in an aggregated view. In the video about  aggregating custom artifacts, we already talked   about use cases like this. There we explored,  how you can generate an aggregated Javadoc of   your complete code base. In that video, we used  variant-aware dependency management features,   like consumable and resolvable Configurations,  because that's something where Gradle does not   offer a direct solution out-of-the-box. For the  test result or code coverage report aggregation,   we could do something similar. But since  recent Gradle 7 versions, this is supported   more directly by Gradle: by offering plugins  that do most of the setup for you. Always when   you aggregate something, you need to decide  in which project this aggregation happens.   So for the Javadoc, we picked our 'app' project  to do the aggregation there (in the other video).   This is a good choice in a setup like ours,  because the 'app' project is a place where also   all the code is aggregated. So the 'app' project  already has dependencies to all other components   of our software. So if we want to collect some  report or verification data from all of our   projects we already have a dependency setup  where all these projects are reached through   the dependency graph. So in a project setup like  this, we can now go to the convention plugin for   our 'app' project and there we now just apply two  additional plugins: The 'test-report-aggregation'   plugin and the 'jacoco-report-aggregation' plugin.  Without doing any further configuration, Grader   can now provide us with aggregated test reports  and aggregated code coverage reports. We can see   that additional tasks have been added to the 'app'  project in the verification group. Calling one   of these tasks, will generate the corresponding  aggregated report. This will also automatically   trigger the execution of all the tests, because  the report data is output of the Test task.   So typically you might want to wire these tasks  into one of your lifecycle tasks now - for example   the :check task. The aggregated report can now be  found in the build folder of the 'app' project.   For a pretty standard setup, this might  already be sufficient for your build   and with these new plugins by Gradle, the  setup is rather straightforward. Still,   you might want to do further customization. And  then you quickly get to a point where you need   a better understanding of what's happening in  the background. One situation where you possibly   want to customize things further is when you have  tests in multiple source sets. In the "configuring   testing" video we used integrationTest as  an example of an additional source set or   an additional test suite. So for example, if we  would configure an integrationTest source set   with the corresponding integrationTest test  suite in our base convention plugin like this, then we would get an additional  aggregation task in the 'app' project   for integration test reporting. So the integration  test reporting, both normal test reports and code   coverage, is completely separated from the  test reporting (which is about the tests   in the 'test' source set only). A customization  you could do now is to also combine all these   reports into one. The use case would be to get  the code coverage of all the combined tests.   For this we can, for example, go and extend  the inputs of the :testCodeCoverageReport task   (the one that for now only looks  at what's happening in the 'test'   source set) to also include the integration  test execution data. The execution data is   something the JaCoCo tool generates. The  testCodeCoverageReport now is configured   to take all the code coverage data that  comes from the tests in the test source set.   We can add more data here, because  executionData is an input of the task and   we can find that there is a configuration called  integrationTestCodeCoverageReportExecutionData.   This is set up by the aggregation plugins where  all the execution data of the integration test   is collected. So we add this as an additional  input here and one thing we need to tweak is   that we need an artifactView with linient set to  "true". Because otherwise, with the dependency   setup we have, Gradle would also look for  execution data in external dependencies.   For more details on this, check out the  video about 'aggregating custom artifacts'.   With this setup, the testCodeCoverageReport  task will now trigger the execution of the test   and the integration test tasks and collect all  the coverage data from all the test executions.   But this is only one example of how you could  customize the setup given by Gradle. The   aggregation plugins we applied here are only  convenience. They use public Gradle API to do   all the setup they are doing. So as with other  concepts, like Feature Variants, these plugins   just make it convenient to get a working solution  quickly for most cases. But internally, they also   only use public Gradle dependency management APIs.  So all the things the plugins do, is something   you could do step-by-step yourself in your build  scripts, if you want a very customized setup. In   the video about 'Feature Variants', I demonstrated  this on the example of Feature Variants.   If you get into a situation where you want to do  such customizations, there is another help task   I would like to show you that can help you. This  task is called :outgoingVariants and can be found   in the help tasks group. If you execute this  task on a project, for example the business-logic   project, you can see all the outgoing variants of  this project. An outgoing variant is technically   the same as a consumable Configuration. So if you  add a consumable Configuration, you will get a new   outgoing variant. And these are all the things  that the project exports that other projects can   then pick up. For example, here we can see that  the project now has a variant that exports the   source code of the project. This is something we  added manually when we wanted to aggregate Javadoc   in the 'aggregating custom artifacts' video. For  more background about all of this, have a look   at my video about 'declaring dependencies' and  my video about 'aggregating custom artifacts'.  This video should give you a quick start if  you wonder about how to set up code coverage   reporting or tweak test reporting in general  with Gradle. The topic is also another example   of aggregating artifacts with Gradle. So you  can explore it to understand the topic more.   On the other hand, if you want to do more specific  customizations, you need a bit of understanding   of Gradle's variant-aware dependency management  to tweak things for your custom requirements.  If you enjoyed this video, please subscribe  to this channel to get notified when new   videos are available. In addition,  you can also follow me on Twitter and   check out the additional resources i  am linking here. See you next time.
Info
Channel: onepiece.Software by Jendrik Johannes
Views: 2,847
Rating: undefined out of 5
Keywords:
Id: uZvzWlP9BYE
Channel Id: undefined
Length: 10min 27sec (627 seconds)
Published: Mon Aug 22 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.