
How Uber Executed A JUnit Migration at Massive Scale
Earlier this year, Uber’s Java monorepo used JUnit 4 as the primary framework for its test suite. While functional, reliance on this framework prevented us from adopting the enhanced testing capabilities of JUnit 5, which launched over eight years ago. Moreover, active development on JUnit 4 ceased in 2021, meaning bugs, security patches, and features would no longer get addressed. There was a clear case for transitioning to a modernized test framework, but it came with challenges. With over 600,000 JUnit 4 tests spanning 15 million lines of code, we faced both a technical and cultural challenge: motivating developers to adopt JUnit 5. A manual migration would require developers to learn the Jupiter API and migrate custom test suites, consuming valuable engineering hours. Additionally, Uber uses Bazel™, which lacks native JUnit 5 support. Future JUnit versions plan to drop JUnit 4 support entirely, making migration increasingly urgent. Given these challenges, we needed a large-scale migration approach that’d automate the transition while minimally disrupting workflows.