Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JUnit 5 extension #262

Open
Guite opened this issue Mar 5, 2019 · 8 comments
Open

JUnit 5 extension #262

Guite opened this issue Mar 5, 2019 · 8 comments

Comments

@Guite
Copy link

Guite commented Mar 5, 2019

The XpectRunner class needs to be replaced by an extension used with @ExtendWith in JUnit 5. Is there suggestion how to use a "migration mode" until a new Xpect release is available?

@cdietrich
Copy link
Member

i would rather prefer a "complemented" instead of a "replaced"

@Guite
Copy link
Author

Guite commented Mar 5, 2019

Sure 😄
The replacement is done from usage-perspective. Of course Xpect should not drop JUnit 4 support.

@Juancete
Copy link

Juancete commented Dec 9, 2019

@Guite
Is there a workaround to run Xpect with JUNit 5 and the @ExtendWith annotation?

@Guite
Copy link
Author

Guite commented Dec 9, 2019

I don't think so.

@trancexpress
Copy link
Contributor

Hi @tjeske ,

it would be great for Xpect moving forward, if XpectRunner has a JUnit 5 equivalent. Do you have bandwidth to provide one?

Best regards,
Simeon

@tjeske
Copy link
Contributor

tjeske commented May 21, 2024

@trancexpress: 👍 I can have a look end of this week.

@trancexpress
Copy link
Contributor

trancexpress commented May 22, 2024

I've been looking into replacing XpectRunner in our own code (in case it takes a while to provide a JUnit 5 equivalent in Xpect), that seems to not be simple due to it being a singleton: org.eclipse.xpect.runner.XpectRunner.INSTANCE

I assume the JUnit 5 addition will be using TestFactory from JUnit 5, since that seems to be the way to generate tests on-the-fly with JUnit 5 (XpectRunner itself also defines tests on-the-fly). Unfortunately, TestFactory targets methods - its unclear to me how the JUnit 5 construct for Xpect tests should look like.

We have e.g. a test case that is similar to XtextTests (annotated with @RunWith(XpectRunner.class), but the test case also extends our base class for all tests.

Providing a base class that has factory methods therefore doesn't work for us. The way it looks to me, Xpect is forced to provide a static method to delegate to? E.g. something like this will need to be added to test cases that previously had XpectRunner or extend from a class annotated with XpectRunner:

    @TestFactory
    Stream<DynamicTest> dynamicTests() {
        return XpectDynamicTestFactory.dynamicTests(this.getClass());
    }

This seems rather clunky, but I don't see any other option?

Before adding any actual new API, it might be good to discuss this...

My attempts are found here:

https://github.com/trancexpress/Xpect/tree/XpectRunner_JUnit5

See: #343

I'm able to run some tests with this. Will have to check with more tests though; that requires also porting our JUnit 4 constructs (that we have on top of XpectRunner) to JUnit 5...

trancexpress added a commit to trancexpress/Xpect that referenced this issue May 24, 2024
This change provides a JUnit 5 alternative of the JUnit 4 XpectRunner.

To summarize the JUnit 4 specific code for Xpect tests, it looks like this:

* XpectRunner takes the @XpectTestFiles test DSLs and generates a test case for each DSL test file, i.e. it generates test cases.
* XpectFileRunner takes a DSL test file and generates test methods for a test case, these are coming from the XPECT statements (XpectInvocation or XjcTestMethod, I'm not sure which is what in the Xpect tests.
* XpectTestRunner generates a test method for a XpectInvocation.
* TestRunner generates a test method for a XjmTestMethod.

The code JUnit 4 is "transformed" as follows:

XpectRunner     -> XpectDynamicTestFactory
XpectFileRunner -> XpectDynamicTestCase
XpectTestRunner -> XpectInvocationDynamicTest
TestRunner      -> XpectDynamicTest

There is lots of supporting code that is not JUnit 4 specific, it remains functional and unchanged.

The API proposal is to add a marker interface org.eclipse.xpect.dynamic.IXpectDynamicTestFactory, that is implemented by a test case in order to enable Xpect tests (based on JUnit 5) for that test case.

There is also org.eclipse.xpect.dynamic.XpectDynamicTestCase, which has setUp() and tearDown() callbacks, called before reps. after each test method. We require these, since the JUnit 5 construct for generating tests, dynamic tests, doesn't have before/after callbacks (junit-team/junit5#1292 (comment), see also warning here: https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests). XpectRunner itself generates tests based on annotation values via JUnit 4 runners. XpectDynamicTestCase can be used by extending it and specifying the annotation @XpectReplace(XpectDynamicTestCase.class) at the extending class. Then importing the extended class at the client test case via e.g.:

...
@XpectImport({MyXpectDynamicTestCase.class ...})
public class MyXpectTestCase implements IXpectDynamicTestFactory {
...

Fixes: eclipse#262
@trancexpress
Copy link
Contributor

#343 is ready for reviewing.

Ideally we get some feedback on how the new API looks like, though I'm not sure how much of the feedback I'll be able to accommodate. I'm taking care of the JUnit 5 test migration for the product I work on, I'm sure there can be plenty of other uses of XpectRunner that will be difficult to support with JUnit 5.

And of course, likely/arguably we should move Xpect tests themselves to JUnit 5... Or decide how the JUnit 5 functionality is to be tested, in parallel to the JUnit 4 functionality.

trancexpress added a commit to trancexpress/Xpect that referenced this issue May 26, 2024
This change extracts parts of the singleton XpectRunner
to another class, so that other implementations can set the values of the singleton.

This change is required, in order to provide alternatives of XpectRunner,
such as a JUnit 5 alternative, without depending on XpectRunner.

Preparation for: eclipse#262
trancexpress added a commit to trancexpress/Xpect that referenced this issue May 26, 2024
This change provides a JUnit 5 alternative of the JUnit 4 XpectRunner.

To summarize the JUnit 4 specific code for Xpect tests, it looks like this:

* XpectRunner takes the @XpectTestFiles test DSLs and generates a test case for each DSL test file, i.e. it generates test cases.
* XpectFileRunner takes a DSL test file and generates test methods for a test case, these are coming from the XPECT statements (XpectInvocation or XjcTestMethod, I'm not sure which is what in the Xpect tests.
* XpectTestRunner generates a test method for a XpectInvocation.
* TestRunner generates a test method for a XjmTestMethod.

The code JUnit 4 is "transformed" as follows:

XpectRunner     -> XpectDynamicTestFactory
XpectFileRunner -> XpectDynamicTestCase
XpectTestRunner -> XpectInvocationDynamicTest
TestRunner      -> XpectDynamicTest

There is lots of supporting code that is not JUnit 4 specific, it remains functional and unchanged.

The API proposal is to add a marker interface org.eclipse.xpect.dynamic.IXpectDynamicTestFactory, that is implemented by a test case in order to enable Xpect tests (based on JUnit 5) for that test case.

There is also org.eclipse.xpect.dynamic.XpectDynamicTestCase, which has setUp() and tearDown() callbacks, called before reps. after each test method. We require these, since the JUnit 5 construct for generating tests, dynamic tests, doesn't have before/after callbacks (junit-team/junit5#1292 (comment), see also warning here: https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests). XpectRunner itself generates tests based on annotation values via JUnit 4 runners. XpectDynamicTestCase can be used by extending it and specifying the annotation @XpectReplace(XpectDynamicTestCase.class) at the extending class. Then importing the extended class at the client test case via e.g.:

...
@XpectImport({MyXpectDynamicTestCase.class ...})
public class MyXpectTestCase implements IXpectDynamicTestFactory {
...

Fixes: eclipse#262
trancexpress added a commit to trancexpress/Xpect that referenced this issue May 26, 2024
This change provides a JUnit 5 alternative of the JUnit 4 XpectRunner.

To summarize the JUnit 4 specific code for Xpect tests, it looks like this:

* XpectRunner takes the @XpectTestFiles test DSLs and generates a test case for each DSL test file, i.e. it generates test cases.
* XpectFileRunner takes a DSL test file and generates test methods for a test case, these are coming from the XPECT statements (XpectInvocation or XjcTestMethod, I'm not sure which is what in the Xpect tests.
* XpectTestRunner generates a test method for a XpectInvocation.
* TestRunner generates a test method for a XjmTestMethod.

The code JUnit 4 is "transformed" as follows:

XpectRunner     -> XpectDynamicTestFactory
XpectFileRunner -> XpectDynamicTestCase
XpectTestRunner -> XpectInvocationDynamicTest
TestRunner      -> XpectDynamicTest

There is lots of supporting code that is not JUnit 4 specific, it remains functional and unchanged.

The API proposal is to add a marker interface org.eclipse.xpect.dynamic.IXpectDynamicTestFactory, that is implemented by a test case in order to enable Xpect tests (based on JUnit 5) for that test case.

There is also org.eclipse.xpect.dynamic.XpectDynamicTestCase, which has setUp() and tearDown() callbacks, called before reps. after each test method. We require these, since the JUnit 5 construct for generating tests, dynamic tests, doesn't have before/after callbacks (junit-team/junit5#1292 (comment), see also warning here: https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests). XpectRunner itself generates tests based on annotation values via JUnit 4 runners. XpectDynamicTestCase can be used by extending it and specifying the annotation @XpectReplace(XpectDynamicTestCase.class) at the extending class. Then importing the extended class at the client test case via e.g.:

...
@XpectImport({MyXpectDynamicTestCase.class ...})
public class MyXpectTestCase implements IXpectDynamicTestFactory {
...

Fixes: eclipse#262
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants