<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Marc Philipp</title><description/><link>https://marcphilipp.de/</link><item><title>STF Milestone 10: Documentation improvements</title><link>https://marcphilipp.de/blog/2026/01/25/stf-milestone-10-documentation-improvements/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2026/01/25/stf-milestone-10-documentation-improvements/</guid><pubDate>Sun, 25 Jan 2026 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;JUnit has long been publishing its User Guide and API documentation for every release on &lt;a href=&quot;https://junit.org&quot;&gt;junit.org&lt;/a&gt;.
However, there was no way to easily navigate between versions and no warnings when browsing outdated or preview releases.
In &lt;a href=&quot;https://github.com/junit-team/junit-framework/issues/5244&quot;&gt;this milestone&lt;/a&gt;, I finally had the chance to resolve these long-standing issues.&lt;/p&gt;
&lt;!--more--&gt;
&lt;/div&gt;
&lt;p&gt;Prior to this milestone, the only way of accessing a specific version was by manually changing the URL.
For example, the User Guide for version 5.13.0 is available at &lt;a href=&quot;https://docs.junit.org/5.13.0/user-guide/&quot;&gt;https://docs.junit.org/5.13.0/user-guide/&lt;/a&gt;.
Manually changing &lt;code&gt;5.13.0&lt;/code&gt; in the URL to &lt;code&gt;5.14.0&lt;/code&gt; takes one to the corresponding version.
However, doing so requires knowledge about which versions are available and is inconvenient and error-prone.&lt;/p&gt;
&lt;p&gt;Moreover, users should view the documentation specific to the version they’re using.
Looking at documentation that is older or more recent can be confusing: it can point out features that have better replacements or don’t exist yet in a stable version.
Therefore, we have decided to adopt &lt;a href=&quot;https://antora.org/&quot;&gt;Antora&lt;/a&gt; which – among other things – adds a version selector to each documentation page.
In addition, since it’s aware of all versions being deployed as part of the documentation site, it provides the ability to render a banner on &lt;a href=&quot;https://docs.junit.org/6.0.1/&quot;&gt;outdated&lt;/a&gt; or &lt;a href=&quot;https://docs.junit.org/6.1.0-M1/&quot;&gt;preview&lt;/a&gt; releases.
Rather than having a single HTML page for each version, Antora encourages splitting the documentation into separate pages that are focussed on a single topic.&lt;/p&gt;
&lt;p&gt;I started working on this milestone after we had released version 6.0.0.
I really wanted 6.0.0 to be part of the new documentation site, though.
Similarly, since we will continue to support 5.14.x for some time, at least the latest 5.14.x release should also be available on the Antora site.
Therefore, I decided to write &lt;a href=&quot;https://github.com/marcphilipp/antora-migrator&quot;&gt;a script&lt;/a&gt; that would migrate our Asciidoctor-based documentation to an Antora component so that I could run it on different Git branches for different releases.
This strategy worked out nicely in the end!&lt;/p&gt;
&lt;p&gt;Another challenge was adopting Antora’s support for the latest release and prerelease versions.
We wanted to ensure that the those versions continued to be available at &lt;a href=&quot;https://docs.junit.org/current/&quot;&gt;https://docs.junit.org/current/&lt;/a&gt; and &lt;a href=&quot;https://docs.junit.org/snapshot/&quot;&gt;https://docs.junit.org/snapshot/&lt;/a&gt;, respectively.
Before adopting Antora, we had achieved that by publishing the latest release in two places: &lt;code&gt;/current&lt;/code&gt; and &lt;code&gt;/6.0.2&lt;/code&gt;, for example.
Instead of duplicating pages, Antora relies on redirects.
However, GitHub Pages – where the site had been hosted until now – does not support redirects.
After trying a few alternatives, we decided to migrate to &lt;a href=&quot;https://statichost.eu&quot;&gt;statichost.eu&lt;/a&gt; for hosting instead.
It was very simple to set up and connect to GitHub.
It being privacy-focused and hosted in the EU was a nice bonus.&lt;/p&gt;
&lt;p&gt;Overall, I’m very happy how it turned out!
Antora provides a solid foundation to build on.
I’m sure the few limitations we encountered (e.g. its search functionality) will be improved over time.
But don’t take my word for it and have a look at &lt;a href=&quot;https://docs.junit.org&quot;&gt;docs.junit.org&lt;/a&gt; for yourself!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.junit.org&quot;&gt;&lt;img src=&quot;/img/posts/2026-01-25-stf-milestone-10-documentation-improvements/docs-site-screenshot.png&quot; alt=&quot;screenshot of Antora-based documentation site&quot; class=&quot;img-responsive img-thumbnail&quot;&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 8: Improved parallel test execution</title><link>https://marcphilipp.de/blog/2026/01/18/stf-milestone-8-improved-parallel-test-execution/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2026/01/18/stf-milestone-8-improved-parallel-test-execution/</guid><pubDate>Sun, 18 Jan 2026 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;Since its introduction in JUnit 5.3, parallel test execution has become a popular feature of the JUnit Platform.
When enabled, it can significantly speed up test execution for many projects.
However, there were still some rough edges and long-standing issues that needed to be addressed.
Therefore, &lt;a href=&quot;https://github.com/junit-team/junit-framework/issues/5115&quot;&gt;this milestone&lt;/a&gt; focused on improving the parallel test execution capabilities of JUnit.&lt;/p&gt;
&lt;!--more--&gt;
&lt;/div&gt;
&lt;h3 id=&quot;vintage-engine&quot;&gt;Vintage engine&lt;/h3&gt;
&lt;p&gt;JUnit Platform’s parallel execution support works for all test engines extending &lt;code&gt;HierarchicalTestEngine&lt;/code&gt;, such as JUnit Jupiter, Spock, and Cucumber.
Notably missing from that list is the JUnit Vintage engine, which runs JUnit 3 and JUnit 4 tests.
While the Vintage engine is only intended as a temporary migration aid, there are projects that will probably never migrate all their tests to JUnit Jupiter.
To help projects that use both the Vintage engine and Jupiter (or another testing framework based on the JUnit Platform), the Vintage engine has been enhanced to support parallel test execution as well, starting with version 5.12.0.
As documented in the &lt;a href=&quot;https://docs.junit.org/6.0.2/migrating-from-junit4.html#parallel-execution&quot;&gt;User Guide&lt;/a&gt;, the behavior can be enabled and configured via the following configuration parameters:&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;properties&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;junit.vintage.execution.parallel.enabled&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;junit.vintage.execution.parallel.classes&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;junit.vintage.execution.parallel.methods&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;junit.vintage.execution.parallel.pool-size&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thanks to contributor &lt;a href=&quot;https://github.com/YongGoose&quot;&gt;Yongjun Hong&lt;/a&gt; for implementing this feature!&lt;/p&gt;
&lt;h3 id=&quot;resource-locks&quot;&gt;Resource locks&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.junit.org/6.0.2/writing-tests/parallel-execution.html#synchronization&quot;&gt;Resource locks&lt;/a&gt; are a declarative mechanism to control which tests may run in parallel.
For example, the test methods in the following example class use resource locks to prevent conflicting concurrent access to system properties:&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Execution&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;CONCURRENT&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; StaticSharedResourcesDemo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ResourceLock&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SYSTEM_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; READ&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; customPropertyIsNotSetByDefault&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ResourceLock&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SYSTEM_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; READ&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; anotherCustomPropertyIsNotSetByDefault&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.other.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ResourceLock&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SYSTEM_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; READ_WRITE&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; canSetCustomPropertyToApple&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;apple&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;apple&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While &lt;code&gt;customPropertyIsNotSetByDefault()&lt;/code&gt; cannot run concurrently with &lt;code&gt;canSetCustomPropertyToApple()&lt;/code&gt;, it may run in parallel with &lt;code&gt;anotherCustomPropertyIsNotSetByDefault()&lt;/code&gt;.
In order to express that, prior to JUnit 5.12, every test method in this test class needs to be annotated with a &lt;code&gt;@ResourceLock&lt;/code&gt; annotation.
To reduce this boilerplate, a new &lt;code&gt;target&lt;/code&gt; attribute has been added to the &lt;code&gt;@ResourceLock&lt;/code&gt; annotation.
It allows specifying that the lock applies to all test methods in the annotated class.
A test method such as &lt;code&gt;canSetCustomPropertyToApple()&lt;/code&gt; may define a lock with the same &lt;code&gt;value&lt;/code&gt; and a stricter &lt;code&gt;mode&lt;/code&gt;, though.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Execution&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;CONCURRENT&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ResourceLock&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SYSTEM_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; READ&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; target&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; CHILDREN&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; StaticSharedResourcesDemo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; customPropertyIsNotSetByDefault&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; anotherCustomPropertyIsNotSetByDefault&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.other.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ResourceLock&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SYSTEM_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; READ_WRITE&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; canSetCustomPropertyToApple&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;apple&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;apple&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; System&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getProperty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;my.prop&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another improvement was made for test engines such as Cucumber where parent containers have no execution behavior of their own but solely exist to group child tests.
Similar to Jupiter’s &lt;code&gt;@Isolated&lt;/code&gt; annotation, Cucumber scenarios can be annotated with &lt;code&gt;@isolated&lt;/code&gt; to indicate that they should not run in parallel with other tests/scenarios.
However, the JUnit Platform always pulled up that lock to the test class/feature level since a test class in Jupiter or Spock can have its own execution behavior (for example, a Jupiter &lt;code&gt;@AfterAll&lt;/code&gt; method).
This made it impossible to run Cucumber features in parallel if one of them contained an isolated scenario.
The Cucumber engine will be able to configure this behavior once the new API is released in JUnit 6.1.&lt;/p&gt;
&lt;h3 id=&quot;open-heart-surgery-reimplementing-parallel-test-execution&quot;&gt;&lt;s&gt;Open heart surgery&lt;/s&gt; Reimplementing parallel test execution&lt;/h3&gt;
&lt;p&gt;The initial implementation of parallel test execution in the JUnit Platform is based on Java’s &lt;code&gt;ForkJoinPool&lt;/code&gt;.
Given the hierarchical nature of the test tree, this seemed like a natural fit.
For example, a test class would perform its setup, then submit its test methods to the pool for execution (&lt;em&gt;fork&lt;/em&gt;), wait for them to finish (&lt;em&gt;join&lt;/em&gt;), and finally perform its teardown.&lt;/p&gt;
&lt;p&gt;However, over time, it became clear that this implementation decision is causing issues in certain scenarios.
For example, when the code under test also uses &lt;code&gt;ForkJoinPool&lt;/code&gt; for its own parallelism, the pool used to run tests in parallel would suddenly spawn additional threads.
This could lead to more tests running in parallel than configured, causing resource exhaustion and out-of-memory errors.
Another problem was unwanted work-stealing in the presence of resource locks.
We had to implement special handling to prevent tests holding a set of resource locks from stealing work from other tests with conflicting locks.&lt;/p&gt;
&lt;p&gt;There have been several suggestions over the years on how to deal with these issues.
Most recently, a contributor proposed a solution that used a regular thread pool &lt;em&gt;in addition&lt;/em&gt; to the existing &lt;code&gt;ForkJoinPool&lt;/code&gt;.
This milestone finally gave me a chance to explore this idea.
However, I soon realized that using two thread pools would not be a good solution.
Not only would it double the number of threads and require context switching between the two pools, it would also add significant complexity to the implementation.
Therefore, I set out to reimplement parallel test execution using a regular thread pool with “simple” work-stealing support.
As you can imagine, that was quite an undertaking, and difficult to test properly.
Luckily, I had help!
Both, &lt;a href=&quot;https://github.com/leonard84&quot;&gt;Leonard Brünings&lt;/a&gt; from Spock and &lt;a href=&quot;https://github.com/mpkorstanje&quot;&gt;Rien Korstanje&lt;/a&gt; from Cucumber helped challenge, test, and improve the new implementation.
A huge thanks to both of them!&lt;/p&gt;
&lt;p&gt;The new implementation will be an opt-in feature in JUnit 6.1.
You can already give it a try today by using version &lt;a href=&quot;https://docs.junit.org/6.1.0-M1/release-notes.html#v6.1.0-M1&quot;&gt;6.1.0-M1&lt;/a&gt; (see &lt;a href=&quot;https://docs.junit.org/6.1.0-M1/writing-tests/parallel-execution.html#config-executor-service&quot;&gt;User Guide&lt;/a&gt; for details).
If we receive promising feedback in 6.1, we will switch the default to the new implementation in 6.2.
Looking forward to your feedback!&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 7: Safe cancellation</title><link>https://marcphilipp.de/blog/2025/12/28/stf-milestone-7-safe-cancellation/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/12/28/stf-milestone-7-safe-cancellation/</guid><pubDate>Sun, 28 Dec 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;Prior to this milestone, the JUnit Platform provided no safe way to cancel test execution early, e.g. after the first test failed.
The only option was to forcibly terminate the JVM running the tests.
However, that also caused cleanup operations, such as deleting temporary files or stopping Docker containers used in tests, to be skipped.
Letting all tests run is often wasteful in terms of resources such as CPU and causes longer feedback cycles for developers.
Therefore, &lt;a href=&quot;https://github.com/junit-team/junit-framework/issues/4725&quot;&gt;this milestone&lt;/a&gt; was all about introducing a safe cancellation mechanism to the JUnit Platform.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The Launcher API is the main entry point to the JUnit Platform for IDEs and build tools.
The new &lt;a href=&quot;https://docs.junit.org/6.0.1/api/org.junit.platform.engine/org/junit/platform/engine/CancellationToken.html&quot;&gt;&lt;code&gt;CancellationToken&lt;/code&gt;&lt;/a&gt; API allows clients to request cancellation of a running test execution.
The &lt;code&gt;Launcher&lt;/code&gt; interface already contained two methods for executing tests; one taking a &lt;code&gt;LauncherDiscoveryRequest&lt;/code&gt; and another taking a &lt;code&gt;TestPlan&lt;/code&gt;.
Rather than adding two additional overloads that take a &lt;code&gt;CancellationToken&lt;/code&gt;, a new &lt;a href=&quot;https://docs.junit.org/6.0.1/api/org.junit.platform.launcher/org/junit/platform/launcher/LauncherExecutionRequest.html&quot;&gt;&lt;code&gt;LauncherExecutionRequest&lt;/code&gt;&lt;/a&gt; class was introduced that encapsulates all parameters required for test execution, including an optional &lt;code&gt;CancellationToken&lt;/code&gt;.
This design allows for future extensions of the test execution parameters without breaking existing clients.
A &lt;code&gt;LauncherExecutionRequest&lt;/code&gt; can be created from a &lt;code&gt;LauncherDiscoveryRequest&lt;/code&gt;, a &lt;code&gt;TestPlan&lt;/code&gt;, or via &lt;code&gt;LauncherDiscoveryRequestBuilder.forExecution()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using these new concepts, clients can implement “fail fast” behavior as follows (see &lt;a href=&quot;https://docs.junit.org/6.0.1/advanced-topics/launcher-api.html#launcher-cancellation&quot;&gt;User Guide&lt;/a&gt; for details):&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;CancellationToken&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; cancellationToken&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; CancellationToken&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;TestExecutionListener&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; failFastListener&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; TestExecutionListener&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; executionFinished&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;TestIdentifier&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; identifier&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; TestExecutionResult&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getStatus&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; FAILED&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            cancellationToken&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;cancel&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;LauncherExecutionRequest&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; executionRequest&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LauncherDiscoveryRequestBuilder&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;selectors&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;selectClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;MyTestClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;forExecution&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;cancellationToken&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;cancellationToken&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;listeners&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;failFastListener&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;try&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;LauncherSession&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; session&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LauncherFactory&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;openSession&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    session&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getLauncher&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;execute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;executionRequest&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cancelling tests relies on test engines checking and responding to the &lt;code&gt;CancellationToken&lt;/code&gt;.
As a stop-gap solution, the &lt;code&gt;Launcher&lt;/code&gt; also checks the token and cancels test execution when multiple test engines are present at runtime.&lt;/p&gt;
&lt;p&gt;At the time of writing, the following test engines support cancellation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JUnit Jupiter&lt;/li&gt;
&lt;li&gt;JUnit Vintage&lt;/li&gt;
&lt;li&gt;JUnit Platform Suite&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/junit-team/testng-engine&quot;&gt;TestNG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;All &lt;code&gt;HierarchicalTestEngine&lt;/code&gt; implementations such as &lt;a href=&quot;https://spockframework.org/&quot;&gt;Spock&lt;/a&gt; and &lt;a href=&quot;https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-junit-platform-engine&quot;&gt;Cucumber&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the changes in JUnit, I submitted a &lt;a href=&quot;https://github.com/apache/maven-surefire/pull/3155&quot;&gt;pull request&lt;/a&gt; to the Maven Surefire project.
It uses the new cancellation mechanism to implement support for Surefire’s &lt;a href=&quot;https://maven.apache.org/surefire/maven-surefire-plugin/examples/skip-after-failure.html&quot;&gt;&lt;code&gt;skipAfterFailureCount&lt;/code&gt;&lt;/a&gt; feature.
It was merged and released in Maven Surefire 3.5.4.
For Gradle, there’s an &lt;a href=&quot;https://github.com/gradle/gradle/issues/34184&quot;&gt;open issue&lt;/a&gt; to implement similar support across all testing frameworks.&lt;/p&gt;
&lt;p&gt;To try out the new safe cancellation mechanism, you need to use &lt;a href=&quot;https://docs.junit.org/6.0.1/release-notes.html#v6.0.0&quot;&gt;JUnit 6.0.0&lt;/a&gt; or later.
I am looking forward to your feedback!&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 6: Improved Kotlin support</title><link>https://marcphilipp.de/blog/2025/08/21/stf-milestone-6-improved-kotlin-support/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/08/21/stf-milestone-6-improved-kotlin-support/</guid><pubDate>Thu, 21 Aug 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;Kotlin is a highly popular language for JVM applications (and beyond).
Not only is it the default language for Android apps, it has also become increasingly popular for backend applications.
JUnit Jupiter has always supported writing tests in Kotlin and provides Kotlin-specific assertions.
However, there were some long-standing and highly-voted issues for improving the usability when writing tests and extensions in Kotlin which have now been addressed in this STF milestone.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The improvements made in this milestone fall into the following categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#kotlin-contracts&quot;&gt;Kotlin contracts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jspecify-nullness-annotations&quot;&gt;JSpecify nullness annotations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#kotlin-suspending-functions&quot;&gt;Kotlin suspending functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#kotlin-sequence-support&quot;&gt;Kotlin &lt;code&gt;Sequence&lt;/code&gt; support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;kotlin-contracts&quot;&gt;Kotlin contracts&lt;/h2&gt;
&lt;p&gt;Kotlin is a statically typed language and the Kotlin compiler has powerful static analysis capabilities.
One of them and an often cited difference between Java and Kotlin is its null safety.&lt;/p&gt;
&lt;p&gt;Given a &lt;code&gt;Person&lt;/code&gt; class, a Kotlin variable can be of type &lt;code&gt;Person&lt;/code&gt; or &lt;code&gt;Person?&lt;/code&gt; where the former does not allow assigning &lt;code&gt;null&lt;/code&gt; while the latter does.
When using a variable of a nullable type such as &lt;code&gt;Person?&lt;/code&gt;, the compiler requires code to deal with the possibility of the value being &lt;code&gt;null&lt;/code&gt;.
For example, to access the &lt;code&gt;firstName&lt;/code&gt; property of &lt;code&gt;Person&lt;/code&gt; class on &lt;code&gt;person: Person?&lt;/code&gt;, one can’t just use &lt;code&gt;person.firstName&lt;/code&gt;.
Instead, one usually either writes &lt;code&gt;person!!.firstName&lt;/code&gt; (which will throw a &lt;code&gt;NullPointerException&lt;/code&gt; in case &lt;code&gt;person&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;) or &lt;code&gt;person?.firstName&lt;/code&gt; (which will evaluate to &lt;code&gt;null&lt;/code&gt; if &lt;code&gt;person&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;person.firstName&lt;/code&gt; otherwise).&lt;/p&gt;
&lt;p&gt;To make dealing with nullable types easier, Kotlin has a feature called “smart casts”.
If the Kotlin compiler can deduce that a value can no longer be &lt;code&gt;null&lt;/code&gt; because it has already been checked for nullness, it allows using it directly without the &lt;code&gt;!!.&lt;/code&gt; or &lt;code&gt;?.&lt;/code&gt; operators.
To support the compiler, Kotlin functions can define &lt;a href=&quot;https://kotlinlang.org/docs/whatsnew13.html#contracts&quot;&gt;contracts&lt;/a&gt; that describe their behavior.&lt;/p&gt;
&lt;p&gt;As part of this milestone, JUnit’s Kotlin-specific assertion functions have been enhanced to define such contracts.
For example, the &lt;code&gt;assertNotNull&lt;/code&gt; function now defines the following contract:&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;kotlin&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; assertNotNull&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(actual: Any?) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;    contract&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        returns&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;implies&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (actual &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The contract states that if the function returns normally, meaning without throwing an assertion error, that its &lt;code&gt;actual&lt;/code&gt; argument has been checked for nullness and that subsequent code can assume it’s not &lt;code&gt;null&lt;/code&gt;.
The following example demonstrates why this can be useful:&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;kotlin&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;val&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; person: Person? &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; findPerson&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;&quot;Doe&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;assertNotNull&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(person)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;assertEquals&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, person.firstName)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;assertEquals&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;&quot;Doe&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, person.lastName)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In both calls to &lt;code&gt;assertEquals&lt;/code&gt;, &lt;code&gt;person&lt;/code&gt; is dereferenced without using &lt;code&gt;!!.&lt;/code&gt; or &lt;code&gt;?.&lt;/code&gt; since the compiler knows it can no longer be &lt;code&gt;null&lt;/code&gt; due to the prior call of &lt;code&gt;assertNotNull&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;jspecify-nullness-annotations&quot;&gt;JSpecify nullness annotations&lt;/h2&gt;
&lt;p&gt;In addition to contracts for Kotlin code, &lt;a href=&quot;https://docs.junit.org/6.0.0-RC1/release-notes/&quot;&gt;JUnit 6.0.0-RC1&lt;/a&gt; started using &lt;a href=&quot;https://jspecify.dev/&quot;&gt;JSpecify&lt;/a&gt; to indicate nullness throughout its Java APIs.
The Kotlin compiler supports JSpecify’s annotations which makes writing Kotlin code using JUnit’s APIs more safe and idiomatic.&lt;/p&gt;
&lt;p&gt;Of course, there are also benefits when writing code in Java.
JSpecify is supported in IDEs such as IntelliJ IDEA so you may notice new warnings when programming against JUnit’s APIs.
To check nullability during your build, please check out &lt;a href=&quot;https://errorprone.info/&quot;&gt;Error Prone&lt;/a&gt; and &lt;a href=&quot;https://github.com/uber/NullAway&quot;&gt;NullAway&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;kotlin-suspending-functions&quot;&gt;Kotlin suspending functions&lt;/h2&gt;
&lt;p&gt;Kotlin has first-class language support for concurrency and asynchronous programming via &lt;a href=&quot;https://kotlinlang.org/docs/coroutines-overview.html&quot;&gt;coroutines&lt;/a&gt;.
One such language feature is the &lt;code&gt;suspend&lt;/code&gt; keyword that can be applied to function definitions.
Such suspending functions allow writing asynchronous code in regular sequential style but can pause and resume without blocking a thread.&lt;/p&gt;
&lt;p&gt;Prior to &lt;a href=&quot;https://docs.junit.org/6.0.0-RC1/release-notes/&quot;&gt;JUnit 6.0.0-RC1&lt;/a&gt;, writing tests for suspending functions with JUnit Jupiter was not straightforward.
Since suspending functions can only be called from other suspending functions, it felt natural to simply add the &lt;code&gt;suspend&lt;/code&gt; keyword to the &lt;code&gt;@Test&lt;/code&gt; method as well.
However, that didn’t work because &lt;code&gt;@Test&lt;/code&gt; methods with the &lt;code&gt;suspend&lt;/code&gt; modifier were silently ignored by JUnit due to the way the Kotlin compiler generates JVM bytecode for them.
For example, the &lt;code&gt;@Test suspend fun test() { /*...*/ }&lt;/code&gt; function will be compiled to the equivalent of the following Java method:&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; java&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;lang&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Object&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;kotlin&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;coroutines&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Continuation&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; super&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; kotlin&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Unit&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; c&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;	/*...*/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in the &lt;a href=&quot;/blog/2025/08/16/stf-milestone-5-discovery-issues/&quot;&gt;previous post&lt;/a&gt;, &lt;code&gt;@Test&lt;/code&gt; methods must have a &lt;code&gt;void&lt;/code&gt; return type.
Consequently, &lt;a href=&quot;https://docs.junit.org/5.13.0/release-notes/&quot;&gt;JUnit 5.13.0&lt;/a&gt; started reporting discovery issues of severity “warning” in such cases.
However, wouldn’t it be better if it “just worked”?&lt;/p&gt;
&lt;p&gt;Kotlin core libraries provide different ways of executing coroutines, meaning code that calls suspending functions.
One of the simplest is &lt;code&gt;runBlocking&lt;/code&gt; (&lt;a href=&quot;https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html&quot;&gt;docs&lt;/a&gt;) from &lt;code&gt;kotlinx.coroutines&lt;/code&gt;.
It runs the supplied code and blocks the current thread until its completion.
Starting with &lt;a href=&quot;https://docs.junit.org/6.0.0-RC1/release-notes/&quot;&gt;JUnit 6.0.0-RC1&lt;/a&gt;, &lt;code&gt;@Test&lt;/code&gt; functions written in Kotlin may now carry the &lt;code&gt;suspend&lt;/code&gt; modifier.
Behind the scenes, JUnit Jupiter will wrap the function body in a call to &lt;code&gt;runBlocking&lt;/code&gt;.
For example, the following two &lt;code&gt;@Test&lt;/code&gt; methods are equivalent.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;kotlin&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; CoroutineTests&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    @Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    suspend&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test1&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        someSuspendingFunction&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    @Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test2&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(): Unit &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; runBlocking&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        someSuspendingFunction&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    suspend&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; someSuspendingFunction&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(): String {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’d rather use one of the alternatives to &lt;code&gt;runBlocking&lt;/code&gt;, such as &lt;code&gt;runTest&lt;/code&gt; (&lt;a href=&quot;https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/run-test.html&quot;&gt;docs&lt;/a&gt;), you can do so explicitly as follows.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;kotlin&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; CustomCoroutineTests&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    @Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(): Unit &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; runTest&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        someSuspendingFunction&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;kotlin-sequence-support&quot;&gt;Kotlin &lt;code&gt;Sequence&lt;/code&gt; support&lt;/h2&gt;
&lt;p&gt;Kotlin’s &lt;code&gt;Sequence&lt;/code&gt; (&lt;a href=&quot;https://kotlinlang.org/docs/sequences.html&quot;&gt;docs&lt;/a&gt;) abstraction is similar to Java’s &lt;code&gt;Iterable&lt;/code&gt;.
The main difference lies in how it’s used in Kotlin’s standard library.
Methods operating on &lt;code&gt;Iterable&lt;/code&gt; are typically eager whereas those using &lt;code&gt;Sequence&lt;/code&gt; are lazy.
For example, the &lt;code&gt;Iterable&amp;lt;T&amp;gt;.map { ... }&lt;/code&gt; extension function applies the supplied function to all elements of the &lt;code&gt;Iterable&lt;/code&gt; and returns a &lt;code&gt;List&amp;lt;R&amp;gt;&lt;/code&gt;.
The corresponding &lt;code&gt;Sequence&amp;lt;T&amp;gt;.map { ... }&lt;/code&gt; extension function returns another &lt;code&gt;Sequence&amp;lt;R&amp;gt;&lt;/code&gt; and does not apply the supplied function until a terminal operation like &lt;code&gt;toList()&lt;/code&gt; is called.
So, from a Java perspective, it’s more similar to &lt;code&gt;Stream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;JUnit supports conversion of a variety of types to &lt;code&gt;Stream&lt;/code&gt; for use with &lt;a href=&quot;https://docs.junit.org/current/user-guide/#writing-tests-dynamic-tests&quot;&gt;dynamic&lt;/a&gt; or &lt;a href=&quot;https://docs.junit.org/current/user-guide/#writing-tests-parameterized-tests&quot;&gt;parameterized&lt;/a&gt; tests.
Prior to &lt;a href=&quot;https://docs.junit.org/5.13.0/release-notes/&quot;&gt;JUnit 5.13.0&lt;/a&gt;, this included different types of &lt;code&gt;Stream&lt;/code&gt;, &lt;code&gt;Collection&lt;/code&gt;, &lt;code&gt;Iterable&lt;/code&gt;, &lt;code&gt;Iterator&lt;/code&gt;, and all array types.
This list has been extended to support all types defining an &lt;code&gt;Iterator iterator()&lt;/code&gt; method, including Kotlin’s &lt;code&gt;Sequence&lt;/code&gt;.
For example, Kotlin sequences can now be used with &lt;code&gt;@MethodSource&lt;/code&gt; or &lt;code&gt;@FieldSource&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;kotlin&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SequenceTests {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    @JvmStatic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    val&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; sequenceOf&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        arguments&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, Month.JANUARY),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        arguments&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, Month.MARCH),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        arguments&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, Month.AUGUST),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        arguments&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, Month.MAY),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        arguments&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;12&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, Month.DECEMBER)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    @ParameterizedTest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    @FieldSource(&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;: Int, month: Month) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;, month.&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Thanks to these improvements writing JUnit Jupiter tests in Kotlin has just gotten more convenient and idiomatic.
Please give &lt;a href=&quot;https://docs.junit.org/6.0.0-RC1/release-notes/&quot;&gt;JUnit 6.0.0-RC1&lt;/a&gt; a try and let us know what you think and provide feedback on &lt;a href=&quot;https://github.com/junit-team/junit-framework/&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 5: Discovery issues</title><link>https://marcphilipp.de/blog/2025/08/16/stf-milestone-5-discovery-issues/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/08/16/stf-milestone-5-discovery-issues/</guid><pubDate>Sat, 16 Aug 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;This milestone was all about finally resolving issue &lt;a href=&quot;https://github.com/junit-team/junit-framework/issues/242&quot;&gt;#242&lt;/a&gt; by introducing an error handling mechanism for test discovery.
As you can tell by the low issue number (we’re currently at #4840) it has been a long time coming.
Since introducing the discovery phase in an early version of JUnit 5, we had seen the need for being able to report “discovery issues” such as errors and warnings but also info-level messages to users.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Have you ever written a test and noticed at some later point that it wasn’t actually being executed?
I know, it sounds like a real nightmare.
But, can you spot what’s wrong with these test methods?&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // Java&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 42&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;kotlin&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;@Test &lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Kotlin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;fun&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(): Nothing &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; fail&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They look like regular tests, don’t they?
Well, actually, &lt;code&gt;@Test&lt;/code&gt; methods must be declared having a &lt;code&gt;void&lt;/code&gt; return type (&lt;code&gt;Unit&lt;/code&gt; in Kotlin)!
During the test discovery phase, the JUnit Jupiter test engine looks for methods that are annotated with &lt;code&gt;@Test&lt;/code&gt; and have a &lt;code&gt;void&lt;/code&gt; return type.
Before version 5.13, if it found a malformed declaration, such as the ones above, it silently discarded them – even if they were clearly intended to be test methods.&lt;/p&gt;
&lt;p&gt;To be fair, IDEs such as IntelliJ often provide inspections to help avoid running into such issues.
However, such IDE-only warnings are easy to overlook, especially in a large codebase.&lt;/p&gt;
&lt;p&gt;Therefore, rather than keeping you up at night, JUnit 5.13 introduced the concept of &lt;a href=&quot;https://docs.junit.org/current/user-guide/#running-tests-discovery-issues&quot;&gt;“discovery issues”&lt;/a&gt; and a two-part mechanism for reporting them.
First, test engines can &lt;a href=&quot;https://docs.junit.org/current/user-guide/#test-engines-discovery-issues&quot;&gt;report issues&lt;/a&gt; such as malformed declarations during test discovery.
Second, the JUnit Platform takes care of reporting them to users.
It logs all non-critical issues and, if there are any critical issues, test execution will fail for that test engine.
The severity that’s considered “critical” is configurable via the &lt;code&gt;junit.platform.discovery.issue.severity.critical&lt;/code&gt; &lt;a href=&quot;https://docs.junit.org/current/user-guide/#running-tests-config-params&quot;&gt;configuration parameter&lt;/a&gt;.
Currently, the default value is &lt;code&gt;ERROR&lt;/code&gt;, but that may be changed in a future release.&lt;/p&gt;
&lt;p&gt;All test engines provided by JUnit (Jupiter, Vintage, and Suite) already make use of this feature to report a variety of issues.
For example, the Jupiter engine will now report a warning for malformed test and lifecycle method declarations such as the ones shown above.
For the full list, please consult issue &lt;a href=&quot;https://github.com/junit-team/junit-framework/issues/242&quot;&gt;#242&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;p&gt;We’ve introduced this mechanism at a stage when the JUnit Platform and its test engines were already widely used.
Therefore, it was probably inevitable that the initial 5.13.0 release reported a few false-positives.
For example, in 5.13.0 abstract test methods were overeagerly reported as being problematic, but we’ve since learned about use cases for them in the wild.
Those and other checks have since been refined and improved in 5.13.x patch releases.&lt;/p&gt;
&lt;p&gt;On the other hand, we’ve already seen a bunch of projects that had actual problems that needed addressing reported to them after they updated.
For example, one project had lots of inner classes that contained test methods but those inner classes were not annotated with &lt;code&gt;@Nested&lt;/code&gt; so those tests were never executed.
That’s exactly the kind of problem we wanted to address by introducing this mechanism!&lt;/p&gt;
&lt;p&gt;If you haven’t yet updated to JUnit 5.13 or later, please do and look out for any reported discovery issues.
To surface all discovery issues in your project, we recommend setting the &lt;code&gt;junit.platform.discovery.issue.severity.critical&lt;/code&gt; configuration parameter to &lt;code&gt;INFO&lt;/code&gt; and then running all your tests.&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 4: Parameterized test classes</title><link>https://marcphilipp.de/blog/2025/06/07/stf-milestone-4-parameterized-test-classes/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/06/07/stf-milestone-4-parameterized-test-classes/</guid><pubDate>Sat, 07 Jun 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;In version 5.0, JUnit Jupiter introduced support for parameterizing test methods.
In JUnit 4, only test classes could be parameterized.
Therefore, being able to do so on the method level provided more flexibility.
However, there are cases where a set of tests should be executed against the same sets of arguments.
The recent &lt;a href=&quot;https://github.com/junit-team/junit5/releases/tag/r5.13.0&quot;&gt;5.13 release&lt;/a&gt; introduced support for &lt;code&gt;@ParameterizedClass&lt;/code&gt; thereby finally resolving this highly-voted feature request.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;To write a parameterized test &lt;em&gt;method&lt;/em&gt;, the &lt;code&gt;@ParameterizedTest&lt;/code&gt; annotation is used instead of &lt;code&gt;@Test&lt;/code&gt;.
In addition, at least one &lt;code&gt;@...Source&lt;/code&gt; annotation is required to specify the &lt;em&gt;source&lt;/em&gt; of argument sets that the method will be invoked with.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; SomeTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedTest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;strings&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; shouldNotBeNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNotNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedTest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;strings&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; lengthShouldBeThree&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, both test methods are parameterized with an identical &lt;code&gt;@ValueSource&lt;/code&gt; annotation.
Each will be invoked twice, once with &lt;code&gt;&quot;foo&quot;&lt;/code&gt; and once with &lt;code&gt;&quot;bar&quot;&lt;/code&gt; as its &lt;code&gt;String&lt;/code&gt; parameter.&lt;/p&gt;
&lt;p&gt;Since both test methods use the same parameters, parameterizing the test class allows to remove the duplication.
To do so, the test class is annotated with the new &lt;code&gt;@ParameterizedClass&lt;/code&gt; annotation and the &lt;code&gt;@...Source&lt;/code&gt; annotation.
The test methods are changed to use the &lt;code&gt;@Test&lt;/code&gt; annotation.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;strings&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; SomeTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Parameter&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; shouldNotBeNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNotNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; lengthShouldBeThree&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of declaring the parameter on the methods, JUnit injects it into the &lt;code&gt;@Parameter&lt;/code&gt;-annotated field.
Alternatively, JUnit also supports &lt;a href=&quot;https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests-consuming-arguments-classes&quot;&gt;constructor injection&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;strings&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;record&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; SomeTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; shouldNotBeNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertNotNull&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; lengthShouldBeThree&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the example above, a Java &lt;em&gt;record&lt;/em&gt; is used and the class-level parameters are specified as record components.
This allows reducing the boilerplate of declaring a constructor and assigning its parameters to fields.
Regular classes may be used as well, though.&lt;/p&gt;
&lt;h3 id=&quot;a-common-use-case&quot;&gt;A common use case&lt;/h3&gt;
&lt;p&gt;A common use case for parameterizing a test class is to run its tests against different implementations of an interface.
Prior to JUnit 5.13, one would typically achieve that by writing an abstract base test class and creating a subclass for each concrete implementation.
For example, the following test class implements two tests against Java’s &lt;code&gt;List&lt;/code&gt; interface that are executed against three implementations of &lt;code&gt;List&lt;/code&gt; that are part of the JDK.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; abstract&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; AbstractListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;        List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;BeforeEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; initializeList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;            list &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; createList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        protected&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; abstract&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; createList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;            var&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; added&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;added&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getFirst&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Nested&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;DisplayName&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ArrayListTests&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB;font-weight:bold&quot;&gt; AbstractListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        protected&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; createList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&amp;gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Nested&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;DisplayName&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; LinkedListTests&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB;font-weight:bold&quot;&gt; AbstractListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        protected&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; createList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&amp;gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Nested&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;DisplayName&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; VectorTests&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB;font-weight:bold&quot;&gt; AbstractListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        protected&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; createList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&amp;gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This test can be rewritten using &lt;code&gt;@ParameterizedClass&lt;/code&gt; and a &lt;code&gt;@MethodSource&lt;/code&gt; as follows.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;MethodSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;listImplementations&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ParameterizedListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    static&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Stream&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; listImplementations&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Stream&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;                argumentSet&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&amp;gt;()),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;                argumentSet&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&amp;gt;()),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;                argumentSet&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&amp;gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        )&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Parameter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;    List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; added&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;added&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getFirst&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;AfterEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; clearList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // Necessary since the `List` parameter is mutable!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows to get rid of the abstract base class and subclasses resulting in a much simpler structure.&lt;/p&gt;
&lt;h3 id=&quot;converters&quot;&gt;Converters&lt;/h3&gt;
&lt;p&gt;The same use case can also be implemented using &lt;code&gt;@ValueSource&lt;/code&gt; (and constructor injection) instead of &lt;code&gt;@MethodSource&lt;/code&gt; as follows.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;[{index}] {0}&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ParameterizedWithValueSourceListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;    List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;    ParameterizedWithValueSourceListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; listType&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; ReflectionSupport&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;newInstance&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;listType&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // same as above...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // same as above...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;@ValueSource&lt;/code&gt; only supports class literals, not concrete instances, the constructor relies on JUnit’s &lt;code&gt;ReflectionSupport&lt;/code&gt; class to instantiate the &lt;code&gt;List&lt;/code&gt; via the implementations’ default constructors.
Whether it’s ok to use reflection here is, of course, debatable.
Personally, I think it’s acceptable in this case since test code is executed with every build and would fail right away.&lt;/p&gt;
&lt;p&gt;If you find yourself using such a &lt;em&gt;conversion&lt;/em&gt; in multiple places, it might make sense to extract it into a custom &lt;code&gt;ArgumentConverter&lt;/code&gt; and annotate the parameter with &lt;code&gt;@ConvertWith&lt;/code&gt; instead.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;[{index}] {0}&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ParameterizedWithValueSourceAndConverterListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Parameter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ConvertWith&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ClassToInstanceConverter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;    List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // same as above...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // same as above...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;AfterEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; clearList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // Necessary since the `List` parameter is mutable!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The custom &lt;code&gt;ArgumentConverter&lt;/code&gt; implementation is called &lt;code&gt;ClassToInstanceConverter&lt;/code&gt; in this example and contains the code that was part of the constructor in the previous example.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ClassToInstanceConverter&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB;font-weight:bold&quot;&gt; SimpleArgumentConverter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    protected&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Object&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; convert&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Object&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; source&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; targetType&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; ReflectionSupport&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;newInstance&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Class&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; source&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can even make this shorter by utilizing JUnit’s support for composed annotations.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Retention&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;RUNTIME&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;PARAMETER&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; FIELD&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ConvertWith&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ClassToInstanceConverter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt; Instantiate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, that also works with constructor injections, for example, using a Java record.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;[{index}] {0}&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;record&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; ParameterizedWithValueSourceAndConverterRecordListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Instantiate&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; added&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;added&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getFirst&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;AfterEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; clearList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // Necessary since the `List` parameter is mutable!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;mutable-vs-immutable-arguments&quot;&gt;Mutable vs. immutable arguments&lt;/h3&gt;
&lt;p&gt;When using &lt;em&gt;mutable&lt;/em&gt; data as parameters, one has to be mindful of tests that change state.
In the above example, if &lt;code&gt;itemCanBeAdded()&lt;/code&gt; were to run before &lt;code&gt;newListIsEmpty()&lt;/code&gt; without the &lt;code&gt;@AfterEach&lt;/code&gt; lifecycle method, &lt;code&gt;newListIsEmpty()&lt;/code&gt; would fail because the &lt;code&gt;list&lt;/code&gt; would no longer be empty.
Therefore, it’s usually a better idea to use &lt;em&gt;immutable&lt;/em&gt; data as parameters.
In this case, this can be achieved by using a &lt;code&gt;Supplier&lt;/code&gt; to create a list in the test class constructor.
Since each test method uses a separate instance of the test class (unless &lt;code&gt;@TestInstance(PER_CLASS)&lt;/code&gt; is used), this will prevent test methods from influencing each other.
This also removes the need to reset the state of the parameters in an &lt;code&gt;@AfterEach&lt;/code&gt; lifecycle method.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;MethodSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;listImplementations&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ParameterizedListWithSuppliersTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    static&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Stream&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; listImplementations&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Stream&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;                argumentSet&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Supplier&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; ArrayList&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;::new&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;                argumentSet&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Supplier&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;::new&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;                argumentSet&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Supplier&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;::new&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        )&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    final&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;    ParameterizedListWithSuppliersTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;Supplier&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; listSupplier&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; listSupplier&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // same as above...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;        // same as above...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;argument-sources&quot;&gt;Argument sources&lt;/h3&gt;
&lt;p&gt;In addition to &lt;code&gt;@ValueSource&lt;/code&gt; and &lt;code&gt;@MethodSource&lt;/code&gt;, JUnit provides the following annotations for specifying the sources of arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@EnumSource&lt;/code&gt;, &lt;code&gt;@NullSource&lt;/code&gt;, and &lt;code&gt;@EmptySource&lt;/code&gt; for simple values&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@CsvSource&lt;/code&gt;, &lt;code&gt;@CsvFileSource&lt;/code&gt; for CSV content&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@FieldSource&lt;/code&gt; for custom code&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@ArgumentsSource(MyProvider.class)&lt;/code&gt; for custom providers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please refer to JUnit’s &lt;a href=&quot;https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests-sources&quot;&gt;User Guide&lt;/a&gt; for details.&lt;/p&gt;
&lt;h3 id=&quot;lifecycle-methods&quot;&gt;Lifecycle methods&lt;/h3&gt;
&lt;p&gt;Parameterized classes may declare &lt;code&gt;@BeforeParameterizedClassInvocation&lt;/code&gt; and &lt;code&gt;@AfterParameterizedClassInvocation&lt;/code&gt; lifecycle methods which are called once before/after each invocation of the parameterized class with a set of arguments.
This may be used, for example, to initialize an argument as demonstrated in the following example.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;{0}&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;record&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; CustomInitializationListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Instantiate&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; List&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;BeforeParameterizedClassInvocation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    static&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; before&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;list &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;instanceof&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ArrayList&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; arrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            arrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;ensureCapacity&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; added&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;added&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getFirst&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;AfterEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; clearList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;cartesian-products&quot;&gt;Cartesian products&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;@ParameterizedClass&lt;/code&gt; annotation may be combined with &lt;code&gt;@Nested&lt;/code&gt;, also within an enclosing &lt;code&gt;@ParameterizedClass&lt;/code&gt;-annotated test class.
Moreover, a &lt;code&gt;@ParameterizedClass&lt;/code&gt; may contain &lt;code&gt;@ParameterizedTest&lt;/code&gt; methods.
Both can be used to test all combinations or, mathematically speaking, the Cartesian product of two parameter lists.&lt;/p&gt;
&lt;p&gt;The following example demonstrates that by testing all three concrete list implementations from the previous examples against each other in the &lt;code&gt;@Nested&lt;/code&gt; &lt;code&gt;Interoperability&lt;/code&gt; test class.
The &lt;code&gt;@Nested&lt;/code&gt; class additionally contains a &lt;code&gt;@ParameterizedTest&lt;/code&gt; method  to test against different &lt;code&gt;String&lt;/code&gt; values.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;[{index}] {0}&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ParameterizedWithNestedListTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Parameter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Instantiate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;    List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; newListIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; itemCanBeAdded&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; added&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;added&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;        assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getFirst&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;AfterEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; clearList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;        list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Nested&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedClass&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;[{index}] {0}&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ArrayList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; LinkedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Vector&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    class&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Interoperability&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Parameter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Instantiate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;        List&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; secondList&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; twoListsWithSameItemsAreEqual&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            secondList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;addAll&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;secondList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ParameterizedTest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;ValueSource&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;strings&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;baz&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;qux&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; removeAllItemsInPassedList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; extraItem&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            secondList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            secondList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;extraItem&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;removeAll&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;secondList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;            assertEquals&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getFirst&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;AfterEach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;        void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; clearList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;            secondList&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A word of warning: the number of combinations can quickly become very large!
Therefore, you should take that into consideration when deciding whether to use this feature.&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Parameterized test classes are a powerful testing tool that has long been missing from JUnit Jupiter.
I’m super happy that I’ve finally had the chance to resolve this long-standing and highly-voted issue thanks to the &lt;a href=&quot;/blog/2025/01/19/being-a-full-time-open-source-maintainer-supported-by-the-sovereign-tech-fund/&quot;&gt;Sovereign Tech Fund&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Edit: Thanks to my fellow JUnit 5 co-maintainer &lt;a href=&quot;https://github.com/sbrannen&quot;&gt;Sam Brannen&lt;/a&gt; for his feedback which I applied after initially publishing this post.&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 3: Release verification and automation</title><link>https://marcphilipp.de/blog/2025/04/01/stf-milestone-3-release-verification-and-automation/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/04/01/stf-milestone-3-release-verification-and-automation/</guid><pubDate>Tue, 01 Apr 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;A major goal of the Sovereign Tech Fund’s investment is to help projects become more sustainable and decrease their &lt;a href=&quot;https://en.wikipedia.org/wiki/Bus_factor&quot;&gt;truck factor&lt;/a&gt;. For JUnit, one activity in desperate need of improvement in this area was performing a release. Prior to this milestone, all JUnit releases of the past years had been performed from my local computer.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Artifacts were uploaded to Maven Central via Sonatype’s OSSRH infrastructure from my machine. Documentation and sample projects were also updated by a local build running on my machine. In total, the release checklist had 24 steps that I would perform manually for every release. Whenever I told people this, I was afraid they would gasp. However, releases of JUnit were not that frequent and it never felt important enough to spend the little time I had on release automation.&lt;/p&gt;
&lt;p&gt;While that may sound reasonable, doing releases this way was also a bad idea from a security perspective. A malicious actor would only have to compromise my machine (or me) in order to pull of a supply chain attack. A manipulated JUnit jar would soon find its way to a large portion of the Java ecosystem. While usually not part of any production system, JUnit runs during the build and could be used to manipulate production code. Therefore, I jumped at the opportunity to rectify this deficiency and proposed a milestone to the STF for verifying the release and automating the majority of it.&lt;/p&gt;
&lt;p&gt;One additional reason for doing releases locally was that Maven Central requires artifacts to be signed with a PGP key. Doing the release on a CI system therefore would mean trusting that system with my private key. In my book, that’s a bad idea as well. Even if the CI system might only store the private key temporarily, it could have been compromised, have some kind of data leak etc. Thus, I decided to keep that step local. However, since JUnit’s artifacts are completely reproducible, I would keep building and signing them locally, but rebuild them on a CI system. Thereby, the release process would verify the integrity of the binaries and rule out that they had been tampered with.&lt;/p&gt;
&lt;p&gt;Thus, I decided to keep the first part of the release process local:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a release branch&lt;/li&gt;
&lt;li&gt;Change to release version&lt;/li&gt;
&lt;li&gt;Change release date in README and release notes&lt;/li&gt;
&lt;li&gt;Build and deploy release artifacts to Sonatype staging repository&lt;/li&gt;
&lt;li&gt;Create a tag for the release&lt;/li&gt;
&lt;li&gt;Change back to snapshot version&lt;/li&gt;
&lt;li&gt;Push to GitHub&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The remainder of the release is now performed by triggering a &lt;a href=&quot;https://github.com/junit-team/junit5/actions/workflows/release.yml&quot;&gt;GitHub Actions workflow&lt;/a&gt;:&lt;/p&gt;
&lt;img src=&quot;/img/posts/2025-04-01-stf-milestone-3-release-verification-and-automation/github-actions-release-workflow.png&quot; alt=&quot;screenshot of GitHub Actions workflow chart&quot; class=&quot;img-responsive&quot;&gt;
&lt;p&gt;The most important job in the above workflow is “Verify reproducibility”. It checks out the Git tag, rebuilds all binaries, and verifies that they are identical to the ones uploaded to the staging repository. This step verifies not only their reproducibility but also rules out that they have been compromised by my local build.&lt;/p&gt;
&lt;p&gt;The “Verify consumability” job updates all sample projects to consume the artifacts from the staging repository and builds them. Once the first phase is done, the staging repository is released. While waiting for the release artifacts to be synced to Maven Central, the documentation is published. Once the artifacts are indeed available on Maven Central, the sample projects are updated again but without the previous configuration that caused them to consume artifacts from the staging repository. Finally, a GitHub release is created.&lt;/p&gt;
&lt;p&gt;Since I introduced this workflow in January, it has already been run 7 times taking between 15 and 26 minutes. It has definitely made releasing less stressful and I’m really happy how it turned out.&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 2: Open Test Reporting</title><link>https://marcphilipp.de/blog/2025/03/21/stf-milestone-2-open-test-reporting/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/03/21/stf-milestone-2-open-test-reporting/</guid><pubDate>Fri, 21 Mar 2025 00:01:00 GMT</pubDate><content:encoded>&lt;p&gt;When JUnit was first released, it did not provide a feature to write test reports in machine-readable format. Build tools like &lt;a href=&quot;https://ant.apache.org/manual/Tasks/junit.html&quot;&gt;Ant&lt;/a&gt; filled that gap and introduced an XML-based report. It was later adopted and sometimes extended by other Java-based build tools such as &lt;a href=&quot;https://maven.apache.org/surefire/maven-surefire-plugin/index.html&quot;&gt;Maven&lt;/a&gt; and &lt;a href=&quot;https://docs.gradle.org/current/userguide/java_testing.html#test_reporting&quot;&gt;Gradle&lt;/a&gt;. CI tools like &lt;a href=&quot;https://plugins.jenkins.io/junit/&quot;&gt;Jenkins&lt;/a&gt; introduced support for parsing these XML reports in order to display test results for each CI run. That led to other ecosystems also adopting the format to benefit from existing tool support. However, given that the format was initially defined for JUnit 3, it’s focused on test classes and methods and does not support nested structures. Some tools defined their own extensions of the schema that added such support or additional attributes. However, there are various partially conflicting schema definitions and subtle differences what gets written to which XML attributes since a proper “standard” was never agreed upon.&lt;/p&gt;
&lt;h3 id=&quot;open-test-reporting-to-the-rescue&quot;&gt;Open Test Reporting to the rescue&lt;/h3&gt;
&lt;p&gt;To address this situation, the JUnit team originally introduced the &lt;a href=&quot;https://github.com/ota4j-team/open-test-reporting?tab=readme-ov-file#xml-format-specification&quot;&gt;Open Test Reporting format&lt;/a&gt; in 2022 along with JUnit 5.9. It aims to replace the legacy XML format in a way that supports all features of JUnit 5. Moreover, it intends to support general testing concepts rather being tied to test classes and methods in order to appeal to other ecosystems as well. Additionally, it supports &lt;a href=&quot;https://github.com/ota4j-team/open-test-reporting#schema-extensions&quot;&gt;extension schemas&lt;/a&gt; for adding framework-specific information.&lt;/p&gt;
&lt;p&gt;Establishing a new format will, of course, take some time. Testing frameworks need to be adjusted in order to write the new format which they will only do if there is significant interest in their user communities. Similarly, tools like CI servers will only add support for reading test results written in the new format once there is a considerable number of testing frameworks supporting it. Therefore, &lt;a href=&quot;https://github.com/junit-team/junit5/issues/4113&quot;&gt;milestone 2&lt;/a&gt; of my STF-supported work focused on making the new format production-ready and increasing its appeal by providing an API and command-line tool for converting from XML into a user-friendly, standalone HTML report.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3 id=&quot;developing-a-new-html-report&quot;&gt;Developing a new HTML report&lt;/h3&gt;
&lt;p&gt;It’s been a long time since I’ve been involved in setting up a frontend project from scratch. Therefore, I had mixed feelings before starting on the development of the HTML report. However, it actually turned out to be a lot of fun to work on once the initial setup was in place. Compared to Java, the development loop of making a change and seeing it in action was insanely fast. For reference, I decided to use &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; with Typescript and &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind CSS&lt;/a&gt;. In addition, there’s a little Java code that injects the test results into the template that is produced by &lt;a href=&quot;https://vite.dev/&quot;&gt;Vite&lt;/a&gt; during the build process.&lt;/p&gt;
&lt;p&gt;I introduced a &lt;a href=&quot;https://github.com/ota4j-team/open-test-reporting#html-report&quot;&gt;CLI command&lt;/a&gt; that takes a single or multiple XML files as input and produces a self-contained HTML file. The test tree is rendered on the left with a details view on the right. The color and icon of the top bar changes depending on the overall status: it’s red if there was at least one failure and green otherwise.&lt;/p&gt;
&lt;img src=&quot;/img/posts/2025-03-21-stf-milestone-2-open-test-reporting/html-report-successful.png&quot; alt=&quot;screenshot of successful test report&quot; class=&quot;img-responsive img-thumbnail&quot;&gt;
&lt;p&gt;The screenshot also shows one other major new features that was added in this milestone: file attachments. In case of images they are rendered inline. This is useful for integration and UI tests. The screenshot shows a browser test that is part of Open Test Reporting’s own test suite and verifies the HTML report gets rendered correctly. The &lt;a href=&quot;https://junit.org/junit5/docs/5.12.1/api/org.junit.jupiter.api/org/junit/jupiter/api/TestReporter.html#publishFile(java.lang.String,org.junit.jupiter.api.extension.MediaType,org.junit.jupiter.api.function.ThrowingConsumer)&quot;&gt;&lt;code&gt;TestReporter&lt;/code&gt; API&lt;/a&gt; in JUnit (along with a &lt;a href=&quot;https://junit.org/junit5/docs/5.12.1/api/org.junit.jupiter.api/org/junit/jupiter/api/extension/ExtensionContext.html#publishFile(java.lang.String,org.junit.jupiter.api.extension.MediaType,org.junit.jupiter.api.function.ThrowingConsumer)&quot;&gt;similar method&lt;/a&gt; in &lt;code&gt;ExtensionContext&lt;/code&gt; for extensions) allows attaching files during test execution.&lt;/p&gt;
&lt;p&gt;Of course, there’s also a dark theme:&lt;/p&gt;
&lt;img src=&quot;/img/posts/2025-03-21-stf-milestone-2-open-test-reporting/html-report-failed.png&quot; alt=&quot;screenshot of failed test report&quot; class=&quot;img-responsive img-thumbnail&quot;&gt;
&lt;p&gt;The format is &lt;a href=&quot;https://github.com/ota4j-team/open-test-reporting#extending-the-html-report&quot;&gt;extensible via an SPI&lt;/a&gt;. For example, the “JUnit metadata” section from the screenshot above is contributed by a JUnit-specific extension. This allows other testing frameworks to render HTML sections if they write additional information to the XML reports.&lt;/p&gt;
&lt;h3 id=&quot;seeing-it-in-action&quot;&gt;Seeing it in action&lt;/h3&gt;
&lt;p&gt;If you want to see it in action, please have a look at &lt;a href=&quot;https://github.com/junit-team/junit5/actions/workflows/main.yml?query=branch%3Amain+is%3Asuccess&quot;&gt;JUnit’s CI builds&lt;/a&gt; which archive the reports. You can find them at the end of the summary page of every GitHub Actions workflow run. Unfortunately, GitHub does not (yet?) support browsing HTML files directly, so you’ll have to download the zip file and extract it locally. It contains one HTML report per subproject.&lt;/p&gt;
&lt;img src=&quot;/img/posts/2025-03-21-stf-milestone-2-open-test-reporting/github-artifacts.png&quot; alt=&quot;screenshot of GitHub Actions workflow run artifacts&quot; class=&quot;img-responsive&quot;&gt;
&lt;p&gt;Even better, you can (and should!) try it out in your own project. JUnit‘s User Guide documents how to enable writing the XML report. You can then use the &lt;a href=&quot;https://github.com/ota4j-team/open-test-reporting#html-report&quot;&gt;Open Test Reporting CLI&lt;/a&gt; to convert it to HTML.&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;java -jar open-test-reporting-cli-0.2.2.jar html-report \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;	--output open-test-report.html \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;	open-test-reporting.xml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;where-to-go-from-here&quot;&gt;Where to go from here&lt;/h3&gt;
&lt;p&gt;Once I was more or less done with the implementation part of this milestone, I reached out to testing framework maintainers in other ecosystems. Some were hesitant or lacked the time to investigate but others were quite enthusiastic. For example, &lt;a href=&quot;https://github.com/sebastianbergmann/phpunit/issues/6077#issuecomment-2613863770&quot;&gt;PHPUnit&lt;/a&gt; right away implemented a proof-of-concept and drafted a concrete plan for adopting the Open Test Reporting format. Moreover, they plan to deprecate the “legacy” XML format in their next major version!&lt;/p&gt;
&lt;p&gt;All in all, I am really happy with the outcome of this milestone! If you have any questions about any of the above, please raise an issue in the &lt;a href=&quot;https://github.com/ota4j-team/open-test-reporting&quot;&gt;Open Test Reporting&lt;/a&gt; repository (if it’s about the format, CLI, etc.) or the &lt;a href=&quot;https://github.com/junit-team/junit5/&quot;&gt;JUnit 5&lt;/a&gt; repo (if it’s JUnit-specific).&lt;/p&gt;
&lt;p&gt;Happy testing!&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 9: Jupiter extension improvements</title><link>https://marcphilipp.de/blog/2025/01/27/stf-milestone-9-jupiter-extension-improvements/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/01/27/stf-milestone-9-jupiter-extension-improvements/</guid><pubDate>Mon, 27 Jan 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;As you can tell from the high number, this milestone was originally planned to be done later. However, a contributor (&lt;a href=&quot;https://github.com/JojOatXGME&quot;&gt;@JojOatXGME&lt;/a&gt;) was eager to work on it so I reached out to the STF and asked to change the order. They agreed and we changed the plan accordingly.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/junit-team/junit5/issues/4057&quot;&gt;issue addressed by this milestone&lt;/a&gt; was a crucial piece of missing functionality in the Jupiter extension API that kept popping up and was re-discussed every few weeks/months: there was no way to access the method-level extension context for &lt;code&gt;TestInstancePostProcessor&lt;/code&gt; (and other) extensions which is important to create and destroy resources on the test class instance level. The hope was that resolving this issue would reduce friction for users and free up time for maintainers to work on other duties.&lt;/p&gt;
&lt;p&gt;After the &lt;a href=&quot;https://github.com/junit-team/junit5/pull/4032&quot;&gt;initial PR&lt;/a&gt; from Johannes that introduced a new annotation to opt-in to the new behavior, I iterated quite a bit on it based on feedback from the rest of the JUnit team. We decided to introduce a new interface with a method instead because it allows custom logic to determine which scope should be used (for example, checking for a configuration parameter):&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; interface&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; TestInstantiationAwareExtension&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB;font-weight:bold&quot;&gt; Extension&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    default&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; ExtensionContextScope&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; getTestInstantiationExtensionContextScope&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;ExtensionContext&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; ctx&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;       return&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; ExtensionContextScope&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;DEFAULT&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    enum&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; ExtensionContextScope &lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;       DEFAULT&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; TEST_METHOD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I then added a configuration parameter to change the default behavior so it could easily be tested by consuming projects without editing any code. Moreover, I updated the &lt;a href=&quot;https://junit.org/junit5/docs/snapshot/user-guide/#extensions-test-instance-post-processing&quot;&gt;User Guide&lt;/a&gt; and modified all core extensions to opt-in right away. This change introduced constructor injection support for &lt;code&gt;@TempDir&lt;/code&gt; and now allows writing a test class that requires a temporary directory like this (using a &lt;code&gt;record&lt;/code&gt; for brevity):&lt;/p&gt;
&lt;pre class=&quot;astro-code nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;record&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; TempDirTests&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(@&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;TempDir&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; Path&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; tempDir&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; shouldExists&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;       assertTrue&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Files&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;exists&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;tempDir&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#D08770&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; shouldAllowCreatingFiles&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; throws&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; IOException&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;       Files&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;createFile&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;tempDir&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;test.txt&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Summing up, I was grateful that the STF allowed us the flexibility to change the original plan. Even more importantly, I was really happy that this long-standing issue was finally resolved!&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item><item><title>STF Milestone 1: Adopt Renovate</title><link>https://marcphilipp.de/blog/2025/01/19/stf-milestone-1-adopt-renovate/</link><guid isPermaLink="true">https://marcphilipp.de/blog/2025/01/19/stf-milestone-1-adopt-renovate/</guid><pubDate>Sun, 19 Jan 2025 00:01:00 GMT</pubDate><content:encoded>&lt;div class=&quot;lead&quot;&gt;
&lt;p&gt;When drafting the project description for the STF, it was important to choose something as a first milestone that I could get done in under a month and that would have a direct benefit to the project right away and improve its maintainability. That’s why I eventually decided on migrating to Renovate for automating updates to dependencies and build tools.&lt;!--more--&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We had already come a long way as a team when it comes to managing dependency updates. When we started to work on JUnit 5 in 2015, dependencies were few and we updated them manually. Over time, we adopted more tools, in particular in the build. We used the &lt;a href=&quot;https://github.com/ben-manes/gradle-versions-plugin&quot;&gt;Gradle Versions Plugin&lt;/a&gt; for a while but it had its limitations. Eventually, we adopted &lt;a href=&quot;https://docs.github.com/en/code-security/dependabot&quot;&gt;Dependabot&lt;/a&gt; and switched to Gradle’s &lt;a href=&quot;https://docs.gradle.org/current/userguide/version_catalogs.html&quot;&gt;version catalogs&lt;/a&gt; which made updating our main dependencies much easier.&lt;/p&gt;
&lt;p&gt;However, the amount of builds we needed to manage increased over time. Standalone projects such as the &lt;a href=&quot;https://github.com/junit-team/testng-engine&quot;&gt;TestNG engine&lt;/a&gt; were introduced and &lt;a href=&quot;https://github.com/junit-team/junit5-samples&quot;&gt;samples&lt;/a&gt; for more build tools were added. Dependabot only supported a subset of those. It also did not support keeping the build tools themselves up to date. So we had a &lt;a href=&quot;https://github.com/junit-team/wrapper-upgrade&quot;&gt;separate repository&lt;/a&gt; that used the &lt;a href=&quot;https://github.com/gradle/wrapper-upgrade-gradle-plugin/&quot;&gt;Wrapper Upgrade Gradle Plugin&lt;/a&gt; for updating our Gradle and Maven (for samples) builds.&lt;/p&gt;
&lt;p&gt;Adopting &lt;a href=&quot;https://mend.io/renovate&quot;&gt;Renovate&lt;/a&gt; promised to enable us to remove this incomplete patchwork of tools with a single solution. So far, it has lived up to this promise. It not only supports Gradle and Maven, but also Bazel, sbt, and npm. We now also use it for pinning our dependencies in GitHub Action workflows. It allowed us to remove the separate repo for updating wrappers and gives us peace of mind that everything is shipshape regarding our dependencies.&lt;/p&gt;
&lt;p&gt;The flip side of the coin are many PRs that can be quite noisy at times. While Renovate can be configured to work without PRs, we decided against that after discussing the topic in the JUnit team. We also decided to enable its auto-merge feature but require its PRs to be approved prior to merging to reduce the risk of supply chain attacks. Overall, I think we’re happy with the switch and would do it again.&lt;/p&gt;
</content:encoded><category>Sovereign Tech Fund</category><category>JUnit</category></item></channel></rss>