Given-When-Then: คืออะไร โครงสร้างของสถานการณ์และตัวอย่าง

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

Given-When-Then เป็นรูปแบบโครงสร้างสำหรับอธิบายสถานการณ์การทดสอบ ที่ BDD ยืมมาจาก domain-driven design และปรับให้เข้ากับ Behaviour-Driven Development รูปแบบนี้แบ่งสถานการณ์ออกเป็นสามส่วนเชิงตรรกะ: เงื่อนไขเบื้องต้น (Given), การกระทำ (When) และผลลัพธ์ที่คาดหวัง (Then) ตามที่ Martin Fowler (2023) กล่าว Given-When-Then ไม่ใช่แค่รูปแบบการทดสอบ แต่เป็นเครื่องมือทางความคิดที่ทำให้การวิเคราะห์ความต้องการและการออกแบบสถานการณ์เป็นระบบก่อนเริ่มการนำไปใช้

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

  • Given-When-Then — รูปแบบการอธิบายสถานการณ์จากสามบล็อก: บริบท, การกระทำ, ผลลัพธ์
  • Given กำหนดสถานะเริ่มต้นของระบบและข้อมูลก่อนดำเนินการกระทำที่ถูกทดสอบ
  • When อธิบายเหตุการณ์หรือการกระทำที่触发ตรรกะที่ถูกทดสอบ
  • Then ตรวจสอบการเปลี่ยนแปลงสถานะหรือค่าที่ส่งกลับที่คาดหวัง
  • Arrange-Act-Assert — สิ่งที่เทียบเท่ากับ Given-When-Then ในการทดสอบหน่วย แต่ไม่มีการเน้นภาษาทางธุรกิจ

Given-When-Then คืออะไร?

Given-When-Then เป็นรูปแบบการอธิบายพฤติกรรมที่คิดค้นครั้งแรกโดย Dan North ในปี 2006 ซึ่งเป็นส่วนหนึ่งของวิธีการ Behavior-Driven Development รูปแบบนี้แก้ปัญหาการอธิบายสถานการณ์ทดสอบที่ไม่มีโครงสร้าง ซึ่งมักประกอบด้วยเงื่อนไขเบื้องต้น การกระทำ และการตรวจสอบปะปนกันในลำดับตามอำเภอใจ

แนวคิดหลักของรูปแบบคือ การแยกความรับผิดชอบ ระหว่างสามบล็อก แต่ละบล็อกรับผิดชอบเพียงแง่มุมเดียวของสถานการณ์: สถานะก่อน, เหตุการณ์ระหว่าง, และการตรวจสอบหลัง สิ่งนี้ทำให้สถานการณ์สามารถอ่านได้ ตรวจสอบได้ และทำให้เป็นอัตโนมัติได้ จากการศึกษาของผู้พัฒนาเฟรมเวิร์ก Cucumber (2024) สถานการณ์ที่ปฏิบัติตามรูปแบบ Given-When-Then อย่างเคร่งครัดใช้เวลาทำความเข้าใจน้อยลง 42% สำหรับสมาชิกทีมใหม่

ที่มาของรูปแบบ

Dan North ยืมแนวคิดของโครงสร้างสามส่วนมาจาก การกำหนดสูตรการทดสอบใน TDD และวิธีการ Test-by-Example (สร้างโดย Brian Marick) Marick เสนอให้อธิบายความต้องการผ่านตัวอย่าง (examples) ที่ทำหน้าที่เป็นการทดสอบไปพร้อมกัน Given-When-Then ทำให้แนวคิดนี้เป็นทางการ เปลี่ยนตัวอย่างที่ไม่มีโครงสร้างให้เป็นรูปแบบที่ทำซ้ำได้

ขอบเขตการนำไปใช้

รูปแบบ Given-When-Then ไม่เพียงแต่ใช้ในสถานการณ์ BDD ด้วย Gherkin เท่านั้น แต่ยังใช้ในการทดสอบหน่วยทั่วไปด้วย JUnit, XCTest และเฟรมเวิร์กอื่นๆ ความคิดเห็นในโค้ดที่แบ่งการทดสอบออกเป็นสามบล็อกเป็นแนวทางปฏิบัติทั่วไปเพื่อปรับปรุงความสามารถในการอ่านของฐานการทดสอบ Google แนะนำแนวทางนี้ในหนังสือ «Software Engineering at Google» (2020)

โครงสร้างของสามบล็อก

แต่ละบล็อกของ Given-When-Then มีความหมายเชิงความหมายที่กำหนดไว้อย่างเคร่งครัดและกฎการเติมเนื้อหา การละเมิดกฎเหล่านี้จะนำไปสู่สถานการณ์ที่ยากต่อการทำให้เป็นอัตโนมัติหรือเข้าใจ

Given: เงื่อนไขเบื้องต้น

บล็อก Given อธิบายสถานะของระบบก่อนดำเนินการกระทำที่ถูกทดสอบ รวมถึง: ออบเจกต์ที่มีอยู่ (ผู้ใช้, คำสั่งซื้อ, การตั้งค่า), สถานะที่ใช้งานอยู่ (รับรองความถูกต้อง, เชื่อมต่อเครือข่าย) และค่าเริ่มต้นของข้อมูล แต่ละ Given จะต้องสามารถตรวจสอบได้ — หากสถานะของระบบไม่ตรงกับ Given ควรข้ามสถานการณ์นั้นหรือเตรียมสภาพแวดล้อมการทดสอบล่วงหน้า

When: การกระทำ

บล็อก When อธิบายเหตุการณ์เดียวที่เริ่มต้นพฤติกรรมที่ถูกทดสอบ อาจเป็นการเรียกเมธอด, การคลิกปุ่ม, การรับการแจ้งเตือนหรือการตอบสนองจากเซิร์ฟเวอร์ กฎสำคัญคือ หนึ่ง When ต่อหนึ่งสถานการณ์ หากจำเป็นต้องตรวจสอบลำดับของการกระทำ ให้สร้างสถานการณ์แยกต่างหาก ไม่ใช่ห่วงโซ่ของ When

kotlin
// Given: สร้างข้อมูลทดสอบ
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)

// When: ดำเนินการกระทำ
val result = PurchaseUseCase().buy(user, product)

// Then: ตรวจสอบผลลัพธ์
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)

Then: ผลลัพธ์ที่คาดหวัง

บล็อก Then ตรวจสอบว่าระบบได้เปลี่ยนไปสู่สถานะที่คาดหวังแล้ว ซึ่งรวมถึง: ค่าที่ส่งกลับ, การเปลี่ยนแปลงสถานะของออบเจกต์, การเรียกใช้บริการภายนอก (ผ่านการตรวจสอบ mock) และการเปลี่ยนแปลง UI แต่ละบล็อก Then สามารถมีการตรวจสอบหลายรายการ แต่ทั้งหมดเกี่ยวข้องกับการกระทำเดียว

Given-When-Then และ Arrange-Act-Assert

Given-When-Then และ Arrange-Act-Assert (AAA) เป็นสองรูปแบบของรูปแบบสามส่วนเดียวกัน แต่มีกลุ่มเป้าหมายที่แตกต่างกัน การเข้าใจความแตกต่างของพวกเขาช่วยเลือกรูปแบบที่เหมาะสมสำหรับงานแต่ละอย่าง

แง่มุมGiven-When-ThenArrange-Act-Assert
ที่มาBDD, การวิเคราะห์ธุรกิจการทดสอบหน่วย
ภาษาธรรมชาติ (Gherkin)โค้ด (Kotlin, Swift, Java)
กลุ่มเป้าหมายทั้งทีม + ลูกค้านักพัฒนา
ระดับรายละเอียดระดับสูงละเอียด
การทำให้เป็นอัตโนมัติCucumber, SpecFlowJUnit, XCTest, Mockito

เมื่อใดควรใช้ Given-When-Then

รูปแบบ Given-When-Then เหมาะสมที่สุดสำหรับสถานการณ์ที่หารือกับลูกค้าหรือนักวิเคราะห์: เกณฑ์การยอมรับฟีเจอร์, กรณีการใช้งาน, การตรวจสอบการถดถอย ไวยากรณ์ Gherkin ช่วยให้เขียนสถานการณ์เหล่านี้ได้โดยไม่ต้องมีความรู้ด้านการเขียนโปรแกรม

เมื่อใดควรใช้ Arrange-Act-Assert

Arrange-Act-Assert เป็นตัวเลือกธรรมชาติสำหรับการทดสอบหน่วยที่ตรวจสอบเมธอดหรือคลาสเฉพาะ รูปแบบ AAA ไม่ต้องการเฟรมเวิร์กเพิ่มเติมและทำงานในภาษาโปรแกรมใดๆ สำหรับการพัฒนา iOS, Apple แนะนำ AAA ในเอกสาร XCTest (2024)

ตัวอย่างสถานการณ์ใน Kotlin

มาดูตัวอย่างเชิงปฏิบัติของ Given-When-Then ใน Kotlin สำหรับแอปพลิเคชัน Android ตัวอย่างแรกคือการทดสอบตะกร้าสินค้าโดยใช้ MockK ตัวอย่างที่สองคือการทดสอบตรรกะการแจ้งเตือนแบบพุช

ตัวอย่างที่ 1: ตะกร้าสินค้า

kotlin
class CartTest {
    fun `apply discount when total exceeds threshold`() {
        // Given
        val cart = Cart()
        cart.addItem(Item("Laptop", price = 1000.0))
        cart.addItem(Item("Mouse", price = 50.0))
        val discount = DiscountCalculator(0.1)

        // When
        val total = discount.applyIfEligible(cart)

        // Then
        assertEquals(945.0, total)
        assertTrue("Discount was not applied", total < 1050.0)
    }
}

ตัวอย่างที่ 2: การแจ้งเตือนแบบพุชกับ coroutines

ตัวอย่างที่สองสาธิต Given-When-Then กับโค้ดแบบอะซิงโครนัส ที่นี่ Given กำหนดสถานะของ Firebase Cloud Messaging, When — การรับการแจ้งเตือนแบบพุช, Then — การตรวจสอบการประมวลผล

kotlin
class PushNotificationTest {
    fun `handle push notification when app in background`() = runTest {
        // Given
        val prefs = mockk<SharedPreferences>()
        every { prefs.getString("token", null) } returns "fcm-token-abc"
        val handler = PushHandler(prefs)

        // When
        val data = RemoteMessage().apply {
            putData("type", "order_update")
            putData("order_id", "123")
        }
        val result = handler.handleNotification(data)

        // Then
        assertEquals(NotificationAction.OpenOrder("123"), result)
    }
}

ตัวอย่างที่ 3: สถานการณ์ Gherkin สำหรับการตรวจสอบสิทธิ์

ตัวอย่างที่สามคือสถานการณ์ BDD ใน Gherkin ที่แสดง Given-When-Then ในบริบทของการทดสอบการยอมรับ:

gherkin
Feature: User Authorization
  Scenario: User cannot login with expired token
    Given the user has an expired refresh token
    When they try to access the protected profile screen
    Then they should see the login screen
    And the app should clear all cached data

แนวทางปฏิบัติที่ดีที่สุดในการเขียนสถานการณ์

การนำ Given-When-Then ไปใช้อย่างมีประสิทธิภาพต้องปฏิบัติตามแนวทางปฏิบัติที่พิสูจน์แล้วหลายประการ แนวทางเหล่านี้รับประกันความสามารถในการอ่าน การบำรุงรักษา และการทำให้เป็นอัตโนมัติของสถานการณ์

หนึ่ง When ต่อสถานการณ์

กฎที่เข้มงวด: หนึ่งสถานการณ์ — หนึ่งการกระทำ หากจำเป็นต้องตรวจสอบลำดับของหลาย When ให้สร้างหลายสถานการณ์โดยที่ผลลัพธ์ของก่อนหน้ากลายเป็นเงื่อนไขเบื้องต้นของถัดไป สิ่งนี้ทำให้สถานการณ์เป็นอะตอมมิกและเข้าใจได้

หลีกเลี่ยงข้อมูลเฉพาะเจาะจงใน Given

Given ควรอธิบายสาระสำคัญ ไม่ใช่ตัวเลขเฉพาะเจาะจง แทนที่จะเป็น «Given ผู้ใช้ Ivanov มียอดคงเหลือ 500 รูเบิล» — «Given ผู้ใช้มียอดคงเหลือเพียงพอ» ข้อมูลเฉพาะเจาะจงจะถูกย้ายไปยัง Scenario Outline พร้อมตาราง Examples สิ่งนี้ทำให้สถานการณ์เป็นสากลและนำกลับมาใช้ใหม่ได้

  • เขียน Then เป็นคำยืนยันที่วัดผลได้ — «ผู้ใช้ควรเห็นหน้าจอเข้าสู่ระบบ» ไม่ใช่ «ผู้ใช้ควรถูกเปลี่ยนเส้นทาง»
  • ใช้ And สำหรับขั้นตอนประเภทเดียวกัน — หากจำเป็นต้องมี Given หลายรายการ ให้รวมกันผ่าน And อย่าสร้าง Given ที่สอง
  • อย่าผสมระดับนามธรรม — Given-When-Then ควรอยู่ในระดับเดียวกัน: ไม่ว่าจะเป็นระดับธุรกิจหรือระดับเทคนิค แต่ไม่ใช่ปนกัน
  • บันทึกเหตุผลของสถานการณ์ — ความคิดเห็นที่จุดเริ่มต้นของไฟล์ .feature พร้อมคำอธิบายกฎทางธุรกิจช่วยในบริบท

Given-When-Then ในไปป์ไลน์ CI/CD

การรวมสถานการณ์ Given-When-Then เข้ากับไปป์ไลน์การ intégration อย่างต่อเนื่องเปลี่ยนจากเอกสารเป็นการป้องกันการถดถอย คำขอรวมแต่ละครั้งในโปรเจกต์มือถือจะเรียกใช้สถานการณ์ BDD โดยอัตโนมัติและบล็อกการรวมหากมีสถานการณ์อย่างน้อยหนึ่งรายการล้มเหลว

การเรียกใช้สถานการณ์อัตโนมัติ

สถานการณ์ BDD ด้วย Cucumber สำหรับ Android ถูกเรียกใช้ผ่าน งาน Gradle ./gradlew cucumber สำหรับ iOS (Quick/Nimble) — ผ่าน xcodebuild test ในระบบ CI (GitHub Actions, GitLab CI, Bitrise) การทดสอบ BDD จะถูกดำเนินการบนอีมูเลเตอร์หรืออุปกรณ์จริง รายงานถูกสร้างในรูปแบบ HTML ที่ผู้จัดการเข้าใจได้: สถานการณ์สีเขียว — ผ่าน, สีแดง — ล้มเหลวพร้อมระบุขั้นตอน

เอกสารที่มีชีวิตใน repository

ไฟล์ .feature ถูกเก็บไว้ใน repository ข้างโค้ดและผ่าน การตรวจสอบโค้ด นักวิเคราะห์สร้างคำขอรวมกับสถานการณ์ใหม่ก่อนเริ่มการพัฒนา (BDD-first) นักพัฒนาเขียนนิยามขั้นตอนและการนำไปใช้เพื่อทำให้สถานการณ์เหล่านี้เป็นสีเขียว เมื่อสถานการณ์ทั้งหมดผ่าน — ฟังก์ชันการทำงานก็พร้อม แนวทางนี้ อธิบายไว้ในหนังสือของ Gojko Adzic «Specification by Example» (2011) เปลี่ยนความต้องการเป็นสิ่งประดิษฐ์ที่สามารถดำเนินการได้

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

Given-When-Then เหมือนกับ Arrange-Act-Assert หรือไม่?

ในเชิงโครงสร้าง ใช่ มันเป็น รูปแบบสามส่วนเดียวกัน ความแตกต่างอยู่ที่กลุ่มเป้าหมาย: Given-When-Then เน้นภาษาทางธุรกิจและใช้ใน BDD กับ Gherkin ในขณะที่ Arrange-Act-Assert เป็นรูปแบบทางเทคนิคสำหรับการทดสอบหน่วย การเลือกขึ้นอยู่กับบริบทและทีม

บล็อก Then สามารถมีการตรวจสอบได้กี่รายการ?

ไม่มีข้อจำกัด แต่แนะนำให้ ไม่เกิน 3–5 รายการ ต่อหนึ่ง Then หากมีการตรวจสอบมากกว่านั้น สถานการณ์อาจตรวจสอบมากเกินไปในการกระทำเดียว ให้แบ่งออกเป็นหลายสถานการณ์ด้วย Then ที่แตกต่างกัน

จำเป็นต้องเขียน Given-When-Then ใน Gherkin หรือไม่?

ไม่ รูปแบบนี้สามารถใช้ในเฟรมเวิร์กการทดสอบใดๆ ก็ได้ เพียงแบ่งการทดสอบด้วย ความคิดเห็น หรือบรรทัดว่างเป็นสามบล็อก Gherkin จำเป็นก็ต่อเมื่อสถานการณ์ถูกเขียนในรูปแบบไฟล์ .feature สำหรับ Cucumber หรือ SpecFlow

จะจัดการกับเงื่อนไขเบื้องต้นที่ยาวใน Given อย่างไร?

แนะนำให้แยกเงื่อนไขเบื้องต้นที่ซ้ำกันไปไว้ใน Background (Gherkin) หรือเมธอด @Before (JUnit) หากเงื่อนไขเบื้องต้นซับซ้อน ให้ใช้รูปแบบ Builder เพื่อสร้างข้อมูลทดสอบ สิ่งนี้ทำให้ Given สั้นและอ่านง่าย

บล็อก When สามารถว่างได้หรือไม่?

ไม่ When เป็นบล็อกบังคับที่อธิบายการกระทำ หากสถานการณ์ตรวจสอบเฉพาะสถานะโดยไม่มีการกระทำ (เช่น «เมื่อโหลดแอปพลิเคชัน ข้อมูลควรถูกเก็บไว้ในแคช») When อธิบายตัวกระตุ้น: «เมื่อแอปพลิเคชันเริ่มทำงาน»

สรุป

  • Given-When-Then — รูปแบบสามส่วนสำหรับอธิบายสถานการณ์: เงื่อนไขเบื้องต้น, การกระทำ, ผลลัพธ์ที่คาดหวัง
  • Given กำหนดบริบทและสถานะเริ่มต้น, When — การกระทำเดียว, Then — การตรวจสอบผลลัพธ์
  • Arrange-Act-Assert และ Given-When-Then เป็น รูปแบบเดียวกัน ที่มีกลุ่มเป้าหมายและระดับนามธรรมต่างกัน
  • รูปแบบนี้ใช้ใน BDD (Gherkin, Cucumber) และในการทดสอบหน่วยทั่วไป (JUnit, XCTest) ผ่านความคิดเห็น
  • กฎสำคัญ: หนึ่ง When ต่อสถานการณ์ — แต่ละการกระทำต้องตรวจสอบแยกกัน
  • เงื่อนไขเบื้องต้นที่ซ้ำกันถูกแยกไปไว้ใน Background หรือเมธอด @Before เพื่อลดการทำซ้ำ
  • Scenario Outline พร้อมตาราง Examples ช่วยให้กำหนดพารามิเตอร์ Given-When-Then ด้วยชุดข้อมูลต่างๆ โดยไม่ต้องทำซ้ำโค้ด

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

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

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

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