Hero Background

Power Your Software Testing with AI Agents and Cloud

The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.

Testing

JUnit Test Execution Order: @TestMethodOrder and @Order

Control JUnit test execution order with @TestMethodOrder, @Order, the MethodName, DisplayName, and Random orderers, ClassOrderer, and a default-order property.

Published on:

A checkout test passes when you run it alone and fails in the full build, because a test that happened to run earlier emptied the shared cart. Someone adds @Order(1) to "create cart" and @Order(2) to "checkout", the build goes green, and the suite now has a hidden dependency that nobody can run in parallel. This chapter covers both halves of that story: how to control JUnit test execution order when a flow genuinely needs it, with @TestMethodOrder, @Order, the built-in orderers, ClassOrderer, and the configuration properties, and how to tell when ordering is the wrong fix.

It follows the JUnit Annotations chapter, which covers the lifecycle order of @BeforeAll, @BeforeEach, and their counterparts; ordering here is about the test methods themselves.

TL;DR

JUnit runs test methods in a deterministic but intentionally nonobvious order by default. To fix the order, annotate the class with @TestMethodOrder(OrderAnnotation.class) and number the methods with @Order; MethodName, DisplayName, and Random orderers and a ClassOrderer cover the other cases, and junit-platform.properties sets a project-wide default.

  • @TestMethodOrder + @Order - explicit numbering inside one class; the only orderer that expresses a business sequence.
  • MethodName and DisplayName - alphanumeric orderers for suites that want predictable, readable reports without numbering every method.
  • Random with a seed - the orderer that finds hidden dependencies; the seed is logged so a failing order can be replayed.
  • ClassOrderer - the same four strategies applied to test classes, through junit.jupiter.testclass.order.default.
  • Order and parallelism - an ordered class must run on one thread; TestMu AI HyperExecute keeps each class on one VM while distributing classes across many.

What Is the Default Test Order in JUnit?

The JUnit user guide's test execution order page states it in one line: by default, test classes and methods will be ordered using an algorithm that is deterministic but intentionally nonobvious. Deterministic means the same build produces the same order every time. Nonobvious means the order is not the one in the source file and not alphabetical, so a test that happens to pass because of its neighbors will keep passing until a method is added or renamed.

I ran a four-method class with no orderer on a TestMu AI HyperExecute Linux VM (job 665c5859, Java 17, JUnit 6.1.3) to see what that looks like. The methods are declared in the order charlie, alpha, bravo, delta, and each prints its name:

[INFO] Running ordering.DefaultOrderTest
[default-order] alpha
[default-order] bravo
[default-order] delta
[default-order] charlie
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.086 s -- in ordering.DefaultOrderTest

Neither declaration order nor alphabetical order, and the same sequence on every rerun. The design is deliberate: the project, whose junit-team/junit-framework repository had 7,055 stars on GitHub on October 7, 2026, wants a suite that works in any order, and an order that looks meaningful would invite tests that depend on it. When you do need control, you ask for it explicitly.

Order Methods With @TestMethodOrder and @Order

The job takes one annotation on the class and one on each method. @TestMethodOrder on the class names the strategy, and @Order on each method supplies the number; lower values run first. Both live in org.junit.jupiter.api, and the orderer is the nested class MethodOrderer.OrderAnnotation:

import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

@TestMethodOrder(OrderAnnotation.class)
class OrderedByAnnotationTest {

    @Test
    @Order(3)
    void validValues() {
        System.out.println("[order-annotation] 3 validValues");
    }

    @Test
    @Order(1)
    void nullValues() {
        System.out.println("[order-annotation] 1 nullValues");
    }

    @Test
    @Order(2)
    void emptyValues() {
        System.out.println("[order-annotation] 2 emptyValues");
    }
}

The methods are declared 3, 1, 2 on purpose. The same job ran them as declared by the annotation, not by the file:

[INFO] Running ordering.OrderedByAnnotationTest
[order-annotation] 1 nullValues
[order-annotation] 2 emptyValues
[order-annotation] 3 validValues
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 s -- in ordering.OrderedByAnnotationTest

Methods without an @Order value get the default value Integer.MAX_VALUE / 2, so they run after any method numbered below that, and @Order applies only inside one class; it says nothing about which class runs first, which is what ClassOrderer is for below. If a numbered sequence does not take effect, the class-level @TestMethodOrder is almost always the missing piece.

MethodName, DisplayName, and Random Orderers

The user guide lists four MethodOrderer implementations, and the right one depends on why you want order at all:

OrdererSorts byUse it when
MethodOrderer.OrderAnnotationThe numeric @Order value on each methodSteps of a flow must run in a business sequence
MethodOrderer.MethodNameMethod name and formal parameter list, alphanumericallyYou want a predictable, readable order in reports without annotating every method
MethodOrderer.DisplayNameThe @DisplayName value, alphanumericallyDisplay names already read as a sequence, such as "1. create" and "2. update"
MethodOrderer.RandomA pseudo-random order with an optional seedYou suspect hidden dependencies and want them to fail now, in CI, rather than later

MethodName is the one most teams reach for when they only want the report to read top to bottom. The run confirms it does exactly what it says, turning charlie, alpha, bravo into alphabetical order:

[INFO] Running ordering.MethodNameOrderTest
[method-name] alpha
[method-name] bravo
[method-name] charlie
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.032 s -- in ordering.MethodNameOrderTest

Random is the least used of the four and the most useful for finding hidden dependencies. Its javadoc names the configuration parameter junit.jupiter.execution.order.random.seed, and when no seed is supplied the default seed is logged at CONFIG level, so a failing nightly run can be replayed with the same order the next morning. Running it once a night surfaces the shared-state bugs that a fixed order hides.

Test infrastructure that does not break, from TestMu AI

Set a Default Orderer in junit-platform.properties

Annotating every class is noisy. The configuration parameter junit.jupiter.testmethod.order.default applies one orderer to every class that does not declare its own, and the usual place to set it is src/test/resources/junit-platform.properties, where the user guide's example reads:

# src/test/resources/junit-platform.properties
junit.jupiter.testmethod.order.default = \
    org.junit.jupiter.api.MethodOrderer$OrderAnnotation

The value is the fully qualified class name with a dollar sign before the nested class, because MethodOrderer.OrderAnnotation is a nested type. A class-level @TestMethodOrder overrides the property, so a project can default to MethodName for readable reports and switch one integration class to OrderAnnotation. The same file is where parallel execution is switched on, which the JUnit Parallel Testing chapter covers; an ordered class and a concurrent class can live in the same suite as long as the ordered one runs its methods on a single thread.

Order Test Classes With ClassOrderer

Method order says nothing about which class runs first. For that the Platform provides ClassOrderer, with four implementations that mirror the method ones: ClassName sorts by fully qualified class name, DisplayName by display name, OrderAnnotation by an @Order value placed on the class, and Random pseudo-randomly with a seed. It is selected globally rather than per class:

# src/test/resources/junit-platform.properties
junit.jupiter.testclass.order.default = \
    org.junit.jupiter.api.ClassOrderer$OrderAnnotation
@Order(1)
class SchemaMigrationIT { /* runs first */ }

@Order(2)
class DataSeedingIT { /* runs second */ }

Class ordering only holds within one JVM and one run. Surefire's -Dtest selection, a JUnit Test Suite that selects a subset, or a cloud grid that splits classes across machines all change which classes are present, and a class that must run before another is a class that cannot be split away from it.

Nested Classes, Parameterized Tests, and Repeated Tests

These cases trip people up once ordering is in place:

  • @Nested classes - the user guide states that top-level test classes are ordered relative to each other, whereas @Nested test classes are ordered relative to other @Nested test classes sharing the same enclosing class. An @Order on a nested class therefore competes only with its siblings, and the JUnit 6.0 release notes list deterministic ordering of nested classes among the changes. The JUnit Nested Tests chapter covers the lifecycle inside them.
  • @ParameterizedTest invocations - the method is one unit for the orderer; its invocations run in argument-source order, so @Order sorts the method among its neighbors but cannot interleave individual rows. See JUnit Parameterized Tests.
  • @RepeatedTest - the same rule: the repetitions stay together, numbered 1 to n, wherever the method lands. The JUnit Repeated Tests chapter explains the RepetitionInfo each one receives.

Disabled tests keep their position too: a method skipped with @Disabled still occupies its slot in the order, which matters when step 2 of a numbered flow is switched off and step 3 assumes it ran. The JUnit Ignore Test chapter covers the conditional annotations that cause that.

JUnit 4: @FixMethodOrder and MethodSorters

JUnit 4 had the same philosophy and a coarser tool. The @FixMethodOrder javadoc explains that the default order within a class is deterministic but not predictable, and that JUnit 4.11 introduced it because the earlier JVM order was not guaranteed and could change from run to run. The annotation takes one of the MethodSorters values: DEFAULT, the deterministic but not predictable order; NAME_ASCENDING, lexicographic by method name with Method.toString() as a tiebreaker; or JVM, the order the JVM returns, which may vary from run to run.

// JUnit 4
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class LegacyOrderedTest {
    @Test public void test1_create() { }
    @Test public void test2_update() { }
}

// JUnit 5 and 6 equivalent
@TestMethodOrder(MethodOrderer.MethodName.class)
class OrderedTest {
    @Test void test1_create() { }
    @Test void test2_update() { }
}

The migration is a one-line swap for NAME_ASCENDING, and an upgrade for everything else: JUnit 4 had no per-method @Order, so suites that encoded sequence in method names like test1_ and test2_ can finally drop the prefixes. The JUnit 4 vs JUnit 5 chapter lists the rest of the annotation map.

When Ordering Is the Wrong Fix

The user guide puts the caveat next to the feature: although true unit tests typically should not rely on the order in which they are executed, there are times when it is necessary to enforce a specific test method execution order. The distinction is between a sequence the domain requires and a sequence the test code accidentally requires.

SymptomOrdering hides itThe fix that lasts
A test fails only after another test ran@Order moves the victim earlierReset the shared state in @BeforeEach, or give each test its own fixture
Tests share a static field or a singleton@Order keeps the writes in a safe sequenceInject the dependency per test; static state is also what breaks parallel runs
Test 2 needs the record test 1 created@Order(1) and @Order(2)Create the record in test 2's own setup; a test that cannot run alone is not a unit test
A real multi-step flow: register, log in, check outNot hiding anythingKeep @Order, mark the class as integration, and run it on one thread
Expensive setup shared by many tests@Order puts the setup test first@BeforeAll, or a @BeforeSuite in a suite class, which runs once and is not a test

TestNG offers the same tools under different names, priority and dependsOnMethods, and the same caution applies; the Priority in TestNG chapter covers that side. Where ordering is legitimate, the cost shows up at scale: an ordered class is a unit that cannot be split. HyperExecute works with that constraint rather than against it. Its Auto-Split discovers test classes and distributes whole classes across fresh VMs with mvn test -Dtest=$test, so an @Order sequence inside a class always executes on one machine in one JVM, while unrelated classes run in parallel elsewhere, and the merged report still reads as one run. The HyperExecute getting started guide shows the discovery command for a Maven project.

Note

Note: Keep ordered classes intact and still cut suite time: TestMu AI runs each JUnit class on its own VM and merges the results. Try TestMu AI free!

Best Practices for JUnit Test Order

  • Default to no order - if a test needs a neighbor, fix the test; @TestMethodOrder is for flows, not for making a red build green.
  • Number in tens - @Order(10), @Order(20), @Order(30) leaves room to insert a step without renumbering the class.
  • Mark ordered classes - a @Tag("flow") or an IT suffix tells the next reader, and the pipeline, that the class must run whole and single-threaded.
  • Run Random in CI once a day - with the seed in the log, an order-dependent test is found and reproduced the same morning.
  • Prefer MethodName for reports - when the only goal is a readable report, the alphabetical orderer costs nothing and tempts nobody to add dependencies.
  • Keep ClassOrderer for integration packages - class order across a whole unit suite is a sign the tests share infrastructure that should be per class.

Conclusion

Add @TestMethodOrder(MethodOrderer.Random.class) to one class that you suspect of hidden dependencies and run it ten times; if it survives, it never needed ordering. For the flows that do, @TestMethodOrder(OrderAnnotation.class) with @Order values in tens, a junit-platform.properties default for the rest, and a ClassOrderer only in integration packages cover every case of JUnit test execution order this chapter ran.

The next chapter, JUnit Ignore Test, covers @Disabled and the conditional annotations, including how a skipped step behaves inside an ordered class. The What Is JUnit chapter explains the engine that applies these orderers if you want the model behind them.

Author

...

Himanshu Sheth

Blogs: 142

  • Twitter
  • Linkedin

Himanshu Sheth is the Director of Marketing (Technical Content) at TestMu AI, with over 8 years of hands-on experience in Selenium, Cypress, and other test automation frameworks. He has authored more than 130 technical blogs for TestMu AI, covering software testing, automation strategy, and CI/CD. At TestMu AI, he leads the technical content efforts across blogs, YouTube, and social media, while closely collaborating with contributors to enhance content quality and product feedback loops. He has done his graduation with a B.E. in Computer Engineering from Mumbai University. Before TestMu AI, Himanshu led engineering teams in embedded software domains at companies like Samsung Research, Motorola, and NXP Semiconductors. He is a core member of DZone and has been a speaker at several unconferences focused on technical writing and software quality.

Reviewer

...

Srinivasan Sekar

Reviewer

  • Linkedin

Srinivasan Sekar is Director of Engineering at TestMu AI (formerly LambdaTest), where he leads engineering and open-source initiatives behind the Selenium and Appium automation grid and owns TestMu AI's MCP Server. A committer to Appium and a contributor to Selenium, WebdriverIO, Taiko, and AppiumTestDistribution, he brings over 15 years of experience in quality engineering and open-source technologies. He is the author of the Apress book 'The MCP Standard: A Developer's Guide to Building Universal AI Tools with the Model Context Protocol,' a Certified Kubernetes and Cloud Native Associate, and an international conference speaker. Before TestMu AI he spent over eight years at Thoughtworks as a Principal Consultant and Quality Architect. Srinivasan holds a B.Tech in Information Technology from Anna University.

JUnit Test Order FAQs

Did you find this page helpful?

More Related Learning Hubs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests