จะใช้การทดสอบหน่วยเมื่อใช้ BDD ได้อย่างไร


17

ฉันพยายามที่จะเข้าใจ BDD ฉันอ่านบทความแล้วและฉันเข้าใจว่า BDD คือ "ขั้นตอนต่อไป" จาก TDD ฉันบอกว่าเพราะฉันพบว่าทั้งคู่มีความคล้ายคลึงกันมากและอย่างที่ฉันสามารถอ่านได้ในบทความนี้ BDD เกิดมาเพื่อปรับปรุงจาก TDD เยี่ยมมากฉันชอบความคิดจริงๆ

มีจุดหนึ่งที่ใช้งานได้จริงที่ฉันไม่ได้รับคิดว่า: มีไฟล์. Feature ซึ่ง BA จะเขียนพฤติกรรมที่คาดหวังไว้ทั้งหมดซึ่งระบบจะมี ในฐานะที่เป็นปริญญาตรีเขาไม่มีความคิดว่าระบบจะสร้างอย่างไรดังนั้นเราจะเขียนดังนี้:

+ สถานการณ์ที่ 1: บัญชีอยู่ในเครดิต +

รับบัญชีเป็นเครดิต

และบัตรถูกต้อง

และตัวจ่ายประกอบด้วยเงินสด

เมื่อลูกค้าขอเงินสด

จากนั้นตรวจสอบให้แน่ใจว่าบัญชีเดบิตและตรวจสอบให้แน่ใจว่าจ่ายเงินสดแล้ว

และให้แน่ใจว่าบัตรจะถูกส่งกลับ

ตกลงนี่เป็นสิ่งที่ดี แต่มีหลายส่วนของระบบที่จะทำงานร่วมกันเพื่อให้สามารถเกิดขึ้นได้ (คิดว่าบัญชี obj, เครื่องจ่าย obj, ลูกค้า obj และอื่น ๆ ) สำหรับฉันนี่ดูเหมือนการทดสอบการรวมเข้าด้วยกัน

ฉันต้องการทดสอบยูนิต ฉันจะทดสอบรหัสที่ตรวจสอบว่าเครื่องจ่ายมีเงินได้อย่างไร หรือว่าเงินสดจ่าย? หรือว่าบัญชีถูกหักบัญชีเมื่อจำเป็น? ฉันจะผสมการทดสอบหน่วยกับการทดสอบ "สร้างโดย BA" ได้อย่างไร


นั่นคือสิ่งที่ mocks และ stubs ใช้สำหรับ: เพื่อแยกชิ้นส่วนภายใต้การทดสอบ
Robert Harvey

ขอโทษฉันไม่เข้าใจ คุณหมายถึงฉันควรเยาะเย้ยตู้? ฉันจะทดสอบได้อย่างไร
JSBach

เมื่อคุณทดสอบเครื่องจ่ายคุณจำลองบัญชีบัตรและลูกค้า
Robert Harvey

3
ทำไมคุณต้องการผสมผสานการทดสอบหน่วยและ "การทดสอบ BA ที่สร้างขึ้น" ใช้ TDD เป็นเทคนิคในการสร้างการทดสอบหน่วยสำหรับแต่ละส่วนของซอฟต์แวร์ของคุณและเพิ่มการทดสอบเพิ่มเติมสำหรับการทดสอบข้อกำหนดจากมุมมองของ BA (เรียกการทดสอบการรวมหลังหากคุณต้องการ) คุณเห็นความขัดแย้งที่ไหน
Doc Brown

@DocBrown: โดย "ธรรมชาติโผล่ออกมา" ฉันหมายความว่า TDD'ers บางคนเชื่อว่าการออกแบบซอฟต์แวร์โดยธรรมชาติจะเกิดขึ้นจากการทดสอบหน่วยในขณะที่คุณ "red-green-refactor" อย่างต่อเนื่องแชทสนทนาเกี่ยวกับคำถามนี้เกิดขึ้นในไวท์บอร์ด
Robert Harvey

คำตอบ:


27

การพัฒนาพฤติกรรมขับเคลื่อนและการทดสอบขับเคลื่อนนั้นเป็นบริการฟรี แต่ไม่สามารถทดแทนซึ่งกันและกันได้

วิธีที่แอปพลิเคชัน "ทำงาน" อธิบายไว้ในการทดสอบการยอมรับซึ่งตาม BDD จะเป็นคุณลักษณะและสถานการณ์ที่เขียนในแตงกวา

รายละเอียดเล็กน้อยเกี่ยวกับการทำงานของส่วนประกอบเล็ก ๆ แต่ละอันอธิบายไว้ในการทดสอบหน่วย ผลลัพธ์ของการทดสอบหน่วยรองรับสถานการณ์ที่คุณเขียนในแตงกวา

ลองนึกภาพกระบวนการสร้างรถยนต์

ขั้นแรกทีมผลิตภัณฑ์จะมาพร้อมกับความคิดของพวกเขาและในที่สุดก็ต้มพวกเขาลงในสถานการณ์การใช้งาน:

Scenario: Starting the car
    Given I am standing in front of the drivers door
    When I open the door
    Then the door should lift up DeLorean-style (yeah, baby!)
    When I get into the car
    And turn the key
    Then the engine roars to life

ฉันรู้ว่าสถานการณ์นี้ฟังดูไร้สาระ แต่เป็นระดับที่สูงมากความต้องการผลิตภัณฑ์และผู้ใช้ปลายทาง เพียงแค่เปิดประตูการหมุนกุญแจและสตาร์ทเครื่องยนต์นั้นประกอบไปด้วยส่วนประกอบต่าง ๆ มากมายที่ทำงานร่วมกัน การทดสอบนี้ไม่เพียงพอที่จะทำให้แน่ใจว่ายานพาหนะทำงานได้อย่างถูกต้อง คุณต้องทดสอบสตาร์ทเตอร์, แบตเตอรี่, อัลเทอร์เนเตอร์, กุญแจ, สวิตช์กุญแจ - และรายการจะดำเนินต่อ --- เพื่อเข้าไปในรถแล้วสตาร์ท แต่ละองค์ประกอบเหล่านั้นต้องการการทดสอบของตัวเอง

สถานการณ์ข้างต้นคือการทดสอบ "ภาพใหญ่" ส่วนประกอบของยานพาหนะแต่ละชิ้นต้องการการทดสอบ "รูปภาพขนาดเล็ก" เพื่อให้แน่ใจว่าสามารถทำงานได้อย่างถูกต้องภายในภาพรวม

ซอฟต์แวร์สร้างและทดสอบนั้นเหมือนกันหลายประการ คุณออกแบบจากบนลงล่างจากนั้นสร้างจากล่างขึ้นบน ทำไมต้องมีประตูที่ยกขึ้นหากคุณไม่สามารถสตาร์ทเครื่องยนต์ได้ ทำไมต้องมีสตาร์ทเตอร์หากคุณไม่มีแบตเตอรี่

ทีมผลิตภัณฑ์ของคุณจะมาพร้อมกับการทดสอบการยอมรับและแยกพวกมันออกเป็นแตงกวา สิ่งนี้จะช่วยให้คุณ "ภาพใหญ่" ตอนนี้มันก็ขึ้นอยู่กับทีมวิศวกรรมเพื่อออกแบบส่วนประกอบที่เหมาะสมและวิธีการที่พวกเขามีปฏิสัมพันธ์แล้วทดสอบแต่ละชิ้นแยกกัน - นี่คือการทดสอบหน่วยของคุณ

เมื่อการทดสอบหน่วยผ่านให้เริ่มต้นนำสถานการณ์จำลองของแตงกวามาใช้ คุณจะส่งมอบสิ่งที่ทีมผลิตภัณฑ์ได้ถาม


มีวิธีเชื่อมโยงการทดสอบ "ภาพใหญ่" กับการทดสอบ "ภาพขนาดเล็ก" หรือไม่? ฉันหมายถึงเมื่อฟีเจอร์เปลี่ยนไปอย่างเป็นทางการ (พูดถึงสถานการณ์แตงกวาที่กำลังเปลี่ยนแปลง) มีวิธีทำแผนที่การเปลี่ยนแปลงที่ทดสอบระดับต่ำสุดหรือไม่ (เช่นทดสอบ Junit ที่ใช้สำหรับสถานการณ์แตงกวานั้น)
Srikanth

คุณสามารถมีวิธีการช่วยเหลือและการยืนยันที่กำหนดเองที่ใช้ร่วมกันระหว่างการทดสอบ "ภาพใหญ่" และ "ภาพขนาดเล็ก" ของคุณได้ แต่ส่วนใหญ่จะเกี่ยวข้องกับการตั้งค่าที่แตกต่างกันเพื่อทดสอบรหัสหน่วยเฉพาะ
Nick McCurdy

[... ] ซึ่งตาม BDD จะเป็นคุณสมบัติและสถานการณ์ที่เขียนในแตงกวา คุณกำลังพูดถึงหลักการและเครื่องมือ
jub0bs

เอาล่ะถ้อยคำก็ดับไปเล็กน้อย แต่ประเด็นก็คือพฤติกรรมของแอปพลิเคชันนั้นถูกจับในฟีเจอร์และสถานการณ์จำลอง
เกร็ก Burghardt

9

ฉันพยายามที่จะเข้าใจ BDD ฉันอ่านบทความแล้วและฉันเข้าใจว่า BDD คือ "ขั้นตอนต่อไป" จาก TDD ฉันบอกว่าเพราะฉันพบว่าทั้งคู่มีความคล้ายคลึงกันมากและอย่างที่ฉันสามารถอ่านได้ในบทความนี้ BDD เกิดมาเพื่อปรับปรุงจาก TDD

ที่จริงแล้วไม่มี BDD ไม่ใช่ "ขั้นตอนต่อไป" จาก TDD มันเป็น TDD หรือมากกว่านั้นอย่างแม่นยำมันเป็นการใช้ถ้อยคำใหม่ของ TDD

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

ดังนั้นพวกเขาจึงปรับปรุง TDD ในแง่ของการกำหนดพฤติกรรม "การทดสอบ" และ "กรณีทดสอบ" ตอนนี้เป็น "ตัวอย่าง", "หน่วย" คือ "พฤติกรรม", "การยืนยัน" คือ "ความคาดหวัง" และอื่น ๆ

อย่างไรก็ตามวิธีการยังคงเหมือนเดิม คุณเริ่มต้นด้วยการทดสอบการยอมรับ (ฉันหมายถึง "คุณสมบัติ") ซูมเข้าสู่การทดสอบหน่วย (ฉันหมายถึง "ตัวอย่าง") ซูมออก ฯลฯ

ฉันต้องการทดสอบยูนิต ฉันจะทดสอบรหัสที่ตรวจสอบว่าเครื่องจ่ายมีเงินได้อย่างไร หรือว่าเงินสดจ่าย? หรือว่าบัญชีถูกหักบัญชีเมื่อจำเป็น? ฉันจะผสมการทดสอบหน่วยกับการทดสอบ "สร้างโดย BA" ได้อย่างไร

เช่นเดียวกับที่คุณทำใน TDD คุณสามารถเขียนคุณสมบัติและตัวอย่างของคุณในกรอบงานที่แตกต่างกัน (เช่น Cucumber และ RSpec) หรือแม้แต่ภาษาอื่น (เช่นการเขียนตัวอย่างสำหรับโครงการ C ใน C และคุณสมบัติใน FIT / Fitnesse) คุณสามารถใช้เฟรมเวิร์กคุณลักษณะเดียวสำหรับทั้งสอง ( เช่นการเขียนตัวอย่างและคุณสมบัติในแตงกวา) หรือคุณสามารถใช้กรอบตัวอย่างเดียวสำหรับทั้งคู่ (เช่นการเขียนทั้งใน RSpec) คุณไม่ต้องใช้กรอบเลยแม้แต่น้อย

ตัวอย่างของ TDD-done-right (ซึ่งเหมือนกับ BDD) โดยใช้เพียงเฟรมเวิร์กเดียวคือ JUnit เองซึ่งประกอบด้วยการทดสอบหน่วย (ตัวอย่าง) และการทดสอบการใช้งาน / การรวม (ฟีเจอร์) ซึ่งทั้งหมดเขียนด้วย JUnit

ฉันเชื่อว่า Kent Beck เรียกสิ่งนี้ว่า "การซูม" เริ่มระดับสูงจากนั้น "ซูมเข้า" ถึงรายละเอียดจากนั้นกลับออกมาอีกครั้ง


1

ข้อจำกัดความรับผิดชอบ: ฉันไม่ใช่ผู้เชี่ยวชาญใน BDD แต่ฉันพยายามให้มุมมองแก่ฉันเกี่ยวกับบทความที่คุณเชื่อมโยง

TDD เป็นเทคนิคการใช้งาน - คุณเขียนการทดสอบก่อนจากนั้นคุณใช้วิธีการทดสอบการทดสอบของคุณ refactor และเพิ่มการทดสอบเพิ่มเติมสำหรับวิธีการเดียวกันหรือวิธีการใหม่ TDD จริง ๆ แล้วไม่ได้กำหนดกฎใด ๆ สำหรับวิธีการเลือกชื่อชั้นเรียนหรือวิธีการที่ขึ้นอยู่กับคุณ TDD ยังไม่บอกคุณว่า "เมื่อคุณทำเสร็จ"

ดังนั้นเมื่อใดก็ตามที่คุณเขียนการทดสอบสำหรับวิธีการใหม่คุณจะต้องเลือกชื่อวิธีการ - และนั่นคือจุดที่ BDD เข้ามาโดยการเลือกชื่อวิธีการใช้เงื่อนไขทางธุรกิจจากสถานการณ์ข้างต้นและโดยการเลือกวิธีในการอธิบาย พฤติกรรมของชั้นเรียนของคุณคุณกำลังทำ BDD เมื่อใดก็ตามที่คุณถามตัวเองว่า "ฉันต้องเพิ่มการทดสอบเพิ่มเติม" คุณสามารถดูสถานการณ์ที่ได้รับจาก BA ของคุณและตรวจสอบว่าคุณได้ดำเนินการทุกส่วนที่จำเป็นทั้งหมดหรือไม่ ถ้าไม่คุณจะต้องทำการทดสอบเพิ่มเติม

ผู้เขียนบทความยังแนะนำให้ใช้รูปแบบการตั้งชื่อที่เกี่ยวข้องกับพฤติกรรมมากขึ้นเมื่อเลือกชื่อการทดสอบของคุณนั่นคือเหตุผลที่เขาแนะนำให้แทนที่ JUnit ด้วยเครื่องมือที่ไม่ต้องพึ่งพาโครงร่างการตั้งชื่อที่แต่ละกรณีการทดสอบจะต้องเริ่มต้นด้วย ชื่อ "ทดสอบ" แม้ว่าฉันจะไม่รู้จัก JBehave แต่ฉันคิดว่านั่นเป็นข้อแตกต่างที่สำคัญระหว่างเครื่องมือนั้นกับ Junit

ยิ่งกว่านั้นสถานการณ์ BDD ก็จะเป็นพิมพ์เขียวสำหรับการทดสอบการรวมซึ่งโดยทั่วไปแล้วคุณจะเพิ่มหลังจากคุณได้รวบรวมชื่อวิธีการโดย TDD และหลังจากที่คุณเพิ่มการทดสอบหน่วยจำนวนพอสมควร

ดังนั้นเพื่อความเข้าใจของฉัน TDD เป็นเครื่องมือที่คุณสามารถใช้เป็นส่วนหนึ่งของ BDD และ BDD ช่วยให้คุณเขียนแบบทดสอบที่ถูกต้องและตั้งชื่อให้ดีขึ้น


จุนจิตสนับสนุนการตั้งชื่อการทดสอบของคุณทุกอย่าง คุณต้องใช้คำอธิบายประกอบ @Test แม้ว่ามันอาจจะยังไม่เสร็จในปี 2003
soru

@soru ย้อนกลับไปในปี 2003 มันแน่นอนบังคับใช้คำว่า "ทดสอบ"
Lunivore

ผู้เขียนบทความนี้คือ Dan North ผู้ซึ่งมาพร้อมกับแนวคิดตั้งแต่แรก หนึ่งในสิ่งที่เขาสังเกตเห็นคือคำว่า "การทดสอบ" ทำให้เราย้ายไปทดสอบการใช้งานของเรา (โดเมนโซลูชัน) ในขณะที่จริงการสำรวจและกำหนดการทดสอบควรทำให้เราอยู่ในโดเมนปัญหา แดนได้อธิบาย BDD ว่า "สิ่งที่ TDD ตั้งใจให้เป็น" อ่านสิ่งนี้สำหรับข้อมูลเพิ่มเติม: dannorth.net/2012/05/31/bdd-is-like-tdd-if
Lunivore
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.