การทดสอบแบบรีเกรสชันเป็นกระบวนการตรวจสอบแอปพลิเคชันซ้ำหลังจากมีการเปลี่ยนแปลงเพื่อค้นหาข้อบกพร่องในฟังก์ชันการทำงานที่เคยใช้งานได้ การเปลี่ยนแปลงโค้ดแต่ละครั้ง — ฟีเจอร์ใหม่ การแก้ไขบั๊ก หรือการปรับโครงสร้าง — อาจทำให้ความสามารถที่มีอยู่ของแอปพลิเคชันพังโดยไม่ตั้งใจ การทดสอบรีเกรสชันจะทำให้การตรวจสอบว่าฟังก์ชันการทำงานเดิมยังคงทำงานได้เป็นไปโดยอัตโนมัติ จากการศึกษาของ IBM, 2023 การทดสอบรีเกรสชัน ครอบคลุม 30 ถึง 70% ของการทดสอบทั้งหมดที่ดำเนินการในทีมผลิตภัณฑ์เชิงพาณิชย์ ซึ่งเน้นย้ำถึงบทบาทของมันในฐานะอุปสรรคหลักต่อเหตุการณ์ในการผลิต
ประเด็นสำคัญ
การทดสอบรีเกรสชัน เป็นการทดสอบประเภทหนึ่งที่มีวัตถุประสงค์เพื่อยืนยันว่าการเปลี่ยนแปลงโค้ดไม่ได้ทำลายฟังก์ชันการทำงานที่มีอยู่ คำว่า “รีเกรสชัน” หมายถึงการกลับสู่สถานะที่แย่ลง — เมื่อฟังก์ชันที่ทำงานในเวอร์ชันก่อนหน้าหยุดทำงานในเวอร์ชันใหม่ การทดสอบรีเกรสชันจะดำเนินการซ้ำๆ ในแต่ละรอบการพัฒนา ซึ่งแตกต่างจากการทดสอบฟีเจอร์ใหม่ที่เขียนเพียงครั้งเดียว
ความจำเป็นของการทดสอบรีเกรสชันเกิดจากผลกระทบของ การเปลี่ยนแปลงแบบลูกโซ่: การแก้ไขบั๊กในโมดูลหนึ่งอาจแก้ไขปัญหาได้ แต่ทำลายฟังก์ชันการทำงานที่อยู่ติดกันซึ่งขึ้นอยู่กับมัน ตัวอย่างเช่น การเปลี่ยนคำสั่ง SQL ในพื้นที่เก็บผู้ใช้อาจทำให้การตรวจสอบสิทธิ์เร็วขึ้น แต่ทำลายการส่งออกข้อมูลที่ใช้คำสั่งเดียวกัน การทดสอบรีเกรสชันในการส่งออกข้อมูลจะตรวจพบการละเมิดนี้ก่อนการเผยแพร่
ตามรายงานของ CISQ 2023 ค่าใช้จ่ายในการแก้ไขข้อบกพร่องแบบรีเกรสชันที่พบในระบบการผลิตสูงกว่าถึง 15 เท่าเมื่อเทียบกับขั้นตอนการรันรีเกรสชันอัตโนมัติ บริษัทที่ลงทุนในการทดสอบรีเกรสชันอัตโนมัติจะลดสัดส่วนของข้อบกพร่องรีเกรสชันในการเผยแพร่จาก 25% เหลือ 5% ภายในหนึ่งปีหลังจากการนำไปใช้ ตามรายงาน Capgemini World Quality Report
มีวิธีการหลายวิธีในการทดสอบรีเกรสชันที่แตกต่างกันในขอบเขตและเกณฑ์การเลือกทดสอบ การเลือกวิธีการ ขึ้นอยู่กับขนาดของโปรเจกต์ ความถี่ของการเปลี่ยนแปลง และเวลาที่มีในไปป์ไลน์ CI ด้านล่างนี้เป็นประเภทหลักของการทดสอบรีเกรสชันพร้อมคุณลักษณะของมัน
การรันรีเกรสชันแบบเต็ม ดำเนินการทดสอบอัตโนมัติทั้งหมดของโปรเจกต์โดยไม่มีข้อยกเว้น วิธีการนี้ให้ความมั่นใจสูงสุด แต่ต้องการทรัพยากรการคำนวณและเวลาอย่างมาก การรันแบบเต็มจะดำเนินการก่อนการเผยแพร่ครั้งใหญ่ — ทุก 2–4 สัปดาห์ สำหรับแอปพลิเคชันที่มี 5,000 การทดสอบ การรันแบบเต็มใช้เวลา 2 ถึง 6 ชั่วโมงขึ้นอยู่กับโครงสร้างพื้นฐาน
วิธีการแบบเลือกสรร จะรันเฉพาะการทดสอบที่เกี่ยวข้องกับโมดูลที่เปลี่ยนแปลงเท่านั้น เพื่อกำหนดความเกี่ยวข้อง จะใช้การวิเคราะห์การพึ่งพาในระดับโค้ด: หากคลาส UserRepository ถูกเปลี่ยนแปลง การทดสอบที่ขึ้นอยู่กับ UserRepository โดยตรงหรือโดยอ้อมจะถูกดำเนินการ เครื่องมืออย่าง Jacoco, Android Test Coverage และ Xcode Code Coverage ให้แผนที่การครอบคลุมสำหรับการเลือกที่แม่นยำ การรันแบบเลือกสรรจะดำเนินการในทุก pull request และใช้เวลา 5–15 นาที
รีเกรสชันตามความเสี่ยง จะจัดลำดับการทดสอบตามความสำคัญของฟังก์ชันและโอกาสที่จะเสียหาย ฟังก์ชันที่สำคัญ — การชำระเงิน การตรวจสอบสิทธิ์ การซิงโครไนซ์ — จะถูกทดสอบทุกครั้งที่มีการเปลี่ยนแปลงโค้ด ฟังก์ชันเสริม — หน้าจอ “เกี่ยวกับ” อนิเมชัน — จะถูกทดสอบก่อนการเผยแพร่เท่านั้น การจัดลำดับจะถูกทบทวนทุกไตรมาสตามข้อมูลเหตุการณ์ในการผลิต
แนวคิดของการทดสอบรีเกรสชันและการทดสอบซ้ำมักจะสับสน แม้ว่าจะเป็นกระบวนการที่แตกต่างกัน การทดสอบซ้ำ คือการรันการทดสอบเฉพาะที่เคยล้มเหลวก่อนหน้านี้ซ้ำ หลังจากแก้ไขข้อบกพร่องแล้ว จุดประสงค์ของการทดสอบซ้ำคือเพื่อยืนยันว่าการแก้ไขทำงาน: บั๊กไม่เกิดขึ้นอีก การทดสอบซ้ำจะดำเนินการหนึ่งครั้ง ทันทีหลังจากการแก้ไขและการยืนยันการแก้ไขโดยนักพัฒนา
การทดสอบรีเกรสชัน คือการรันการทดสอบบนฟังก์ชันการทำงานที่มีอยู่ซึ่งไม่ได้ถูกเปลี่ยนแปลง เป้าหมายคือเพื่อให้แน่ใจว่าการแก้ไขข้อบกพร่องหนึ่งไม่ได้สร้างข้อบกพร่องใหม่ในที่อื่น การทดสอบรีเกรสชันจะถูกดำเนินการซ้ำๆ ในแต่ละรอบการพัฒนา โดยไม่คำนึงถึงว่าบั๊กใดถูกแก้ไข ความแตกต่างหลัก: การทดสอบซ้ำตรวจสอบการแก้ไข รีเกรสชันตรวจสอบผลที่ตามมาของการแก้ไข
ในไปป์ไลน์ CI/CD ทั้งสองกระบวนการจะดำเนินการตามลำดับ หลังจากรวม pull request แล้ว การทดสอบซ้ำของบั๊กเฉพาะจะถูกดำเนินการ ตามด้วยการรันรีเกรสชันแบบเต็มหรือแบบเลือกสรร ตามข้อมูลของ SmartBear (2022) การแยกกระบวนการเหล่านี้ช่วยลดเวลาในการวินิจฉัยการรัน CI ที่ล้มเหลวลง 30% เนื่องจากทีมเห็นทันทีว่าข้อบกพร่องใดเกี่ยวข้องกับรีเกรสชันและข้อบกพร่องใดเกี่ยวข้องกับการแก้ไขที่ใช้ไม่ได้
ระบบอัตโนมัติของการทดสอบรีเกรสชันเป็นปัจจัยสำคัญต่อความสำเร็จสำหรับโปรเจกต์มือถือสมัยใหม่ การทดสอบรีเกรสชันด้วยตนเอง ไม่สามารถปรับขนาดได้: ด้วยชุดทดสอบ 200 รายการ การรันหนึ่งครั้งต้องใช้เวลา 2–3 วันทำการของวิศวกร QA ทำให้การรันทุกวันเป็นไปไม่ได้ การทดสอบรีเกรสชันอัตโนมัติจะทำงานใน 10–60 นาทีโดยไม่ต้องมีมนุษย์เกี่ยวข้อง ทำให้สามารถดำเนินการได้ในทุก commit หรือ pull request
เพื่อให้ชุดรีเกรสชันเป็นปัจจุบัน การวิเคราะห์การทดสอบ จะถูกใช้: เครื่องมืออย่าง Allure, ReportPortal และ Xray จะติดตามอัตราผ่าน ระยะเวลา และความเสถียรของการทดสอบแต่ละรายการ การทดสอบที่มีความเสถียรต่ำกว่า 90% (มักจะเสียหายเนื่องจากข้อกำหนดที่เปลี่ยนแปลง) จะถูกทำเครื่องหมายเป็นมรดกตกทอดและมอบหมายให้เจ้าของตรวจสอบ
มาดูการตั้งค่าการทดสอบรีเกรสชันอัตโนมัติบน Android โดยใช้ไลบรารี JUnit 5 และ Espresso ตัวอย่างแสดงให้เห็นการรีเกรสชันแบบเลือกสรร — การทดสอบตรวจสอบว่าหลังจากการปรับโครงสร้างพื้นที่เก็บผู้ใช้ หน้าจอโปรไฟล์ไม่เสียหาย สำหรับ iOS จะใช้ XCTest ด้วยตรรกะที่คล้ายกัน — การทดสอบซ้ำในสถานการณ์หลัก
การทดสอบใช้ MockWebServer เพื่อจำลองเซิร์ฟเวอร์และตรวจสอบเส้นทางแบบเต็ม: การโหลดข้อมูลผู้ใช้ การแสดงบนหน้าจอโปรไฟล์ และการจัดการข้อผิดพลาดเมื่อเซิร์ฟเวอร์ไม่พร้อมใช้งาน การทดสอบดังกล่าวจะรวมอยู่ในชุดรีเกรสชันและดำเนินการทุกครั้งที่มีการเปลี่ยนแปลงใน module-profile
@RunWith(AndroidJUnit4::class)
class ProfileRegressionTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun profileScreen_rendersCorrectly() {
val user = User(id = 1, name = "Alice", email = "alice@test.com")
composeRule.setContent {
ProfileScreen(user)
}
composeRule.onNodeWithText("Alice").assertIsDisplayed()
composeRule.onNodeWithText("alice@test.com").assertIsDisplayed()
}
@Test
fun profileScreen_handlesNetworkError() {
setNetworkError()
composeRule.onNodeWithText("ข้อผิดพลาดในการโหลด").assertIsDisplayed()
}
}
สำหรับ iOS การทดสอบรีเกรสชันใช้ XCTestExpectation สำหรับการตรวจสอบการอัปเดต UI แบบอะซิงโครนัสหลังจากได้รับข้อมูลจาก API การทดสอบจำลองการตอบสนองของเครือข่ายและตรวจสอบว่าองค์ประกอบ UI อัปเดตอย่างถูกต้อง
class ProfileRegressionTests: XCTestCase {
func testProfileScreen_rendersCorrectly() {
let viewModel = ProfileViewModel(userId: 1)
let view = ProfileView(viewModel: viewModel)
viewModel.loadProfile()
let expectation = expectation(description: "profile loaded")
viewModel.onProfileLoaded = {
XCTAssertEqual(viewModel.userName, "Alice")
XCTAssertEqual(viewModel.userEmail, "alice@test.com")
expectation.fulfill()
}
waitForExpectations(timeout: 3.0)
}
}
การสร้างชุดรีเกรสชันที่มีประสิทธิภาพเป็นกระบวนการทำซ้ำซึ่งอ้างอิงจากข้อมูลข้อบกพร่องและการเปลี่ยนแปลงโค้ด กลยุทธ์เริ่มต้น คือรวมการทดสอบที่มีอยู่ทั้งหมดในชุดรีเกรสชันและรันแบบเต็มก่อนการเผยแพร่แต่ละครั้ง เมื่อฐานการทดสอบเติบโตขึ้น (มากกว่า 2000 การทดสอบ) การรันแบบเต็มจะยาวเกินไปและจำเป็นต้องใช้วิธีการแบบเลือกสรร
ระยะที่สอง — การนำเครื่องมือวิเคราะห์การพึ่งพามาใช้: Jacoco สำหรับ Android, Xcode Test Plan สำหรับ iOS เครื่องมือเหล่านี้สร้างแผนที่ “การทดสอบ — คลาส — วิธีการ” และช่วยให้สามารถระบุได้ว่าการทดสอบใดได้รับผลกระทบจากการเปลี่ยนแปลงเฉพาะ Spotify Engineering (2022) ระบุว่าการรันแบบเลือกสรรโดยอิงจากการวิเคราะห์การครอบคลุมช่วยลดเวลาในการดำเนินการลง 60–80% ในขณะที่คงประสิทธิภาพการตรวจจับรีเกรสชันไว้ที่ 95%
ระยะที่สาม — การติดตามและปรับให้เหมาะสมอย่างต่อเนื่อง การทดสอบที่ไม่ล้มเหลวเป็นเวลา 6 เดือนจะถูกย้ายไปยังชุดลำดับความสำคัญต่ำ การทดสอบที่ล้มเหลวมากกว่าเดือนละครั้งเป็นผู้สมัครสำหรับการตรวจสอบ: ไม่ว่าจะเป็นการจับปัญหาจริง (ต้องการการแก้ไข) หรือเปราะบางเกินไป (ต้องการการรักษาเสถียรภาพ) การตรวจสอบชุดรีเกรสชันทุกไตรมาสเป็นแนวทางปฏิบัติมาตรฐานเพื่อรักษาประสิทธิภาพและความเร็วในการดำเนินการ
คำถามที่พบบ่อย
การรันรีเกรสชันแบบเลือกสรร — ทุก pull request การรันรีเกรสชันแบบเต็ม — ก่อนการเผยแพร่แต่ละครั้งและทุกสัปดาห์ (nightly build) กฎสำคัญ: ยิ่งรันบ่อยเท่าไหร่ ก็ยิ่งตรวจพบรีเกรสชันได้เร็วเท่านั้น และค่าใช้จ่ายในการแก้ไขก็จะ越低ลง สำหรับโปรเจกต์ที่สำคัญ สามารถทำรีเกรสชันแบบเต็มทุกครั้งที่มีการรวมโค้ด
การทดสอบหน่วยทั้งหมด (รีเกรสชันพื้นฐาน) การทดสอบการผสานรวมบนส่วนประกอบหลัก และการทดสอบ UI ในสถานการณ์ผู้ใช้ที่สำคัญ ไม่รวม การทดสอบสำหรับฟังก์ชันทดลอง การทดสอบที่มีความไม่เสถียร (flakiness) สูงกว่า 10% และการทดสอบที่ต้องการสภาพแวดล้อมแบบ manual
ลบการทดสอบสำหรับฟังก์ชันที่ถูกลบออก อัปเดตการทดสอบเมื่อข้อกำหนดเปลี่ยนแปลง ตรวจสอบชุดทดสอบทุกไตรมาส การวิเคราะห์ CI — Allure, ReportPortal — ช่วยระบุการทดสอบที่สูญเสียความเกี่ยวข้อง: หากการทดสอบไม่เปลี่ยนแปลงหรือไม่ล้มเหลวเป็นเวลา 3 เดือน แสดงว่าเป็นผู้สมัครที่จะถูกลบออกจากการรันประจำวัน
ใช้การดำเนินการทดสอบแบบขนานบนอุปกรณ์หลายเครื่อง ใช้รีเกรสชันแบบเลือกสรรโดยอิงจากการวิเคราะห์การครอบคลุมของโค้ดที่เปลี่ยนแปลง ปิดการจับภาพหน้าจอสำหรับหน้าจอที่ไม่เกี่ยวข้อง เวลาเป้าหมาย สำหรับการรันแบบเลือกสรร: 5–10 นาที สำหรับการรันแบบเต็ม: ไม่เกิน 2 ชั่วโมง
ไม่ การทดสอบรีเกรสชันยังรวมถึงการตรวจสอบด้วยตนเอง: การทดสอบเชิงสำรวจหลังการเผยแพร่ รีเกรสชัน UX และการตรวจสอบการเข้าถึงหลังการเปลี่ยนแปลงอินเทอร์เฟซ ระบบอัตโนมัติครอบคลุม 70–80% ของการตรวจสอบรีเกรสชัน ส่วนที่เหลือ 20–30% เป็นแบบ manual โดยเน้นที่สถานการณ์ที่ไม่สามารถหรือมีค่าใช้จ่ายสูงเกินไปในการทำให้เป็นอัตโนมัติ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม