ฉันจำเป็นต้องมีการทดสอบหน่วยหรือไม่ถ้าฉันมีการทดสอบการรวมระบบแล้ว


47

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

สิ่งที่ฉันรู้ถึงประโยชน์ของการทดสอบหน่วยผ่านการทดสอบการรวมคือ

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

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


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

คำถามนี้ดูเหมือนคลุมเครือ สมมติว่าฉันมีวิธีการควบคุม Rails ที่เรียกผู้โต้ตอบ ( github.com/collectiveidea/interactor ) ฉันตัดสินใจที่จะเขียนการทดสอบการรวมสำหรับวิธีการควบคุมของฉัน (เพราะไม่มีพวกเขาฉันไม่สามารถเชื่อถือได้ว่าจุดสิ้นสุด API ของฉันทำงาน) มีคำถามอย่างน้อยสองข้ออยู่ที่: (1) ฉันควรเขียนการทดสอบหน่วยสำหรับวิธีการควบคุมของฉัน (เช่นฉันควรเขียนการทดสอบหน่วยที่ทดสอบพฤติกรรมเดียวกับการทดสอบการรวมระบบของฉัน) และ (2) ฉันควรเขียนการทดสอบหน่วยด้วย สำหรับผู้โต้ตอบของฉัน ฉันจะตอบคำถามสองข้อนี้ในบริบททางธุรกิจที่แตกต่างกัน
แดเนียล

คำตอบ:


33

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

  • ขนาดเล็กและรวดเร็วเป็นลักษณะที่ดีของการทดสอบหน่วยแม้ว่าจะไม่สำคัญที่สุด
  • Locating-bug [s] -easier มีค่ามาก การศึกษาจำนวนมากของการพัฒนาซอฟต์แวร์มืออาชีพแสดงให้เห็นว่าค่าใช้จ่ายของข้อผิดพลาดเพิ่มขึ้นอย่างมากในขณะที่มันอายุและย้ายลงท่อส่งซอฟต์แวร์
  • การค้นพบข้อบกพร่องนั้นมีค่า เมื่อคุณรู้ว่าส่วนประกอบเฉพาะมีการตรวจสอบพฤติกรรมทั้งหมดของมันคุณสามารถใช้มันได้ในลักษณะที่ไม่เคยใช้มาก่อนด้วยความมั่นใจ หากการตรวจสอบเพียงอย่างเดียวคือผ่านการทดสอบการรวมคุณจะรู้ว่าการใช้งานในปัจจุบันนั้นทำงานอย่างถูกต้อง
  • การเยาะเย้ยนั้นมีค่าใช้จ่ายสูงในกรณีที่เกิดขึ้นจริงและการบำรุงรักษา mocks นั้นเป็นสองเท่าเช่นกัน ในความเป็นจริงเมื่อทำการจำลองวัตถุหรืออินเทอร์เฟซที่น่าสนใจคุณอาจต้องทำการทดสอบเพื่อตรวจสอบว่าวัตถุจำลองของคุณจำลองวัตถุจริงของคุณอย่างถูกต้อง!

ในหนังสือของฉันข้อดีมีมากกว่าข้อเสีย


2
การเย้ยหยันถูกกว่าในกรณีจริงหรือไม่? คุณเพียงแค่ตั้งค่าความคาดหวังของข้อความที่เยาะเย้ยได้รับและระบุสิ่งที่จะกลับมา
Dogweather

10
@Dogweather Mocks ทำงานได้ดีเมื่อสร้างครั้งแรก เมื่อเวลาผ่านไปและวัตถุจริงมีการเปลี่ยนแปลง mocks ต้องเปลี่ยนด้วย 10 ปีกับการทดสอบ 6,000 ครั้งตามถนนเป็นเรื่องยากมากที่จะรู้ว่าการทดสอบ "สำเร็จ" ของคุณนั้นประสบความสำเร็จจริงๆ
Ross Patterson

1
นอกเหนือจากนั้น "การทดสอบ 10 ปีและ 6,000 บท" เป็นตัวเลขจากประสบการณ์ส่วนตัวไม่ใช่การทดสอบ
Ross Patterson

3
ฉันเริ่มเขียนการทดสอบนักพัฒนาอัตโนมัติ (หน่วยและการรวม แต่ส่วนใหญ่หลัง) ย้อนกลับไปในปี 2004 หรือ 2005 และพัฒนาห้องสมุดเยาะเย้ยขั้นสูงสำหรับ Java หลายครั้งที่ผมเห็นการทดสอบการรวมหลายหมดด้วยเหตุผลเดียวกัน (เช่นการเปลี่ยนแปลงใน DB หรือเปลี่ยนแปลงเครือข่าย) และบางครั้งที่ผมเขียน "ลดระดับ" การทดสอบการรวมสำหรับส่วนประกอบที่นำมาใช้ใหม่ แต่ยังคงผมชอบมากที่จะเพียงมี การทดสอบแบบรวม การทดสอบแบบแยกหน่วยกับการเยาะเย้ยส่วนใหญ่มักไม่คุ้มค่า ฉันใช้การเยาะเย้ยเท่านั้นเป็นตัวช่วยสำหรับการทดสอบการรวม
Rogério

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

8

ฉันไม่เห็นคุณค่ามากนักในการปรับใช้งานการทดสอบการรวมที่มีอยู่ในลักษณะที่ไม่เหมาะสม

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

> Then what are the reasons to write/add unit tests?

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

หากรหัสนั้นมีอยู่แล้วโดยไม่มีการทดสอบหน่วยมักจะมีงานพิเศษมากมายในการเขียนการทดสอบหน่วยหลังจากนั้นเพราะรหัสนั้นไม่ได้ถูกเขียนขึ้นเพื่อการทดสอบที่ง่าย

หากคุณทำ TDD รหัสนั้นจะทดสอบได้ง่ายโดยอัตโนมัติ


2
หากฉันมีแอปพลิเคชันรุ่นเก่าที่ไม่มีunit-testsและฉันต้องการรวมunit-testsไว้ในบางส่วนคุณคิดว่าการเขียนintegration testsรหัสดั้งเดิมนั้นดีกว่าหรือไม่ เมื่อเขียนเสร็จแล้วคุณสามารถแยกคลัปคับและสร้างฟังก์ชั่นด้วยอินเตอร์เฟสที่สามารถทดสอบได้? เนื่องจากคุณได้integration-testเขียนไว้แล้วคุณสามารถยืนยันในแต่ละขั้นตอนของการปรับโครงสร้างใหม่ว่ารหัสใหม่ยังคงทำงานตามที่ต้องการหรือไม่
alpha_989

2
@ alpha_989 นี่เป็น IMHO อย่างมากและฉันเปิดรับฟังความคิดเห็นอื่น ๆ แต่ฉันชอบการทดสอบการรวมมากกว่าการทดสอบหน่วยสำหรับรหัสดั้งเดิม ในทั้งสองกรณีคุณจะต้องแน่ใจว่าวิธีการทำงานอย่างถูกต้องก่อนที่จะเพิ่มประเภทของการทดสอบใด ๆ แต่การทดสอบบูรณาการช่วยให้มั่นใจได้ว่าความคาดหวังโดยรวมของวิธีการทำงานเมื่อเทียบกับองค์ประกอบรหัสแต่ละ
Britt Wescott

5

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


4

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

นอกจากนี้ข้อผิดพลาดที่คุณอาจทำคือเชื่อมั่นในสิ่งนั้น

Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.

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

ฉันเดาการอ้างอิงแบบบัญญัติกับการทดสอบแบบรวมเป็นโพสต์ของ JBrains:

http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1

ในกรณีที่คุณยังไม่ได้อ่าน

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


ฉันไม่ได้รับบทความนั้นจริงๆ ดังนั้นจึงมีเส้นทางรหัสจำนวนมากและการทดสอบการรวมไม่สามารถครอบคลุมได้ทั้งหมด ... เหรอ? สิ่งเดียวกันนี้ใช้กับการทดสอบหน่วยเว้นแต่ว่าหน่วยของคุณมีความรู้รอบรู้เรื่องไร้จุดหมาย
Casey

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

1

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

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


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