Detox là một framework kiểm thử E2E gray-box cho các ứng dụng di động, được tạo ra bởi nhóm Wix dành riêng cho các dự án React Native. Khác với các phương pháp black-box, Detox có quyền truy cập vào trạng thái nội bộ của ứng dụng, cho phép tự động đồng bộ mà không cần timeout thủ công. Theo Wix Engineering, 2026, đồng bộ tự động giảm thời gian chạy kiểm thử xuống 40% so với các tạm dừng truyền thống.
Các điểm chính
Detox là một framework kiểm thử đầu cuối (E2E) cho các ứng dụng di động, được phát triển bởi Wix vào năm 2017. Nó được thiết kế cho các dự án React Native nhưng cũng hỗ trợ các ứng dụng native thuần túy trên iOS và Android. Detox hoạt động theo mô hình gray-box, nghĩa là nó có quyền truy cập vào các cơ chế nội bộ của ứng dụng.
Sự khác biệt chính giữa Detox và Appium hay Calabash là đồng bộ tự động với ứng dụng. Framework chờ đợi các hoạt ảnh, yêu cầu mạng và xử lý sự kiện hoàn tất trước khi thực hiện hành động tiếp theo. Điều này loại bỏ hoàn toàn nhu cầu về Thread.sleep() hoặc waitForElement, những thứ làm chậm kiểm thử.
Detox hỗ trợ iOS (qua XCTest và Xcode) và Android (qua Espresso và UI Automator). Đối với các ứng dụng React Native, hỗ trợ đầy đủ được cung cấp cho Fabric và kiến trúc cũ. Trên iOS, các kiểm thử chạy trên trình mô phỏng; trên Android, chạy trên trình giả lập hoặc thiết bị thật.
Kiến trúc Detox bao gồm ba thành phần chính: Detox CLI, trình chạy kiểm thử Detox và Detox Native Driver. Detox CLI quản lý việc xây dựng, cài đặt và chạy kiểm thử ứng dụng. Trình chạy kiểm thử (Jest hoặc Mocha) thực hiện các kịch bản kiểm thử và giao tiếp với ứng dụng qua WebSocket.
Kiểm thử gray-box có nghĩa là Detox có quyền truy cập vào trạng thái nội bộ của ứng dụng thông qua một cầu nối native. Framework giám sát các yêu cầu mạng, hoạt ảnh, bộ đếm thời gian và hàng đợi thao tác. Khi tất cả các hàng đợi trống, Detox coi ứng dụng đã sẵn sàng cho bước tiếp theo.
Đồng bộ dựa trên việc giám sát luồng chính của ứng dụng. Detox chờ cho đến khi tất cả các hoạt ảnh hoàn tất, các yêu cầu HTTP trả về phản hồi và các trình xử lý sự kiện kết thúc thực thi. Nếu một kiểm thử bị treo do hoạt ảnh vô hạn, bạn có thể tắt đồng bộ thủ công cho một khối mã cụ thể.
// Tắt đồng bộ cho một phần có vấn đề
await device.disableSynchronization();
// Hành động có hoạt ảnh dài
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
Việc cài đặt Detox bắt đầu bằng cách thêm gói qua npm hoặc yarn. Sau khi cài đặt, bạn cần tạo một tệp cấu hình .detoxrc.js, mô tả các cài đặt xây dựng và chạy cho từng nền tảng. Detox sử dụng loại xây dựng riêng cho iOS, dựa trên cấu hình Xcode.
Cấu hình bao gồm đường dẫn đến ứng dụng (app), loại trình xây dựng (build), đối số xây dựng và cài đặt thiết bị (device). Cho iOS, appleSimulator được sử dụng; cho Android, androidEmulator. Bạn cũng có thể chỉ định các đối số khởi chạy như ngôn ngữ hoặc khu vực của trình mô phỏng.
// .detoxrc.js — ví dụ cấu hình
module.exports = {
testRunner: { args: { '$0': 'jest', config: 'e2e/config.json' } },
apps: {
'ios.debug': { type: 'ios.app', build: 'xcodebuild ...' },
'android.debug': { type: 'android.apk', build: 'cd android && ./gradlew ...' }
},
devices: {
simulator: { type: 'ios.simulator', device: { type: 'iPhone 15' } },
emulator: { type: 'android.emulator', device: { avdName: 'Pixel_4_API_34' } }
}
};
Sau khi cấu hình, các lệnh sau đây khả dụng: detox build — xây dựng ứng dụng với các cờ kiểm thử, và detox test — chạy các kiểm thử. Detox hỗ trợ chạy song song trên nhiều thiết bị bằng cờ --workers.
Các kiểm thử Detox được viết bằng JavaScript hoặc TypeScript sử dụng API dựa trên tìm kiếm phần tử (matchers) và hành động (actions). Matchers cho phép bạn tìm một phần tử theo định danh, văn bản, loại hoặc vị trí trên màn hình. Các hành động thực hiện chạm, nhập văn bản, vuốt và cuộn.
Một kiểm thử điển hình tuân theo trình tự sau: tìm phần tử → thực hiện hành động → xác minh kết quả. Để xác minh, API expect được sử dụng với các matcher về sự hiện diện, khả năng hiển thị hoặc văn bản của phần tử. Detox hỗ trợ cú pháp describe/it thông qua tích hợp với Jest.
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should log in with valid credentials', async () => {
await element(by.id('emailInput')).typeText('user@test.com');
await element(by.id('passwordInput')).typeText('password123');
await element(by.id('loginButton')).tap();
await expect(element(by.id('homeScreen'))).toBeVisible();
});
});
Detox hỗ trợ tất cả các cử chỉ phổ biến: tap, longPress, swipe, scroll, pinch, multiTap. Đối với scroll, bạn có thể chỉ định hướng, tốc độ và vị trí dừng. Điều này cho phép kiểm thử các kịch bản phức tạp như pull-to-refresh hoặc băng chuyền.
Detox tích hợp tốt với các hệ thống CI phổ biến: GitHub Actions, CircleCI, Bitrise và Jenkins. Để chạy trong CI, bạn cần thiết lập trình mô phỏng iOS ảo (không có giao diện đồ họa) và trình giả lập Android với tăng tốc phần cứng. Detox cung cấp các artifact — ảnh chụp màn hình và nhật ký — để phân tích các kiểm thử thất bại.
Để tăng tốc chạy kiểm thử trong CI, nên sử dụng sharding (song song hóa) với cờ --workers. Detox tự động phân phối các tệp kiểm thử giữa nhiều trình mô phỏng. Việc lưu vùng đệm các bản dựng ứng dụng giữa các lần chạy cũng hữu ích để giảm thời gian xây dựng.
# GitHub Actions — chạy Detox trên iOS
- name: Install Dependencies
run: npm ci
- name: Build Detox App
run: npx detox build --configuration ios.sim
- name: Run Detox Tests
run: npx detox test --configuration ios.sim --workers 2
timeout-minutes: 30
Để có các kiểm thử E2E ổn định và nhanh chóng, nên tuân theo một số quy tắc. Tránh sleep() — Detox cung cấp đồng bộ tự động, và các độ trễ rõ ràng chỉ làm chậm kiểm thử và khiến chúng không ổn định. Nếu một kiểm thử thất bại do vấn đề thời gian, trước tiên hãy kiểm tra xem đồng bộ có bị tắt không. Việc nhóm các kiểm thử theo tính năng và chạy chúng độc lập cũng hữu ích — điều này giúp dễ dàng tìm ra nguyên nhân thất bại.
Detox cung cấp một số phương thức device để quản lý trạng thái: device.reloadReactNative() tải lại bundle, device.launchNewApp() khởi chạy ứng dụng với tham số mới, device.sendToHome() thu nhỏ ứng dụng. device.setURLBlacklist() cho phép loại trừ các URL cụ thể khỏi đồng bộ, hữu ích cho phân tích và kết nối long-polling.
Cho mỗi kiểm thử, nên tạo trạng thái cô lập. Sử dụng beforeEach để tải lại ứng dụng qua device.reloadReactNative(). Đối với các kiểm thử yêu cầu dữ liệu cụ thể, hãy tạo các factory hoặc client API để chuẩn bị dữ liệu trên máy chủ. Tránh sự phụ thuộc giữa các kiểm thử — mỗi kiểm thử phải độc lập.
Detox hỗ trợ kiểm thử WebView qua các phương thức web.element() và web.invoke(). Để tương tác với các phần tử web, by.web](:id, css hoặc className được sử dụng. Điều quan trọng cần nhớ là WebView cần thêm thời gian tải — nếu đồng bộ không hoạt động, hãy thêm chờ tải bằng waitFor.
// Kiểm thử WebView trong Detox
const webView = web(by.id('webview'));
await webView.element(by.web.cssSelector('#submit-btn')).tap();
const result = await webView.element(
by.web.cssSelector('.result-text')
).getText();
await expect(result).toEqual('Success');
Detox hỗ trợ so sánh ảnh chụp màn hình qua plugin detox-image-matching. Ảnh chụp màn hình cho phép phát hiện các hồi quy trực quan: các phần tử bị dịch chuyển, màu sắc không đúng, biểu tượng bị thiếu. Để có ảnh chụp ổn định, hãy tắt các hoạt ảnh và sử dụng kích thước trình mô phỏng cố định.
Các vấn đề phổ biến nhất của Detox liên quan đến đồng bộ: hoạt ảnh vô hạn, yêu cầu mạng dài hoặc bộ đếm thời gian bị treo. Ghi nhật ký với cờ --loglevel trace hiển thị Detox đang chờ tài nguyên nào. Nếu Detox bị treo, hãy sử dụng device.disableSynchronization() cho khối mã có vấn đề.
Trên trình mô phỏng iOS, Detox yêu cầu ứng dụng phải được xây dựng trước qua xcodebuild với cấu hình iphonesimulator. Một lỗi phổ biến là sử dụng lược đồ Release thay vì Debug, điều này vô hiệu hóa các cờ kiểm thử. Đối với Android, hãy đảm bảo AVD được tạo với API tương thích với ứng dụng của bạn và tăng tốc Intel HAXM được bật. Đối với môi trường CI trên macOS, thật tiện lợi khi sử dụng GitHub Actions với trình chạy macOS, nơi Xcode và các trình mô phỏng đã được cài đặt sẵn.
Nếu các kiểm thử thường xuyên thất bại do quá thời gian, hãy kiểm tra: đồng bộ có bị tắt toàn cục không, setTimeout hoặc setInterval có được sử dụng trong mã ứng dụng mà không dọn dẹp không, và luồng chính có bị chặn bởi một thao tác dài không. Đôi khi việc tăng thời gian chờ trong detoxrc.js qua testRunner.args.jest.$.testTimeout sẽ giúp. Để tìm các khu vực có vấn đề, hãy bật ghi nhật ký theo dõi Detox — nó hiển thị các tài nguyên và bộ đếm thời gian mà framework hiện đang chờ.
Sau khi chạy kiểm thử, Detox tạo các artifact: ảnh chụp màn hình của các kiểm thử thất bại, nhật ký ứng dụng và báo cáo XML JUnit. Ảnh chụp màn hình được chụp tự động khi kiểm thử thất bại và giúp xác định trực quan vấn đề. Đối với CI, các artifact được tải lên bộ nhớ đám mây và có sẵn qua giao diện web để phân tích nguyên nhân thất bại.
Câu hỏi thường gặp
Detox sử dụng phương pháp gray-box với quyền truy cập vào trạng thái nội bộ của ứng dụng và đồng bộ tự động. Appium hoạt động theo mô hình black-box qua WebDriver và yêu cầu chờ thủ công. Detox nhanh hơn và ổn định hơn cho các dự án React Native.
Các kiểm thử Detox được viết bằng JavaScript hoặc TypeScript. Framework tích hợp với Jest và Mocha làm trình chạy kiểm thử. Cơ chế native cho iOS được viết bằng Swift, cho Android bằng Kotlin và Java.
Có, Detox hỗ trợ các ứng dụng native trên iOS (qua XCTest) và Android (qua Espresso). Tuy nhiên, đối tượng chính của Detox là các nhà phát triển React Native, vì có những giải pháp trưởng thành hơn cho các dự án native.
Detox cung cấp artifact: ảnh chụp màn hình, nhật ký ứng dụng và báo cáo HTML. Để gỡ lỗi cục bộ, sử dụng cờ --loglevel trace, và cho CI, sử dụng trình thu thập artifact tự động với tải lên đám mây.
Đây là một phương thức của API Detox giúp tải lại bundle JavaScript của React Native mà không cần cài đặt lại ứng dụng. Nó được sử dụng trong beforeEach để đặt lại trạng thái ứng dụng về màn hình ban đầu trước mỗi kiểm thử.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm