TDD และการควบคุมเวอร์ชัน


25

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

  1. ฉันเริ่มต้นโครงการใหม่และเขียนการทดสอบอย่างง่ายเพื่อสร้างคลาสแบบ as-yet-nonexistent ฉันควรจะทำแบบทดสอบก่อนเขียนชั้นแม้ว่าการทดสอบจะไม่ได้รวบรวม หรือฉันควรเริ่มต้นจำนวนขั้นต่ำของรหัสที่จำเป็นสำหรับการทดสอบเพื่อคอมไพล์ก่อนที่จะคอมมิท?

  2. ฉันพบข้อบกพร่องและเขียนการทดสอบเพื่อสร้างใหม่ ฉันควรคอมมิชชันทดสอบที่ล้มเหลวหรือใช้การแก้ไขข้อบกพร่องแล้วคอมมิท?

เหล่านี้เป็นสองตัวอย่างที่มาถึงใจทันที อย่าลังเลที่จะให้ตัวอย่างเพิ่มเติมในคำตอบของคุณ

แก้ไข:

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

ซึ่งหมายความว่าคำถามของฉันเป็นเรื่องเกี่ยวกับสิ่งที่จะกระทำตามที่เป็นอยู่เมื่อใดที่จะกระทำ

คำตอบ:


21

ฉันควรจะทำแบบทดสอบก่อนที่จะเขียนชั้นแม้ว่าการทดสอบจะไม่ได้รวบรวม หรือฉันควรเริ่มต้นจำนวนขั้นต่ำของรหัสที่จำเป็นสำหรับการทดสอบเพื่อคอมไพล์ก่อนที่จะคอมมิท?

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

ฉันพบข้อบกพร่องและเขียนการทดสอบเพื่อสร้างใหม่ ฉันควรคอมมิชชันทดสอบที่ล้มเหลวหรือใช้การแก้ไขข้อบกพร่องแล้วคอมมิท?

ไม่ไม่ต้องทำการทดสอบที่ล้มเหลว กฎหมายของเลอบลังระบุ:

ต่อมาเท่ากับไม่เคย

และการทดสอบของคุณอาจล้มเหลวเป็นเวลานาน มันจะดีกว่าที่จะแก้ไขปัญหาทันทีที่ตรวจพบ

นอกจากนี้สไตล์การพัฒนา TDD ก็บอกว่า:

การพัฒนาที่ขับเคลื่อนด้วยการทดสอบจะทำซ้ำขั้นตอนของการเพิ่มกรณีทดสอบที่ล้มเหลวส่งผ่านและสร้างซ้ำอย่างต่อเนื่อง

หากคุณตรวจสอบในการทดสอบที่ล้มเหลวนั่นหมายความว่าคุณยังไม่ครบรอบ


1เมื่อฉันพูดว่าคอมมิชชันฉันหมายถึงการผูกมัดจริง ๆ (สำหรับผู้ใช้คอมไพล์ดันการเปลี่ยนแปลงของคุณดังนั้นนักพัฒนาคนอื่นจะได้พวกเขามา)


4
"และจะทำให้คนโกรธทำงานในโครงการเดียวกันหาก" - มีคนอาศัยอยู่ใน SVN โลกใช้ GIT และคุณจะไม่ทำให้ใครโกรธ
Mateusz

3
ฉันคิดว่าการทำดีหลังจากเขียนแบบทดสอบอย่าผลักจนกว่าคุณจะทำเสร็จ
Matsemann

4
@radarbob สิ่งนี้ใช้ได้กับ DVCS ที่มีความแตกต่างระหว่างการยืนยันและการผลักหรือไม่? ฉันสามารถจินตนาการถึงสถานการณ์ที่ฉันทำหลายอย่างเพื่อคอมไพล์ git ท้องถิ่นของฉันที่สุดท้ายกระทำการสร้างไม่พัง แต่ในระหว่างกาลใด ๆ ที่มันอาจจะเป็น
Code-Guru

6
ไม่ไม่ยอมรับการทดสอบที่ล้มเหลว แต่หนึ่งในจุดของ TDD คือการทดสอบที่ล้มเหลวอย่างแม่นยำก่อนการเข้ารหัส ดังนั้นการยอมรับการทดสอบที่ล้มเหลวนั้นสมเหตุสมผล
mouviciel

4
@ Code-Guru: สำหรับ DVCS กฎนั้นควรจะเป็น: "อย่าส่งรหัสที่เสียหายไปยังสาขาที่คนอื่นดึงมาเป็นประจำ" หากคนอื่นไม่ดึงจาก repo ในพื้นที่ของคุณนั่นอาจจะอยู่ในสถานะใด ๆ ก็ตาม
Bart van Ingen Schenau

6

ฉันควรจะทำแบบทดสอบก่อนที่จะเขียนชั้นแม้ว่าการทดสอบจะไม่ได้รวบรวม

เลขที่

ฉันควรจะทำแบบทดสอบที่ล้มเหลวหรือไม่

เลขที่

คุณกำลังพูดถึงสองกระบวนทัศน์ที่นี่:

  1. การพัฒนาที่ขับเคลื่อนด้วยการทดสอบ - ซึ่งไม่ได้บอกอะไรเกี่ยวกับการส่งโค้ด แน่นอนมันจะบอกคุณเกี่ยวกับวิธีการเขียนโค้ดและเมื่อคุณทำเสร็จแล้ว ดังนั้นฉันจะพิจารณาทุก 'ทำ' เป็นผู้สมัครสำหรับการกระทำ
  2. การพัฒนาที่คล่องตัวโดยเฉพาะ: "กระทำเร็วและบ่อยครั้ง" (ซึ่งไม่ต้องการ TDD) แนวคิดเบื้องหลังคือต้องมีการรวมเข้ากับส่วนประกอบอื่น ๆ ในระบบอย่างรวดเร็วและได้รับข้อเสนอแนะก่อน หากคุณกระทำการใน DVCS ในพื้นที่และอย่าผลักดันมันไร้ค่าในความหมายนั้น Local commits ช่วยนักพัฒนาในการจัดโครงสร้างงานของพวกเขา

คำแนะนำของฉันคือ: ทำตามวงกลมของ TDD จนกว่ารหัสของคุณจะรวบรวมการทดสอบของคุณเป็นสีเขียวและคุณมีสิ่งที่จะมีส่วนร่วมในระบบ ดังนั้นคุณควรตัดคุณสมบัติของคุณในแนวตั้งเช่นสำหรับ UI รูปแบบใหม่อย่าสร้างทั้งรูปแบบและกระทำโดยไม่มีตรรกะทางธุรกิจ แต่ควรใช้สิ่งเล็ก ๆ น้อย ๆ แต่ในส่วนหน้าและตรรกะทางธุรกิจและในชั้นความคงทน .

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


5

แน่นอนว่าคุณเริ่มต้นด้วยการใช้ตัวควบคุมแหล่งที่ดีต่อสุขภาพอย่าง git

จากนั้นคุณสามารถทำงานในแบบที่คุณชอบและกระทำในแต่ละมุม - ขั้นตอนหรือขั้นตอนย่อยเป็นเกมที่ยุติธรรม

จากนั้นก่อนที่จะผลักดันสิ่งที่คุณสควอชงานทั้งหมดในการกระทำเดียว หรือคู่ที่จุดที่ทุกอย่างเป็นสีเขียวและองค์ประกอบที่ทำให้รู้สึก และผลักดันการกระทำที่สมเหตุสมผลเหล่านั้น สำหรับหลายกรณีให้เป็นสาขาที่คุณรวมเข้ากับ - no-ff

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


5

มันเป็นความเข้าใจของฉันเกี่ยวกับโลกที่เรามุ่งมั่นที่จะทำเครื่องหมายจุดที่มันอาจเป็นที่พึงปรารถนาที่จะกลับไป จุดที่การทดสอบล้มเหลว (แต่คอมไพล์) นั้นเป็นจุดหนึ่งที่แน่นอน หากฉันต้องเดินไปในทิศทางที่ผิดพยายามที่จะทำการทดสอบผ่านฉันต้องการที่จะสามารถเปลี่ยนรหัสกลับเป็นจุดเริ่มต้นและลองอีกครั้ง ฉันไม่สามารถทำสิ่งนี้ได้หากฉันไม่ได้ทำ


ฉันเห็นด้วยกับคุณ. ฉันชอบที่จะใช้สาขาที่แตกต่างกันเพื่อปฏิบัติตามกฎ "อย่าทำลายโครงสร้าง" และรวมการเปลี่ยนแปลงใน trunk เฉพาะเมื่อการทดสอบผ่าน
Fil

5

ฉันควรจะทำแบบทดสอบก่อนที่จะเขียนชั้นแม้ว่าการทดสอบจะไม่ได้รวบรวม

ด้วยการแยก SCM (ฉันเห็นว่าคุณใช้ Git) คุณควรกระทำเมื่อใดก็ตามที่คุณต้องการจุดสำรองข้อมูล ("ฉันพลาดบางสิ่งบางอย่างฉันจะรีเซ็ต dir ที่ทำงานเป็นจุดสำรองสุดท้าย") หรือเมื่อคุณมีรุ่นที่เสถียร เมื่อคุณมีรุ่นที่เสถียร (ผ่านการทดสอบทั้งหมด) คุณควรพิจารณารวมสาขาฟีเจอร์ปัจจุบันเข้ากับสาขาการพัฒนาหลักของคุณ

หรือฉันควรเริ่มต้นจำนวนขั้นต่ำของรหัสที่จำเป็นสำหรับการทดสอบเพื่อคอมไพล์ก่อนที่จะคอมมิท?

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

ฉันพบข้อบกพร่องและเขียนการทดสอบเพื่อสร้างใหม่ ฉันควรคอมมิชชันทดสอบที่ล้มเหลวหรือใช้การแก้ไขข้อบกพร่องแล้วคอมมิท?

ฉันมักจะทำสองคอมมิชชันยกเว้นว่าโค้ดทดสอบนั้นเล็ก / เขียนเล็กน้อย

เหล่านี้เป็นสองตัวอย่างที่มาถึงใจทันที อย่าลังเลที่จะให้ตัวอย่างเพิ่มเติมในคำตอบของคุณ

แก้ไข:

ฉันตั้งสมมติฐานในทั้งสองตัวอย่างว่าฉันทันทีหลังจากเขียนแบบทดสอบฉันจะเขียนโค้ดเพื่อทำแบบทดสอบ

นั่นอาจเป็นข้อสันนิษฐานที่ผิดที่จะทำ หากคุณทำงานคนเดียว (โครงการส่วนตัว) ไม่มีอะไรทำให้คุณหยุดทำสิ่งนั้นได้ตลอดเวลา ในหนึ่งในโครงการที่ประสบความสำเร็จมากที่สุดของฉัน (เกี่ยวกับการรักษาคุณภาพรหัสสูงและ TDD ตลอดการพัฒนาโครงการ) เรากำหนดการทดสอบบางครั้งหลายสัปดาห์ก่อนนำไปใช้ (เช่นเราจะพูดว่า "การทดสอบ" test_FOO_with_null_first_parameter ") กระทำเช่นนั้น) จากนั้นเราจะใช้ sprint (หรือครึ่ง sprint) บางครั้งประมาณหนึ่งเดือนหรือมากกว่านั้นเพื่อเพิ่มการครอบคลุมการทดสอบสำหรับโมดูลเนื่องจากเรามีการทดสอบที่ประกาศแล้วว่าประเมินได้ง่าย

สถานการณ์อื่นอาจเกิดขึ้น: ฉันทำงานในโครงการที่ใช้ TDD เป็นเวลาหลายชั่วโมงโดยไม่ต้องทำอะไร ในที่สุดเมื่อฉันลงมือทำฉันต้องการที่จะเลิกงานของฉันเป็นชิ้นเล็ก ๆ (Git ทำให้มันค่อนข้างง่ายแม้ว่าคุณต้องการที่จะยอมรับการเปลี่ยนแปลงบางอย่างในไฟล์เดียว) ซึ่งหมายความว่าคำถามของฉันนั้นเกี่ยวกับสิ่งที่ต้องทำตามที่จะต้องทำ

ฉันจะบอกว่ามุ่งมั่นที่จะสร้างจุดสำรองข้อมูลอย่างแน่นอน วิธีนี้ใช้งานได้ดีมากสำหรับการทดสอบเชิงสำรวจ ("ฉันจะเพิ่มการพิมพ์บางส่วนในฐานรหัสให้รันและgit reset --hardลบออกเมื่อเสร็จสิ้น) และการสร้างต้นแบบ


2
ระมัดระวังเกี่ยวกับการแนะนำการรีเซ็ต git - ฮาร์ด มันเป็นหนึ่งในไม่กี่คำสั่งในคอมไพล์ที่จะทำให้คุณทำงานหลวม
gnash117

2

ในกระบวนการทำงานของฉันเมื่อใดก็ตามที่เป็นไปได้ฉันจะทำงานที่ไม่แน่นอนในสาขาการควบคุมแหล่งที่มาส่วนบุคคล ดังนั้นฉันจึงสามารถลองล้มเหลวลองอีกครั้งหากจำเป็นจนกว่าจะได้ผลและจะมอบให้โครงการที่มีขนาดใหญ่ขึ้นเมื่อฉันมีรหัสการทำงานจริงเท่านั้น

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.