How to create a gradle test suite without using built-in frameworks

Lets say I created a new and unique Java test framework, or I am retro-fitting a legacy project where the tests are just main(String[] args)-entrypoint classes and I would like to run those with gradle test and have gradle exit with 0 if none of the tests fail/nothing throws.

“without built-in frameworks” - meaning, without useJUnit(), useJUnitPlatform() et al.

Any guidance for this use case? I also posted on stack overflow.

Create a task that iterates over the classes and calls their main methods, then make test depend on that task.
If it really needs to be the test task that should do it, register a doLast action on the test task that does the same logic.

Or you could also implement a custom JUnit platform engine that discovers your tests and executes them.
This way you can even get an test report out of it and any integration like IDE, CI server, and others that are compatible to JUnit 5 platform can actually see your tests as tests.
Shouldn’t be too complex for such a specific case where you can make some assumptions.

The idea of a custom JUnit engine seems the most appropriate, I had not even thought of implementing the solution in that layer. I must say I’m still very curious what the “Test” type task does in gradle and how i can take advantage of it, but this will probably be a valid solution for my use case.

When you have your custom JUnit engine, you still use the Test type task.
Your custom JUnit engine still runs on JUnit platform and thus you get the integration like runability from IDE, integration in CI servers, HTML report generated by Gradle and so on.
So you would still call useJUnitPlatform() for the task and then your custom engine will find tests and all is well.

yeah I’m well aware of that, but seeing as its also used for JUnit 4 and TestNG, which are probably totally unlike JUnit 5, there probably has to be some kind of undocumented internal API (or spi) that neatly abstracts some of these details in a useful way.

Probably, but why should you care?
Especially if you do it with a custom JUnit platform