TDD: คืออะไร หลักการทดสอบ และระเบียบวิธี

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-04-09 เวลาอ่าน: 9 นาที

Test-Driven Development (TDD) คือระเบียบวิธีการพัฒนาที่เขียนเทสก่อนการimplement โค้ด นักพัฒนาจะกำหนดพฤติกรรมที่คาดหวังในรูปแบบของเทสที่ล้มเหลวก่อน จากนั้นเขียนโค้ดขั้นต่ำเพื่อให้ผ่านเทส และหลังจากนั้นปรับโครงสร้างผลลัพธ์ ตามที่ Martin Fowler (2023) กล่าว TDD ไม่ใช่เทคนิคการทดสอบ — มันเป็นเทคนิคการออกแบบที่ทำให้สถาปัตยกรรมมีวินัยและลดจำนวนข้อบกพร่องในขั้นตอนการเขียนโค้ด

ประเด็นสำคัญ

  • TDD คือระเบียบวิธีที่เขียนเทสก่อนการimplement ไม่ใช่หลังจากนั้น
  • วงจร Red-Green-Refactor คือพื้นฐานของ TDD: เทสแดง เทสเขียว การปรับโครงสร้าง
  • JUnit และ Mockito เป็นเครื่องมือหลักสำหรับ TDD ในการพัฒนา Android
  • ความครอบคลุมโค้ด ในโปรเจกต์ TDD มักเกิน 90% เนื่องจากวินัย “เทสก่อน”
  • การปรับโครงสร้าง โดยไม่ต้องกลัวว่าจะทำให้ฟังก์ชันพัง — ข้อได้เปรียบหลักของแนวทาง TDD

TDD คืออะไร?

Test-Driven Development คือแนวปฏิบัติการพัฒนาซอฟต์แวร์ที่เทสอัตโนมัติกำหนดการเขียนโค้ดโปรดักชัน ต่างจากแนวทางดั้งเดิมที่เขียนโค้ดแล้วทดสอบ TDD กลับลำดับ: เขียนเทสก่อน จากนั้นเขียนโค้ดที่ผ่านเทสนั้น

ผู้ก่อตั้ง TDD คือ Kent Beck ซึ่งกำหนดแนวปฏิบัตินี้ขึ้นในช่วงปลายทศวรรษ 1990 ซึ่งเป็นส่วนหนึ่งของระเบียบวิธี Extreme Programming (XP) ในหนังสือ “Test-Driven Development: By Example” (2002) เบคได้อธิบายกฎห้าข้อของ TDD ที่กลายเป็นมาตรฐาน: เขียนเทสก่อนโค้ดโปรดักชัน เขียนโค้ดเท่าที่จำเป็นเพื่อให้ผ่านเทส และปรับโครงสร้างหลังจากแต่ละรอบ

หลักการสำคัญของ TDD

หลักการแรก — เทสกำหนดอินเทอร์เฟซ นักพัฒนาถูกบังคับให้คิดว่าคอมโพเนนต์จะถูกใช้อย่างไรก่อนที่จะคิดว่ามันถูกimplement อย่างไร สิ่งนี้สร้าง API ที่สะอาดตั้งแต่เริ่มต้น

TDD ในฐานะเทคนิคการออกแบบ

หลักการที่สอง — การimplement ขั้นต่ำ เมื่อเขียนเทสแล้ว นักพัฒนาจะเขียนโค้ดโปรดักชันเท่าที่จำเป็นเพื่อให้ผ่านเทส — ไม่เกินแม้แต่บรรทัดเดียว สิ่งนี้ป้องกันการสร้างนามธรรมก่อนเวลาอันควรและความซับซ้อนที่มากเกินไป ซึ่ง Martin Fowler เรียกว่า Speculative Generality

ความแตกต่างระหว่าง TDD กับการทดสอบทั่วไป

ความแตกต่างหลักระหว่าง TDD กับการทดสอบ “ทีหลัง” — วินัยของลำดับ ใน TDD เทสไม่เพียงตรวจสอบโค้ด — แต่มันนำทางโครงสร้างของโค้ด ตามการศึกษาของ Microsoft Research (Nagappan et al., 2008) ทีมที่ใช้ TDD แสดงความหนาแน่นของข้อบกพร่องลดลง 40–90% เมื่อเทียบกับทีมที่ใช้แนวทางดั้งเดิม

วงจร Red-Green-Refactor

วงจร Red-Green-Refactor คือลำดับสามขั้นตอนที่ทำซ้ำสำหรับแต่ละเทสใหม่ Red: เขียนเทสที่ไม่ผ่าน Green: เขียนโค้ดขั้นต่ำเพื่อให้เทสผ่าน Refactor: ปรับปรุงโค้ดโดยไม่เปลี่ยนพฤติกรรม

ขั้นตอน Red: การเขียนเทสที่ล้มเหลว

นักพัฒนาเขียนเทสที่ตรวจสอบฟังก์ชันการทำงานที่ยังไม่ได้implement ในขั้นตอนนี้ เทสต้อง ล้มเหลว — สิ่งนี้ยืนยันว่าเทสกำลังตรวจสอบบางสิ่งจริงๆ ในสภาพแวดล้อมการพัฒนา Android เฟรมเวิร์ก JUnit 5 จะแสดงตัวบ่งชี้สีแดงสำหรับเทสที่ล้มเหลว ซึ่งเป็นที่มาของชื่อขั้นตอนนี้

kotlin
class CalculatorTest {
    fun testAddition() {
        val result = Calculator().add(2, 3)
        Assertions.assertEquals(5, result)
    }
}

ขั้นตอน Green: การimplement ขั้นต่ำ

ในขั้นตอนนี้ จะเขียนโค้ดโปรดักชันขั้นต่ำที่เพียงพอสำหรับการผ่านเทส ไม่มีความซ้ำซ้อน — เฉพาะสิ่งที่จำเป็นสำหรับตัวบ่งชี้สีเขียว หากการimplement สามารถเป็นค่าคงที่ ก็ให้เป็นค่าคงที่ การปรับโครงสร้างจะเกิดขึ้นในขั้นตอนถัดไปเมื่อมีเทสใหม่ปรากฏขึ้น

kotlin
class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}

ขั้นตอน Refactor: การปรับปรุงโดยไม่มีความเสี่ยง

เทสสีเขียวคือประกันสำหรับ การปรับโครงสร้าง นักพัฒนาสามารถเขียนการimplement ใหม่ ปรับประสิทธิภาพให้เหมาะสม หรือปรับปรุงความอ่านง่าย โดยมั่นใจว่าเทสจะตรวจจับความเบี่ยงเบนจากพฤติกรรมที่คาดหวังได้ทันที ในการพัฒนา Android โมบาย ขั้นตอนนี้สำคัญเป็นพิเศษสำหรับการแยกอินเทอร์เฟซร่วมและลดความซ้ำซ้อนของโค้ด

ข้อดีของ TDD ในการพัฒนาโมบาย

การนำ TDD ไปใช้ในโปรเจกต์โมบายให้ข้อดีที่วัดผลได้ ซึ่งได้รับการยืนยันทั้งจากการวิจัยทางวิชาการและการปฏิบัติของสตูดิโอพัฒนาชั้นนำ

การลดความหนาแน่นของข้อบกพร่อง

การศึกษา IBM (Bhat & Nagappan, 2006) ในสี่โปรเจกต์อุตสาหกรรมแสดงให้เห็นว่าทีมที่ใช้ TDD สร้าง ข้อบกพร่องน้อยกว่า 40% เมื่อเทียบกับทีมที่คล้ายกันซึ่งทำงานด้วยแนวทางดั้งเดิม สำหรับการพัฒนาโมบาย ที่ค่าใช้จ่ายในการแก้ไขบั๊กหลังเผยแพร่บน Google Play สูงกว่าอย่างมีนัยสำคัญเมื่อเทียบกับขั้นตอนการเขียนโค้ด เมตริกนี้มีความสำคัญอย่างยิ่ง

การจัดทำเอกสารโค้ดผ่านเทส

เทสที่เขียนด้วย TDD ทำหน้าที่เป็น เอกสารที่มีชีวิต ของ API นักพัฒนาที่เข้ามาในโปรเจกต์สามารถอ่านเทสและเข้าใจว่าควรใช้แต่ละคอมโพเนนต์อย่างไร สิ่งนี้มีค่าโดยเฉพาะในสภาวะที่ทีมมีการเปลี่ยนแปลงสูง — ปัญหาทั่วไปของสตูดิโอโมบาย

การปรับโครงสร้างอย่างมั่นใจ

ความครอบคลุมโค้ดที่เกิน 90% ช่วยให้นักพัฒนาสามารถปรับโครงสร้างได้โดยไม่ต้องกลัวว่าจะทำอะไรพัง Google ในหนังสือ “Software Engineering at Google” (2020) เรียกความครอบคลุมเทสว่าปัจจัยสำคัญที่ช่วยให้รักษาโค้ดเบสให้สะอาดในโปรเจกต์ที่มีโค้ดหลายล้านบรรทัด

เครื่องมือและเฟรมเวิร์กสำหรับ TDD

ระบบนิเวศ TDD ในการพัฒนาโมบายมีเครื่องมือสำหรับการทดสอบหน่วย การสร้าง mock และการตรวจสอบคอมโพเนนต์ UI — ทั้งสำหรับ Android และ iOS

เครื่องมือแพลตฟอร์มวัตถุประสงค์
JUnit 5Android (Kotlin/Java)เฟรมเวิร์กพื้นฐานสำหรับการทดสอบหน่วย
MockitoAndroidสร้างออบเจกต์ mock และตรวจสอบการเรียก
MockKAndroid (Kotlin)Mocking ด้วยไวยากรณ์ Kotlin-first และรองรับ coroutine
TurbineAndroidทดสอบ Kotlin Flow และสตรีมเชิงปฏิกิริยา
XCTestiOS (Swift)เฟรมเวิร์กการทดสอบมาตรฐาน

การเลือกเฟรมเวิร์กสำหรับ Android

สำหรับโปรเจกต์ Android บน Kotlin สแต็กมาตรฐานประกอบด้วย JUnit 5 + MockK MockK ดีกว่า Mockito เพราะรองรับฟีเจอร์ระดับแรกของ Kotlin — sealed class, coroutine และ suspend function — โดยไม่ต้องตั้งค่าเพิ่มเติม

เครื่องมือสำหรับ iOS

ในการพัฒนา iOS TDD ถูกimplement ผ่าน XCTest — เฟรมเวิร์กในตัวของ Apple ที่ให้ assertions, คลาสเทส และการรวม CI/CD ผ่าน Xcode Server หรือ GitHub Actions สำหรับ mocking บน iOS ใช้ไลบรารี Cuckoo และ OHHTTPStubs

ตัวอย่างโค้ดกับ TDD ใน Kotlin

มาดูสถานการณ์จริงของ TDD ใน Kotlin สำหรับ Android — การทดสอบ repository ผู้ใช้ ขั้นแรกเราเขียนเทส จากนั้น implement ที่ผ่านเทสนั้น

ขั้นตอนที่ 1: เทสสำหรับ UserRepository

kotlin
class UserRepositoryTest {
    private val api = mockk<UserApi>()
    private val dao = mockk<UserDao>()
    private val repo = UserRepository(api, dao)

    fun `when api returns user then cache and emit`() = runTest {
        val user = User(1, "Alice")
        coEvery { api.getUser(1) } returns user
        every { dao.insert(user) } returns Unit

        val result = repo.getUser(1)

        assertEquals(user, result)
        verify { dao.insert(user) }
    }
}

ขั้นตอนที่ 2: การimplement ขั้นต่ำ

kotlin
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUser(id: Int): User {
        val user = api.getUser(id)
        dao.insert(user)
        return user
    }
}

ขั้นตอนที่ 3: เทสสำหรับแคชกับโหมดออฟไลน์

หลังจากผ่านเทสแรก เราเพิ่มเทสที่สอง — ตรวจสอบพฤติกรรมเมื่อเกิด ข้อผิดพลาดเครือข่าย ตอนนี้เทสกำหนดว่าเมื่อ API ล้มเหลว repository ควรส่งคืนข้อมูลจากแคช

kotlin
fun `when api fails then return cached user`() = runTest {
    val cached = User(1, "Cached Alice")
    coEvery { api.getUser(1) } throws IOException()
    every { dao.getById(1) } returns cached

    val result = repo.getUser(1)

    assertEquals(cached, result)
}

ข้อผิดพลาดทั่วไปเมื่อนำ TDD ไปใช้

การเปลี่ยนไปใช้ TDD มาพร้อมกับข้อผิดพลาดทั่วไปที่สามารถลบล้างข้อดีทั้งหมดของระเบียบวิธี การเข้าใจกับดักเหล่านี้ช่วยให้ทีมนำแนวปฏิบัติไปใช้ได้อย่างมีประสิทธิภาพมากขึ้น

เทสที่ใหญ่เกินไป

รูปแบบต้านแรกและพบบ่อยที่สุด — การทดสอบฟังก์ชันการทำงานที่มากเกินไป ในเทสเดียว เทสควรตรวจสอบเพียงหนึ่งการยืนยัน หากเทสล้มเหลว นักพัฒนาควรรู้ทันทีว่าอะไรพังโดยไม่ต้องดีบักเพิ่มเติม

การละเลยขั้นตอนแดง

ข้อผิดพลาดที่สอง — การเขียนเทสที่ผ่านตั้งแต่แรก หากเทสไม่เคยเป็นสีแดงแม้แต่ครั้งเดียว ก็ไม่มีความมั่นใจว่ามันกำลังตรวจสอบบางสิ่งจริงๆ กฎ: อย่าเชื่อถือเทสที่คุณไม่เคยเห็นมันล้มเหลว

การข้ามการปรับโครงสร้าง

ข้อผิดพลาดทั่วไปที่สาม — การหยุดที่ขั้นตอนเขียว การปรับโครงสร้าง ไม่ใช่ทางเลือก แต่เป็นขั้นตอนบังคับของวงจร หากไม่มีมัน โค้ดเบสจะเสื่อมลง เทสจะเปราะบาง และข้อดีของ TDD จะสูญหายไป

  • การทดสอบการimplement แทนพฤติกรรม — เทสผูกติดกับรายละเอียดและพังทุกครั้งที่มีการปรับโครงสร้าง
  • ขาดเทสสำหรับกรณีขอบ — รายการว่าง ค่า null เงื่อนไขขอบเขตไม่ถูกครอบคลุม
  • การละเลยความเร็วของเทส — เทสที่ช้าทำให้วงจรตอบรับช้าลงและทำลายวินัย TDD

คำถามที่พบบ่อย

TDD เป็นเทคนิคการทดสอบหรือการออกแบบ?

TDD เป็นเทคนิคการออกแบบเป็นหลัก ไม่ใช่เทคนิคการทดสอบ เทสใน TDD มีบทบาทเป็นข้อกำหนด: มันกำหนด API ของคอมโพเนนต์ก่อนการimplement Kent Beck เองเรียก TDD ว่า “เป็นวินัยของการออกแบบ ไม่ใช่การทดสอบ”

ต้องใช้เวลานานแค่ไหนในการฝึกฝน TDD?

ตามการศึกษาของ Microsoft Research ทีมต้องใช้เวลา 3 ถึง 6 เดือนของการปฏิบัติอย่างต่อเนื่องเพื่อให้ TDD กลายเป็นนิสัย 2–3 สัปดาห์แรก ประสิทธิภาพลดลง 15–30% แต่หลังจากการปรับตัว มันกลับมาที่ระดับเดิมหรือเกินกว่าเนื่องจากเวลาในการดีบักที่ลดลง

TDD เหมาะกับคอมโพเนนต์ UI หรือไม่?

ใช่ แต่มีข้อจำกัด สำหรับ ตรรกะ UI (ViewModel, State) TDD สามารถใช้ได้โดยตรง สำหรับคอมโพเนนต์ภาพ (Compose UI, SwiftUI Views) การทดสอบภาพจับ (snapshot testing) เสริม TDD แต่ไม่ได้แทนที่ แนะนำให้แยกตรรกะธุรกิจออกจากการแสดงผล

สามารถใช้ TDD ในโปรเจกต์เดิมได้หรือไม่?

สำหรับ โค้ดเดิม แนะนำกลยุทธ์ “เทสลักษณะเฉพาะ” (characterization tests) — ที่เขียนเทสบนพฤติกรรมที่มีอยู่ จากนั้นปรับโครงสร้างโค้ด แนวทางนี้อธิบายไว้ในหนังสือของ Michael Feathers “Working Effectively with Legacy Code” (2004) และอนุญาตให้นำ TDD ไปใช้แบบทีละขั้น

TDD ทำงานร่วมกับ Clean Architecture อย่างไร?

TDD และ Clean Architecture เสริมสร้างซึ่งกันและกัน สถาปัตยกรรมที่สะอาดต้องการขอบเขตที่ชัดเจนระหว่างเลเยอร์ และ TDD บังคับให้นักพัฒนาออกแบบขอบเขตเหล่านั้นผ่านเทส เลเยอร์โดเมนถูกทดสอบแบบแยกส่วนด้วย dependencies แบบ mock เลเยอร์ข้อมูล — ผ่านเทสการรวมระบบ

สรุป

  • TDD — ระเบียบวิธีที่เขียนเทสก่อนการimplement สร้าง API ที่สะอาดและนำทางสถาปัตยกรรม
  • วงจร Red-Green-Refactor — หน่วยพื้นฐานของ TDD: เทสล้มเหลว → การimplement ขั้นต่ำ → การปรับโครงสร้าง
  • การใช้ TDD ลดความหนาแน่นของข้อบกพร่อง 40–90% ตามการศึกษาของ IBM และ Microsoft Research
  • เครื่องมือหลักสำหรับการพัฒนา Android: JUnit 5, MockK, Turbine สำหรับ Flow
  • MockK ดีกว่า Mockito ในโปรเจกต์ Kotlin เนื่องจากการรองรับ coroutine และ sealed class
  • ข้อผิดพลาดทั่วไป: เทสใหญ่เกินไป ข้ามขั้นตอนแดง ละเลยการปรับโครงสร้าง
  • กลยุทธ์การนำไปใช้ที่แนะนำ — แบบทีละขั้น เริ่มจากเลเยอร์โดเมนและฟีเจอร์ใหม่ โดยไม่พยายามครอบคลุมโค้ดเดิมทั้งหมดในครั้งเดียว

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม