Greenhouse of Test Automation: Part IV
How to store JUnit tests in an InfluxDB
Instead of looking at bad memes, wouldn’t you rather extract data of JUnit
tests and store them in an InfluxDB
? Visualizing those tests on a Grafana
dashboard to build trust in test automation and analyze the results ? Or are you looking for inspiration to create your own solution? In all cases you are in the right place!
🌱 Welcome to the blog series about visualizing test automation. Dutch greenhouses excel in sustainability and serve as a main thread running through this journey. I wrote about the concept of extracting test results, storing them in an
InfluxDB
, and how this works forTestCafé
tests. Now it’s time to deep dive in the implementation forJUnit
tests, to enable visualization on aGrafana
dashboard!
How to extract and store JUnit tests in an InfluxDB?
I didn’t find an out the box solution to help me answer this question, so I made my own; junit-listener-influxdb
. Use it in a project with JUnit
tests to extract and store them in an InfluxDB
. It’s ALMOST plug & play:
- 🔌 Plug
- Import thejunit-reporter-influxdb
as a dependency - 🔧 Configure
- Set the right environment variables - 🎮 Play
- Run yourInflux
database on the specified host and port
- Run yourJUnit
tests
That’s it! Note that the junit-listener-influxdb
library is generically set up where the tests run remotely via Gitlab
pipelines. You might want to save data of your tests specific to your context. My advice? Check out the details and possibilities in this README. Then fork the library and specify it to save the most relevant data for your project, like test types, categories, or application names. I will give an example why and how to customize test categories.
Customize JUnit test extraction
When visualizing tests on a dashboard, it is very useful to group them based on categories, risk or feature for example. This is enabled by storing tags with the tests. Create tags with fixed values in the junit-listener-influxdb
library like the example below shows.
Add the relevant categories to yourJUnit
test (note the difference between Java & Kotlin). These tags will be saved along the tests, to enable filtering during the setup of a Grafana
dashboard.
Java:
@Tag(TestMetadata.Risk.HIGH)
@Tag(TestMetadata.Feature.LOGIN)
Kotlin:
@Tags(
Tag(TestMetadata.Risk.HIGH),
Tag(TestMetadata.Feature.LOGIN)
)
How does the junit-reporter-influxdb
library work?
The picture below shows the concept of extracting and storing test results in an InfluxDB. With every step I will explain the implementation for the junit-reporter-influxdb
library below.
Extract JUnit test data
My environment is enriched with different flavors of backend tests. The tests are written both inJava
and Kotlin
, and there is a distinction of three different test layers:
- Unit : test in isolation using the
Mockito
,JPA
orWebMVC
extension. - Component : test within
Spring
application context using theSpringBootTest
extension, external services are mocked usingWireMock
. - Integration : in the
Spring
application context the integration between the system under test and external services is tested.
Luckily they have one thing in common; the tests run using the JUnit
testrunner. The JUnit
TestExecutionListener
provides an interface to tap into the tests during a test run, and supports all above mentioned extension flavors. Only condition is that the tests must run using JUnit5
. Upgrading from JUnit4
to JUnit5
can be a challenge for old services running with ancient Spring
versions, I can tell 😵.
The methods of TestExecutionListener
are called during the test run; at the beginning and end of a test, class or complete test run. junit-listener-influxdb
contains the implementation of those methods, and a service loader to enable the use of the library by other services.
Store JUnit test data in an InfluxDB
Let’s zoom in the executionFinished
method of the TestExecutionListener, which is called when a JUnit
test is completed. I use the influxdb-java
client to interact with InfluxDB
in a Java
environment. This client helps to formulate, address and send the data to an InfluxDB
.
- ✉️ Formulate; set the data in the correct structure
The completed test is accessible via the input parameters ofexecutionFinished
. Relevant data like duration of the test are processed and structured in the plain old Java object (POJO)TestResult
. Annotations provided byinfluxdb-java
ensure that the test result fits perfectly in theInflux
tabletestResults
(@Measurement
). The POJO is saved as aPoint
, which is a single data record inInflux
terminology.
All test results are collected in a batch ofPoints
; we only want to connect with the database and send all results at once, when the test run is done. Finally, I reset the test result to extract the next one with a clean slate.
- 📧 Address; set the properties for the correct database
When thejunit-listener-influxdb
starts, anInfluxDB
object is created with the correct address of the Influx database we want to send the data to. These are originated from the environment variables. You can set them locally when running the application, or as remote variables in your pipeline.
- 📩 Send; post the data to the database
When the test run is completed, a connection with the addressed Influx database is setup and checked. All test results collected in the batch of Points are validated and send with a REST POST call, provided by theInfluxDB
client. Afterwards, the connection with the database is closed.
That’s it! To me it was quite a puzzle to find out how the data of JUnit
tests can be extracted and processed. Several moments I wanted to throw my laptop through the window, but with help from my colleagues of deTesters
and some perseverance I struggled through. I learned a lot and can monitor JUnit
tests on a Grafana
dashboard now!
What’s next? How to display this testdata in an Grafana
dashboard, and the key question of this project; how is it used in practice and what is the result? Stay tuned!
🖇️ You are welcome to connect with me on LinkedIn, or follow me on Medium, to keep updated with my latest blogs.