Use of abstract classes does work in JUnit 5. I've written a lot of JUnit 5
tests that use abstract test classes which define the
@ParameterizedTest/@Test fixtures and then concrete child classes that are
run by the framework. It is supported but IIRC it is not recommended in the
JUnit 5 documentation. It has been a while since I looked to see
what alternatives are provided.

IMO the use of an abstract base class that has all the tests is still a
useful pattern. It is used in Commons Collections for the Bloom filter
package to test that implementations of the BloomFilter interfaces all
provide the required functionality. A more convoluted abstract test class
structure is used in Commons Statistics in the distribution and descriptive
packages. These abstract classes define methods to test interface
implementations. The child classes then provide instances of the interface
to test with standard data, and can provide custom data to test them with.
I do not think it is as configurable to have a single class with
@ParameterizedTest methods to test lots of different implementations. It
requires a very large method to stream all the different instances to test
and their data. This pattern is used in Commons RNG to test instances of a
random generator interface, or distribution samplers.

A quick browse of the API finds @TestTemplate which requires registering
providers and a lot more setup. Note that @ParameterizedTest is a built-in
specialization of @TestTemplate. So this is a JUnit5 way to create more
configurable tests which provide combinations of parameters for the test.

I found that using an abstract class I was able to create a test framework
that tested what was required and allowed testing of each implementation
individually. So I could do what I wanted. However I cannot state if it
would be better with @TestTemplate or some other JUnit 5 way to achieve the
same result. I remember trying a few other options but cannot remember why
I gave up and resorted to the abstract class pattern.

Note that it would be better to have VFS on JUnit 5 using abstract classes
than on JUnit 3 or 4. I would try and upgrade one test and see if it works.

Alex


On Thu, 29 Feb 2024 at 20:43, Gary Gregory <garydgreg...@gmail.com> wrote:

> Thank you for digging into this Eric.
>
> Another component to consider for JUnit 5 migration is Commons VFS. This
> one is challenging due to some similar JUnit 3 and 4 heritage issues.
>
> It is possible that between Net and VFS, what we need are custom JUnit
> extensions. I had started a Commons Testing repository a long time ago but
> never got far with adding what at the time were JUnit 4 rules.
>
> I too find some of the JUnit 5 changes baffling but that's what we got...
> unless we want to switch to TextNG or some other test framework which would
> be a big change.
>
> Gary
>
>
> On Thu, Feb 29, 2024, 3:13 PM Elric V <elri...@melnib.one> wrote:
>
> > Hi folks,
> >
> > I recently made some changes to commons-cli to move it from JUnit 4 to
> > JUnit 5. This was mostly straightforward, and I think it went pretty
> well.
> >
> > Currently looking into doing the same for commons-net, but there are a
> > couple of tricky tests that probably require some up front discussion,
> > mostly JUnit 3 style tests, and one tricky JUnit 4 Parameterized Test.
> >
> > In previous versions, test classes could be extended and their test
> > methods would be executed as part of the child class' execution. This
> > was true for testt methods annotated with JUnit 4's @Test, or JUnit 3's
> > test-prefix naming convention.
> >
> > Unfortunately, this is no longer the case in JUnit 5. I think this is a
> > poor design decision on their part, as it makes it significantly harder
> > to move to JUnit 5, and it makes certain types of tests just plain
> > difficult. There is some discussion about this in the JUnit community
> > [1], but I can't predict whether this will ever be resolved in a way to
> > makes commons-net's upgrade any easier.
> >
> > One of those cases is AbstractFTPParseTest and its children. This
> > abstract base class has 11 concrete test classes. I'm struggling to see
> > a minimally invasive way to migrate these to JUnit 5. I'm loath to use a
> > heavy handed approach there.
> >
> > A second tricky case is FTPSClientTest, which is a Parameterized test of
> > a form that no longer exists in JUnit 5. It basically creates two
> > instances of a test class with a boolean flag (once true, once false).
> >
> > JUnit 5's @ParameterizedTest annotation operates on the **test method**
> > level, not on the class level, which I think would make the test case
> > slower and harded to read.
> >
> > An alternative approach would be to use Dynamic Tests, which basically
> > generate test cases programmatically, but again, that makes grokking the
> > test a lot more difficult as it requires a greater understanding of
> > JUnit's features.
> >
> > Any insights into this would be greatly appreciated.
> >
> > Best,
> >
> > Elric
> >
> > [1] https://github.com/junit-team/junit5/issues/960
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> > For additional commands, e-mail: dev-h...@commons.apache.org
> >
> >
>

Reply via email to