Uber chuyển đổi thành công hơn 75.000 lớp kiểm thử từ JUnit 4 sang JUnit 5 sử dụng công cụ tự động hóa

27 tháng 4, 2026·4 phút đọc

Các kỹ sư của Uber đã di chuyển hơn 75.000 lớp kiểm thử và 1,25 triệu dòng mã từ JUnit 4 sang JUnit 5 bằng cách sử dụng OpenRewrite và hệ thống điều phối nội bộ. Việc này hiện đại hóa cơ sở hạ tầng kiểm thử trên quy mô monorepo mà vẫn đảm bảo tính chính xác thông qua mô hình thực thi kép với Bazel.

Uber chuyển đổi thành công hơn 75.000 lớp kiểm thử từ JUnit 4 sang JUnit 5 sử dụng công cụ tự động hóa

Các kỹ sư của Uber đã thực hiện một dự án kỹ thuật quy mô lớn: chuyển đổi hơn 75.000 lớp kiểm thử và hơn 1,25 triệu dòng mã từ JUnit 4 sang JUnit 5 trên kho mã (monorepo) Java của công ty. Động lực chính cho việc này là nhu cầu áp dụng một khung kiểm thử hiện đại với khả năng mở rộng tốt hơn và giảm bớt nợ kỹ thuật từ một hệ thống cũ đã ngừng phát triển tích cực.

JUnit 4 đã ở chế độ bảo trì kể từ năm 2021, trong khi JUnit 5 mang đến kiến trúc mô-đun dựa trên JUnit Platform, hỗ trợ động cơ Jupiter và cải thiện khả năng kiểm thử có tham số hóa. Đối với Uber, việc tiếp tục sử dụng JUnit 4 làm hạn chế khả năng tiếp cận các tính năng mới, khiến việc di chuyển trở nên cần thiết bất chấp sự phức tạp do quy mô và hạn chế về cơ sở hạ tầng.

Bật hỗ trợ JUnit 5 cho BazelBật hỗ trợ JUnit 5 cho Bazel

Thách thức với Bazel và mô hình thực thi kép

Một trong những thách thức lớn là hệ thống monorepo của Uber tích hợp hàng trăm nghìn bài kiểm thử với Bazel, công cụ này vốn không hỗ trợ JUnit 5 một cách tự nhiên. Để giải quyết vấn đề này, các kỹ sư đã kích hoạt mô hình thực thi thống nhất thông qua JUnit Platform.

Điều này cho phép cả bài kiểm thử JUnit 4 và JUnit 5 chạy cùng nhau thông qua các động cơ Vintage và Jupiter. Lớp tương thích này đảm bảo quá trình di chuyển có thể diễn ra từng bước mà không làm gián đoạn quy trình làm việc hiện có.

Anshuman Mishra và Kaushik Vejju từ Uber nhận định:

"Công cụ chuyển đổi mang tính xác định là rất quan trọng để đảm bảo tính nhất quán ở quy mô này."

Thực tế, nhóm kỹ sư nhận thấy rằng AI tạo sinh (Generative AI) thường đưa ra kết quả không nhất quán đối với các mẫu kiểm thử tùy chỉnh. Do đó, Uber đã chọn hướng đi khác để đảm bảo độ tin cậy.

Tự động hóa với OpenRewrite

Với nền tảng thực thi đã sẵn sàng, Uber đã áp dụng OpenRewrite để tự động hóa các thay đổi mã nguồn. OpenRewrite hoạt động dựa trên biểu diễn ngữ nghĩa của mã, cho phép chuyển đổi xác định từ API JUnit 4 sang tương đương JUnit 5. Các kỹ sư đã định nghĩa các "công thức" chuyển đổi (recipes) để cập nhật chú thích, thay thế các quy tắc cũ và chuyển đổi các mẫu kiểm thử có tham số hóa sang cấu trúc JUnit Jupiter.

Để hỗ trợ các mẫu kiểm thử nội bộ, đội ngũ đã mở rộng các công thức này bằng các chuyển đổi tùy chỉnh nhắm vào các trình chạy kiểm thử và lớp cơ sở đặc thù của Uber. Các kiểm tra điều kiện tiên quyết cũng được đưa vào để tránh các tệp kiểm thử bị chuyển đổi một phần và đảm bảo các mẫu không được hỗ trợ bị loại khỏi các bản cập nhật tự động.

Điều phối quy mô lớn với Shepherd

Việc thực thi ở quy mô lớn được quản lý thông qua một hệ thống điều phối nội bộ gọi là Shepherd. Hệ thống này áp dụng các chuyển đổi song song trên hàng nghìn mục tiêu Bazel. Shepherd tạo ra các diff mã và xác thực chúng thông qua các đường ống tích hợp liên tục (CI), bao gồm cả việc thực thi kiểm thử đơn vị và tích hợp, đảm bảo tính đúng đắn về hành vi trước khi các thay đổi được chấp nhận.

![Tự động tạo diff qua Shepherd](https://imgopt.infoq.com/fit-in/3000x4000/filters:quality(85)/filters:no_upscale()/news/2026/04/uber-junit4-junit5-migration/en/resources/1Screenshot 2026-04-18 at 1.46.18 PM-1776546985000.png)

Quá trình di chuyển tuân theo mô hình triển khai lặp đi lặp lại. Các lần chạy đầu tiên đã phát hiện ra lỗi xây dựng và kiểm thử, từ đó cung cấp thông tin để cập nhật logic chuyển đổi. Qua các lần lặp lại tiếp theo, độ bao phủ của tự động hóa được cải thiện, cho phép chuyển đổi các phần lớn hơn của cơ sở mã với sự can thiệp thủ công tối thiểu.

Kết luận và tương lai

Uber cho biết dự án này đã đặt nền tảng cho các chuyển đổi quy mô lớn trong tương lai sử dụng OpenRewrite. Các nỗ lực đang diễn ra bao gồm tích hợp nó vào Bazel cho các bản dựng Spring Boot 3 và di chuyển Guava sang các API Java chuẩn cũng như Joda-Time sang java.time. Đây là một bước đi chiến lược giúp Uber duy trì tốc độ phát triển phần mềm đồng thời đảm bảo chất lượng và tính hiện đại của hệ thống.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗