-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Provide mechanism to order the sequence of tests #13
Comments
Hi @elygre, Test execution order is something we are certainly considering for the core feature set of JUnit 5. In fact, introducing an annotation such as We'll chime in here once we begin work on ordering. Cheers, Sam |
@elygre ine thing we considered was something like junit-team/junit4#1130 |
In addition to test method, I believe ordering should be applicable to Also, it would be nice if behavior are clearly defined(or documented) when multiple Thanks, |
I like the changes and the new API proposal, although (sigh) I'm not entirely convinced resignation from Take method ordering. The way I implemented it for randomized testing is by adding an annotation that provides a class which receives a list of tests to be executed: Would this kind of flexibility be possible with JUnit5? |
Well, you can always build and register your own test engine. If it 2015-11-23 22:39 GMT+01:00 Dawid Weiss [email protected]:
|
That's my point. What I liked about JUnit4 was the fact that contracts (ok, not clearly formalized, but still there) were somewhat separate from the "execution". I hoped for JUnit5 to follow this paradigm. Specify annotations, interfaces and the execution model, leaving actual implementation out (but providing a default reference). I am not saying the route taken is wrong. I just express my expectations and desires. :) |
I still don't see how extending an existing test engine is qualitatively JUnit5TestEngine is not designed with "subclassability" in mind but that 2015-11-23 23:17 GMT+01:00 Dawid Weiss [email protected]:
|
Let me explain the underlying need a bit. I am a committer to Lucene and Solr. We use a lot of pseudorandomness in tests. Interchangeable components can get swapped, parameters can get picked at random, strings get picked from a random space, etc. Simplifying a lot, every test is still reproducible because the source of randomness is controlled by the framework. There are also tons of other infrastructure elements: parameter factory methods (parameterized tests), more realistic test and suite timeouts that detect and warn about stray threads left behind, different seed test reiterations, test listeners (they can attach to the runner, so they receive suite started/ finished events), custom test method providers... Lots of it. If you're interested in more details and the philosophy behind it there are some lectures I presented in the past about the topic [1, 2]. The reasons we chose JUnit as the underlying framework were basically twofold:
But the two above don't really mean the test runner is the same as in regular JUnit. It is similar, but has multiple differences that go well beyond the default implementation. Most of these are so low-level that they couldn't be implemented by extending base JUnit4 runner because it encapsulates or hides certain test preprocessing points (I've tried). Or it combines functionality scattered across different runners (for example parameterized tests). Finally, having our own runner makes the implementation less tightly bound to JUnit's version -- the details of the base runner's implementation may change, but all we use from JUnit is basically annotations and the (unfortunate) Description object. Perhaps an example would highlight it better. Take this class as a simple example: @RunWith(RandomizedRunner.class)
public class TestFoo {
final int a;
public TestFoo(int a) {
this.a = a;
}
@Test
@Repeat(iterations = 3, useConstantSeed = false)
public void checkMe() {
Assert.assertTrue(Math.abs(a + randomIntBetween(0, 3)) >= 0);
}
@ParametersFactory(argumentFormatting = "a = 0x%08x")
public static Iterable<Object[]> parameters() {
return Arrays.asList(
$(1),
$(0x7fffffff - 2));
}
} The output of running this is Eclipse is 6 tests, with a pseudo-nested suite above. Note the tests need to have unique Descriptions (otherwise Eclipse gets terribly confused) and this description is generated at the runner's level (the runner also expands the hierarchy so that test repetitions for different seeds and arguments are unique and placed under the method's node). Finally and again -- I'm not saying anything in JUnit is badly implemented. We just need very specific stuff that goes beyond the defaults (and would occasionally require stuff that is hidden from subclasses for the right reasons). So if there is a way to extract a "meta test API" level and abstract it from the actual runner implementation it would be beneficial. [1] https://berlinbuzzwords.de/sites/berlinbuzzwords.de/files/media/documents/dawidweiss-randomizedtesting-pub.pdf |
Closed in favor of #48. |
There is a specific need to have a pseudo-random test order, since that allows finding unintended test interactions, and allows repeating the test in that order using the logged seed. #48 does not cover that use case. |
@devrandom Please open a new issue for the pseudo-random order use case. |
@marcphilipp - I see actually that junit4 has a deterministic test order (based on |
You couldn't find it... because it's simply not defined. The ordering of execution of tests within a test class in JUnit Jupiter is based solely on the order in which the methods are returned from the JVM via reflection, which since Java 7 is undefined. In other words, there is no guaranteed order. |
Introduced Deliverables section. |
This commit introduces a new constraint on the order in which the orderMethods() and getDefaultExecutionMode() methods in a MethodOrderer are invoked. Specifically, orderMethods() is now guaranteed to be invoked before getDefaultExecutionMode() so that the latter may include logic that determines the appropriate return value based on what was performed in orderMethods(). This commit also fixes a bug in the Random MethodOrderer when a custom seed is configured and tests are executed in parallel. Specifically, the getDefaultExecutionMode() in the Random orderer now returns SAME_THREAD if a custom seed has been configured and otherwise CONCURRENT. Issue: #13
These commits introduce new support in JUnit Jupiter for ordering the sequence of test methods. Specifically, these commits introduce a new MethodOrderer API that can be registered via a new @TestMethodOrder annotation. JUnit Jupiter provides the following built-in implementations of this new API. - Alphanumeric: sorts test methods alphanumerically based on their names and formal parameter lists. - OrderAnnotation: sorts test methods numerically based on values specified via the @order annotation. - Random: orders test methods pseudo-randomly and supports configuration of a custom seed. Consult the new "Test Execution Order" section of the User Guide for details and example usage. Issue: #13
Drum roll........ Support for ordering the sequence of test methods has been merged into |
Yay! Thanks again |
¡de nada! / You're welcome! 😉 |
Hi. @sbrannen thanks for adding this to Junit! |
You're very welcome.
Do you have a link to an issue for that?
In general, we flag new APIs as experimental for their initial release and then wait a few minor releases to see if the community raises any issues with the API or implementation. This particular feature was released in JUnit Jupiter 5.4, and 5.5 is currently being worked on. There have been a few improvements to the implementation since 5.4.0 but no changes to the API. So if that continues to be the case, we might switch the API status from experimental to stable in 5.6 (even potentially for 5.5 GA -- to be discussed). |
Ok, thanks for info!
Here is the link: spring-cloud/spring-cloud-contract#887 |
Thanks for the link. |
How does this work with |
@Fernal73, as stated in the Javadoc for
If you are experiencing behavior contrary to that, please open a new ticket providing further details. Thanks |
I've experienced out of order invocations when setting the Execution mode as concurrent. How do you decide that the ordering does not interfere with concurrency? I'd expect ordered methods to be executed in a single thread wrapped in a synchronizer that orders the methods as per their values so that shared state in the test class is not adversely impacted causing failed tests. If all my methods are ordered, shouldn't the methods be executed in a single thread irrespective of ExecutionMode? I have since updated my tests to not have a shared state; @order no longer matters and has been removed. |
That is to be expected. The Javadoc for
The
This issue was closed more than 1.5 years ago. If you wish to make suggestions for improvements or changes to the current behavior or feature set, please open a new issue. |
Is this to be expected even for @order annotated methods? Other test methods, of course. This ought to be documented better. If @order methods go out of sync with ExecutionMode.CONCURRENT, then they ought to be permitted only with SINGLE_THREAD mode. See previous response for edits. |
I'm inclined to go with the workaround that @order annotated methods not be mixed with methods to be executed concurrently viz, have a separate Test class for each type. |
Yes
Again, this closed issue is not the place to make recommendations. If you feel strongly about those points, please open one or more new issues to address them. |
Overview
Although it is typically discouraged, having a way to order tests is useful to some people. The JUnit 4
@FixMethodOrder
annotation specifically and deliberately makes it impossible to implement a simple ordering scheme, forcing users who want/need this to resort to method names liketest245_ensureReasonableTestName()
.Proposal
MethodSorter
for@FixMethodOrder
@FixMethodOrder(ORDERED)
, and then@Order(integer)
to specify individual tests. Tests could be run from smallest number to highest, with non-annotated methods having a default of 0. Methods with the same order could be run in parallel; different order tiers could not.Related Issues
Deliverables
@Order
based ordering.@Test
,@TestFactory
and@TestTemplate
methods.@Nested
classes.junit.jupiter.execution.order.random.seed
constant and document it.@API
declarations for types with changed visibility, etc.Out of Scope
The text was updated successfully, but these errors were encountered: