Detox เป็นเฟรมเวิร์กสำหรับการทดสอบ E2E แบบ gray-box ของแอปพลิเคชันมือถือ สร้างขึ้นโดยทีม Wix สำหรับโปรเจกต์ React Native โดยเฉพาะ แตกต่างจากแนวทาง black-box ตรงที่ Detox สามารถเข้าถึงสถานะภายในของแอปพลิเคชัน ทำให้สามารถซิงโครไนซ์โดยอัตโนมัติโดยไม่ต้องใช้เวลาในการรอด้วยตนเอง ตามข้อมูลจาก Wix Engineering, 2026 การซิงโครไนซ์อัตโนมัติ ช่วยลดเวลาการรันทดสอบได้ถึง 40% เมื่อเทียบกับการหยุดชั่วคราวแบบดั้งเดิม
ประเด็นสำคัญ
Detox เป็นเฟรมเวิร์กสำหรับการทดสอบแบบ end-to-end (E2E) ของแอปพลิเคชันมือถือ พัฒนาโดย Wix ในปี 2017 ออกแบบมาสำหรับโปรเจกต์ React Native แต่ยังรองรับแอปพลิเคชันเนทีฟบน iOS และ Android อีกด้วย Detox ทำงานบนโมเดล gray-box ซึ่งหมายความว่าสามารถเข้าถึงกลไกภายในของแอปพลิเคชันได้
ความแตกต่างหลักระหว่าง Detox กับ Appium หรือ Calabash คือ การซิงโครไนซ์อัตโนมัติ กับแอปพลิเคชัน เฟรมเวิร์กจะรอให้แอนิเมชัน คำขอเครือข่าย และการประมวลผลเหตุการณ์เสร็จสมบูรณ์ก่อนดำเนินการต่อไป ซึ่งช่วยขจัดความจำเป็นในการใช้ Thread.sleep() หรือ waitForElement ที่ทำให้การทดสอบช้าลง
Detox รองรับ iOS (ผ่าน XCTest และ Xcode) และ Android (ผ่าน Espresso และ UI Automator) สำหรับแอปพลิเคชัน React Native มีการรองรับอย่างเต็มที่สำหรับ Fabric และสถาปัตยกรรมเก่า บน iOS การทดสอบจะทำงานบนโปรแกรมจำลอง บน Android จะทำงานบนโปรแกรมจำลองหรืออุปกรณ์จริง
สถาปัตยกรรม Detox ประกอบด้วยสามองค์ประกอบหลัก: Detox CLI, ตัวรันทดสอบ Detox และ Detox Native Driver Detox CLI จัดการการสร้าง การติดตั้ง และการทำงานของทดสอบแอปพลิเคชัน ตัวรันทดสอบ (Jest หรือ Mocha) ดำเนินการสถานการณ์ทดสอบและสื่อสารกับแอปพลิเคชันผ่าน WebSocket
การทดสอบ gray-box หมายความว่า Detox สามารถเข้าถึง สถานะภายใน ของแอปพลิเคชันผ่านบริดจ์เนทีฟ เฟรมเวิร์กจะตรวจสอบคำขอเครือข่าย แอนิเมชัน ตัวจับเวลา และคิวการดำเนินการ เมื่อคิวทั้งหมดว่าง Detox จะถือว่าแอปพลิเคชันพร้อมสำหรับขั้นตอนถัดไป
การซิงโครไนซ์ขึ้นอยู่กับการตรวจสอบ เธรดหลัก ของแอปพลิเคชัน Detox จะรอจนกว่าแอนิเมชันทั้งหมดจะเสร็จสมบูรณ์ คำขอ HTTP ส่งคืนการตอบสนอง และตัวจัดการเหตุการณ์ดำเนินการเสร็จสิ้น หากการทดสอบค้างเนื่องจากแอนิเมชันไม่สิ้นสุด คุณสามารถปิดการซิงโครไนซ์ด้วยตนเองสำหรับบล็อกโค้ดที่เฉพาะเจาะจง
// ปิดการซิงโครไนซ์สำหรับส่วนที่มีปัญหา
await device.disableSynchronization();
// การดำเนินการกับแอนิเมชันยาว
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
การติดตั้ง Detox เริ่มต้นด้วยการเพิ่มแพ็คเกจผ่าน npm หรือ yarn หลังจากการติดตั้ง คุณต้องสร้างไฟล์กำหนดค่า .detoxrc.js ซึ่งอธิบายการตั้งค่าการสร้างและการทำงานสำหรับแต่ละแพลตฟอร์ม Detox ใช้ประเภทการสร้างของตัวเองสำหรับ iOS ซึ่งขึ้นอยู่กับการกำหนดค่า Xcode
การกำหนดค่ารวมถึงเส้นทางไปยังแอปพลิเคชัน (app) ประเภทตัวสร้าง (build) อาร์กิวเมนต์การสร้าง และการตั้งค่าอุปกรณ์ (device) สำหรับ iOS ใช้ appleSimulator สำหรับ Android ใช้ androidEmulator คุณยังสามารถระบุอาร์กิวเมนต์การเริ่มต้น เช่น ภาษาหรือภูมิภาคของโปรแกรมจำลอง
// .detoxrc.js — ตัวอย่างการกำหนดค่า
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' } }
}
};
หลังจากการกำหนดค่า คำสั่งต่อไปนี้จะพร้อมใช้งาน: detox build — สร้างแอปพลิเคชันด้วยแฟลกทดสอบ และ detox test — รันการทดสอบ Detox รองรับการทำงานแบบขนานบนหลายอุปกรณ์ด้วยแฟลก --workers
การทดสอบ Detox เขียนด้วย JavaScript หรือ TypeScript โดยใช้ API ที่อิงจากการค้นหาองค์ประกอบ (matchers) และการกระทำ (actions) Matchers ช่วยให้คุณค้นหาองค์ประกอบตามตัวระบุ ข้อความ ประเภท หรือตำแหน่งบนหน้าจอ การกระทำดำเนินการแตะ ป้อนข้อความ ปัด และเลื่อน
การทดสอบทั่วไปจะเป็นไปตามลำดับนี้: ค้นหาองค์ประกอบ → ดำเนินการ → ตรวจสอบผลลัพธ์ สำหรับการตรวจสอบ จะใช้ API expect ร่วมกับ matchers สำหรับการมีอยู่ การมองเห็น หรือข้อความขององค์ประกอบ Detox รองรับไวยากรณ์ describe/it ผ่านการรวมเข้ากับ 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 รองรับท่าทางยอดนิยมทั้งหมด: tap, longPress, swipe, scroll, pinch, multiTap สำหรับ scroll คุณสามารถระบุทิศทาง ความเร็ว และตำแหน่งหยุด ซึ่งช่วยให้ทดสอบสถานการณ์ที่ซับซ้อน เช่น pull-to-refresh หรือภาพหมุน
Detox รวมเข้ากับระบบ CI ยอดนิยมได้ดี: GitHub Actions, CircleCI, Bitrise และ Jenkins สำหรับการทำงานใน CI คุณต้องตั้งค่า โปรแกรมจำลอง iOS เสมือน (ไม่มี GUI) และโปรแกรมจำลอง Android ที่มีการเร่งด้วยฮาร์ดแวร์ Detox ให้สิ่งประดิษฐ์ — ภาพหน้าจอและบันทึก — สำหรับวิเคราะห์การทดสอบที่ล้มเหลว
เพื่อเพิ่มความเร็วในการรันทดสอบใน CI แนะนำให้ใช้ การแบ่งส่วน (การทำขนาน) ด้วยแฟลก --workers Detox จะกระจายไฟล์ทดสอบไปยังโปรแกรมจำลองหลายตัวโดยอัตโนมัติ การแคชบิลด์แอปพลิเคชันระหว่างการรันก็มีประโยชน์เช่นกันเพื่อลดเวลาในการสร้าง
# GitHub Actions — รัน Detox บน 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
สำหรับการทดสอบ E2E ที่เสถียรและรวดเร็ว แนะนำให้ปฏิบัติตามกฎหลายข้อ หลีกเลี่ยง sleep() — Detox ให้การซิงโครไนซ์อัตโนมัติ และการหน่วงเวลาที่ชัดเจนจะทำให้การทดสอบช้าลงและไม่เสถียรเท่านั้น หากการทดสอบล้มเหลวเนื่องจากปัญหาเวลา ให้ตรวจสอบก่อนว่าปิดการซิงโครไนซ์หรือไม่ การจัดกลุ่มการทดสอบตามฟีเจอร์และรันอย่างอิสระก็มีประโยชน์เช่นกัน — ซึ่งช่วยให้ค้นหาสาเหตุของความล้มเหลวได้ง่ายขึ้น
Detox มีเมธอด device หลายตัวสำหรับการจัดการสถานะ: device.reloadReactNative() โหลดบันเดิลใหม่ device.launchNewApp() เริ่มแอปพลิเคชันด้วยพารามิเตอร์ใหม่ device.sendToHome() ย่อแอปพลิเคชัน device.setURLBlacklist() ช่วยให้คุณยกเว้น URL บางอย่างจากการซิงโครไนซ์ ซึ่งมีประโยชน์สำหรับการวิเคราะห์และการเชื่อมต่อ long-polling
สำหรับการทดสอบแต่ละครั้ง แนะนำให้สร้าง สถานะที่แยกออกมา ใช้ beforeEach เพื่อโหลดแอปพลิเคชันใหม่ผ่าน device.reloadReactNative() สำหรับการทดสอบที่ต้องการข้อมูลเฉพาะ ให้สร้างโรงงานหรือไคลเอ็นต์ API เพื่อเตรียมข้อมูลบนเซิร์ฟเวอร์ หลีกเลี่ยงการพึ่งพาระหว่างการทดสอบ — แต่ละการทดสอบควรเป็นอิสระ
Detox รองรับการทดสอบ WebView ผ่านเมธอด web.element() และ web.invoke() สำหรับการโต้ตอบกับองค์ประกอบเว็บ จะใช้ by.web](:id, css หรือ className สิ่งสำคัญที่ต้องจำคือ WebView ต้องใช้เวลาโหลดเพิ่มเติม — หากการซิงโครไนซ์ไม่ทำงาน ให้เพิ่มการรอโหลดโดยใช้ waitFor
// การทดสอบ WebView ใน 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 รองรับการเปรียบเทียบภาพหน้าจอผ่านปลั๊กอิน detox-image-matching ภาพหน้าจอ ช่วยให้คุณตรวจพบการถดถอยทางภาพ: องค์ประกอบที่เคลื่อนที่ สีที่ไม่ถูกต้อง ไอคอนที่หายไป สำหรับภาพหน้าจอที่เสถียร ให้ปิดแอนิเมชันและใช้ขนาดโปรแกรมจำลองที่คงที่
ปัญหาที่พบบ่อยที่สุดของ Detox เกี่ยวข้องกับการซิงโครไนซ์: แอนิเมชันไม่สิ้นสุด คำขอเครือข่ายยาว หรือตัวจับเวลาค้าง การบันทึก ด้วยแฟลก --loglevel trace แสดงให้เห็นว่า Detox กำลังรอทรัพยากรใดอยู่ หาก Detox ค้าง ให้ใช้ device.disableSynchronization() สำหรับบล็อกโค้ดที่มีปัญหา
บนโปรแกรมจำลอง iOS Detox ต้องสร้างแอปพลิเคชันก่อนผ่าน xcodebuild ด้วยการกำหนดค่า iphonesimulator ข้อผิดพลาดที่พบบ่อยคือการใช้สคีมา Release แทน Debug ซึ่งจะปิดแฟลกทดสอบ สำหรับ Android ตรวจสอบให้แน่ใจว่า AVD ถูกสร้างด้วย API ที่เข้ากันได้กับแอปพลิเคชันของคุณและเปิดใช้งานการเร่ง Intel HAXM แล้ว สำหรับสภาพแวดล้อม CI บน macOS สะดวกในการใช้ GitHub Actions กับรันเนอร์ macOS ซึ่ง Xcode และโปรแกรมจำลองได้รับการติดตั้งไว้ล่วงหน้าแล้ว
หากการทดสอบล้มเหลวเป็นประจำเนื่องจากการหมดเวลา ให้ตรวจสอบ: ปิดการซิงโครไนซ์ทั่วโลกหรือไม่ มีการใช้ setTimeout หรือ setInterval ในโค้ดแอปพลิเคชันโดยไม่มีการล้างข้อมูลหรือไม่ และเธรดหลักถูกบล็อกโดยการดำเนินการที่ยาวนานหรือไม่ บางครั้งการเพิ่มการหมดเวลาใน detoxrc.js ผ่าน testRunner.args.jest.$.testTimeout ช่วยได้ หากต้องการค้นหาพื้นที่ที่มีปัญหา ให้เปิดใช้งานการบันทึกการติดตามของ Detox — มันจะแสดงทรัพยากรและตัวจับเวลาที่เฟรมเวิร์กกำลังรออยู่ในขณะนี้
หลังจากรันการทดสอบ Detox จะสร้างสิ่งประดิษฐ์: ภาพหน้าจอของการทดสอบที่ล้มเหลว บันทึกแอปพลิเคชัน และรายงาน XML JUnit ภาพหน้าจอ จะถูกถ่ายโดยอัตโนมัติเมื่อการทดสอบล้มเหลวและช่วยระบุปัญหาด้วยสายตา สำหรับ CI สิ่งประดิษฐ์จะถูกอัปโหลดไปยังพื้นที่จัดเก็บคลาวด์และพร้อมใช้งานผ่านอินเทอร์เฟซเว็บสำหรับวิเคราะห์สาเหตุของความล้มเหลว
คำถามที่พบบ่อย
Detox ใช้แนวทาง gray-box ที่สามารถเข้าถึง สถานะภายใน ของแอปพลิเคชันและการซิงโครไนซ์อัตโนมัติ Appium ทำงานบนโมเดล black-box ผ่าน WebDriver และต้องการการรอด้วยตนเอง Detox เร็วกว่าและเสถียรกว่าสำหรับโปรเจกต์ React Native
การทดสอบ Detox เขียนด้วย JavaScript หรือ TypeScript เฟรมเวิร์กนี้รวมเข้ากับ Jest และ Mocha ในฐานะตัวรันทดสอบ เอ็นจินเนทีฟสำหรับ iOS เขียนด้วย Swift สำหรับ Android เขียนด้วย Kotlin และ Java
ได้ Detox รองรับแอปพลิเคชันเนทีฟบน iOS (ผ่าน XCTest) และ Android (ผ่าน Espresso) อย่างไรก็ตาม กลุ่มผู้ใช้หลักของ Detox คือนักพัฒนา React Native เนื่องจากมีโซลูชันที่เติบโตเต็มที่กว่าสำหรับโปรเจกต์เนทีฟ
Detox ให้ สิ่งประดิษฐ์: ภาพหน้าจอบันทึกแอปพลิเคชันและรายงาน HTML สำหรับการดีบักในเครื่อง ให้ใช้แฟลก --loglevel trace และสำหรับ CI ให้ใช้ตัวรวบรวมสิ่งประดิษฐ์อัตโนมัติพร้อมอัปโหลดคลาวด์
นี่คือเมธอดของ Detox API ที่โหลดบันเดิล JavaScript ของ React Native ใหม่โดยไม่ต้องติดตั้งแอปพลิเคชันใหม่ ใช้ใน beforeEach เพื่อรีเซ็ตสถานะแอปพลิเคชันไปยังหน้าจอเริ่มต้นก่อนการทดสอบแต่ละครั้ง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม