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

Add an option to ExecutionMode to run concurrently but wait for all test runs in the class to complete #3947

Closed
k163377 opened this issue Sep 7, 2024 · 3 comments

Comments

@k163377
Copy link

k163377 commented Sep 7, 2024

It seems that ExecutionMode.CONCURRENT does not wait for everything in the class to complete before executing tests in other classes.
I was trying to parallelize a test for a query to retrieve from a database, but this behavior corrupted the test data and did not produce the expected results.
Is it possible to add a mode where execution within a class is parallelized, but execution of all tests within the class waits for completion?


As far as I have tried, it seems to be possible to achieve this behavior by giving @Execution(ExecutionMode.CONCURRENT) to the inner class and preparing an empty AfterAll in the outer class.
The following is the structure when reproduced (it was actually Kotlin).

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Foo {
  @Nested
  @Execution(ExecutionMode.CONCURRENT)
  class Bar {
    
  }
  
  @AfterAll
  public static void afterAll() {}
}

However, when this was done, it seemed that execution via gradle would result in a normal exit even though there were tests that had not yet been processed.
I am sorry that I have not been able to reproduce the problem at a minimum, but I am reporting this once in consideration of the possibility of a bug.
I have reproduced it at least with 5.10.2 and 5.10.3.

@marcphilipp
Copy link
Member

Is it possible to add a mode where execution within a class is parallelized, but execution of all tests within the class waits for completion?

If you want to run all classes sequentially, but tests within a class concurrently, you can use the following configuration parameter settings:

junit.jupiter.execution.parallel.mode.default = CONCURRENT
junit.jupiter.execution.parallel.mode.classes.default = SAME_THREAD # default

However, when this was done, it seemed that execution via gradle would result in a normal exit even though there were tests that had not yet been processed.

Are you using an include/exclude pattern in your Gradle config that caused the outer class to be excluded?

@marcphilipp marcphilipp closed this as not planned Won't fix, can't repro, duplicate, stale Sep 18, 2024
@k163377
Copy link
Author

k163377 commented Sep 19, 2024

@marcphilipp

If you want to run all classes sequentially, but tests within a class concurrently, you can use the following configuration parameter settings:

Unfortunately this did not help.

In my use case, not all classes can be executed concurrently in the same way.
This means that it is difficult to use an option that would apply equally to all classes.

On the other hand, there does not appear to be a way to apply the same behavior as the option you gave me to only one class.
As far as I have tried the inner class, it does not appear to wait on the entire outer class, even when it is granted to the inner class.

As I tried later, the method of applying it to each test method seemed to work, but I would like to avoid this as it would be too much work.
(As a side note, this also has not been applied due to a bug that I reported separately that causes it to exit midstream.)

Are you using an include/exclude pattern in your Gradle config that caused the outer class to be excluded?

No.
The only difference from normal execution is that junit.jupiter.execution.parallel.enabled is true and @Execution(ExecutionMode.CONCURRENT) is given to a specific internal class or method.

@marcphilipp
Copy link
Member

@k163377 I'm afraid it's close to impossible to discuss this without a concrete example. If you could post a reproducer that illustrates the problem, I'd be happy to take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants