Khi dự án mở rộng sang cả web và mobile, việc duy trì chất lượng mã nguồn trở nên thách thức. Một chiến lược kiểm thử thống nhất giúp phát hiện lỗi sớm, giảm thời gian debug và tăng độ tin cậy khi triển khai. Dưới đây là quy trình thực tế đã áp dụng thành công trong nhiều dự án đa nền tảng. 1. Cấu hình môi trường chung - Sử dụng monorepo (Nx hoặc Turborepo) để chia sẻ cấu hình Jest, TypeScript và ESLint giữa web và native. - Cài đặt @testing-library/react cho web và @testing-library/react-native cho mobile. Cả hai đều tuân thủ cùng một API, giúp viết test một lần, chạy hai nơi. 2. Unit test và component test - Viết test cho logic thuần (hooks, utils, selectors) bằng Jest thuần túy. Ví dụ: test hook useAuth trả về đúng trạng thái đăng nhập. - Với component, dùng render từ testing-library và fireEvent / userEvent để mô phỏng tương tác. Tránh test implementation details; tập trung vào hành vi người dùng thấy. - Sử dụng snapshot test chỉ cho các component UI ổn định (button, card) để phát hiện thay đổi vô tình. 3. Integration test cho luồng nghiệp vụ - Kết hợp nhiều component trong một test: ví dụ luồng đăng nhập → lấy profile → hiển thị dashboard. - Mock API bằng msw (Mock Service Worker) cho web và jest-fetch-mock cho native. Đảm bảo contract giữa client và server được kiểm tra qua contract test (Pact) nếu cần. 4. End‑to‑end test trên thiết bị thật / emulator - Cài đặt Detox cho iOS/Android. Viết kịch bản người dùng thực: mở app, nhập thông tin, bấm nút, kiểm tra màn hình tiếp theo. - Chạy Detox trên CI (GitHub Actions) với matrix os: macos-latest cho iOS, ubuntu-latest cho Android. - Song song, dùng Playwright cho web E2E, cùng một bộ kịch bản (data-test-id) để tái sử dụng. 5. Chiến lược CI/CD - Stage 1: lint + type‑check + unit/component test (chạy nhanh, song song). - Stage 2: integration test (chạy sau stage 1). - Stage 3: e2e test (chạy trên matrix thiết bị). Chỉ merge khi tất cả pass. - Thu thập coverage report (jest --coverage) và upload lên Codecov để theo dõi xu hướng. 6. Mẹo thực chiến - Đặt data-testid nhất quán cho cả web và native (ví dụ: "login-button"). - Tách test utilities vào package shared/testing-utils để tái sử dụng render, mock store, mock navigation. - Sử dụng test‑only scripts trong package.json: "test:web", "test:native", "test:e2e". - Thiết lập flaky test quarantine: chạy lại tối đa 2 lần trước khi fail build. Kết luận: Việc thống nhất công cụ, quy ước đặt tên và pipeline CI giúp team phát triển song song web và mobile mà không lo mất kiểm soát chất lượng. Bắt đầu từ unit test nhỏ, mở rộng dần sang integration và e2e sẽ mang lại sự tự tin khi release liên tục.