อะไรคือความแตกต่างระหว่างการรวมเข้ากับการทดสอบหน่วย?


307

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

ตัวอย่างเช่นถ้าฉันมีWordชั้นเรียนฉันจะเขียนการทดสอบหน่วยสำหรับWordชั้นเรียน จากนั้นฉันเริ่มเขียนSentenceชั้นเรียนของฉันและเมื่อจำเป็นต้องมีปฏิสัมพันธ์กับWordชั้นเรียนฉันมักจะเขียนแบบทดสอบหน่วยเพื่อที่จะทดสอบทั้งสองSentenceและWord... อย่างน้อยในสถานที่ที่พวกเขามีปฏิสัมพันธ์

การทดสอบเหล่านี้กลายเป็นการทดสอบการรวมเข้าด้วยกันเพราะตอนนี้พวกเขาทดสอบการรวมกันของ 2 คลาสเหล่านี้หรือเป็นเพียงการทดสอบหน่วยที่ครอบคลุม 2 คลาส?

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

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

คำตอบ:


300

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

ในทางตรงกันข้ามการทดสอบหน่วยการทดสอบวิธีการเดียวอาศัยสมมติฐาน (มักจะผิด) ว่าส่วนที่เหลือของซอฟต์แวร์ทำงานอย่างถูกต้องเพราะมันชัดเจน mocks ทุกการพึ่งพา

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

สมมติว่าคุณมีวิธีการบางอย่างเช่นนี้:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  Log.TrackTheFactYouDidYourJob();
  return someResults;
}

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

Feature: To be able to do something
  In order to do something
  As someone
  I want the system to do this thing

Scenario: A sample one
  Given this situation
  When I do something
  Then what I get is what I was expecting for

ไม่ต้องสงสัยเลยว่า: หากการทดสอบผ่านไปคุณสามารถยืนยันได้ว่าคุณมีคุณสมบัติที่ใช้งานได้ นี่คือสิ่งที่คุณสามารถโทรหามูลค่าทางธุรกิจ

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

ในทางปฏิบัติคุณทำสิ่งที่ชอบ:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
  return someResults;
}

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

Log.DoSomething()สมมติว่ามีข้อผิดพลาดใน โชคดีที่ข้อมูลจำเพาะของ Gherkin จะค้นหาได้และการทดสอบแบบครบวงจรจะล้มเหลว

คุณลักษณะนี้ใช้งานไม่ได้เพราะใช้Logงานไม่ได้ไม่ใช่เพราะ[Do your job with someInput]ไม่ทำงาน และโดยวิธีการ[Do your job with someInput]เป็นความรับผิดชอบ แต่เพียงผู้เดียวสำหรับวิธีการที่

นอกจากนี้สมมติว่าLogมีการใช้งานในคุณสมบัติอื่น ๆ 100 รายการและวิธีการอื่น ๆ อีก 100 คลาส

ใช่คุณสมบัติ 100 จะล้มเหลว แต่โชคดีที่การทดสอบแบบครบวงจร 100 ครั้งนั้นล้มเหลวเช่นกันและแสดงให้เห็นถึงปัญหา และใช่: พวกเขาจะบอกความจริง

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

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

(หากDoSomething()การทดสอบหน่วยล้มเหลวให้แน่ใจว่า: [Do your job with someInput]มีข้อบกพร่องบางอย่าง)

สมมติว่านี่เป็นระบบที่มีคลาสที่ใช้งานไม่ได้: ระบบที่มีคลาสที่ใช้งานไม่ได้

บั๊กเดี่ยวจะทำลายคุณสมบัติหลายอย่างและการทดสอบการรวมหลาย ๆ ครั้งจะล้มเหลว

บั๊กเดี่ยวจะทำลายคุณสมบัติหลายอย่างและการทดสอบการรวมหลาย ๆ ครั้งจะล้มเหลว

ในทางกลับกันข้อผิดพลาดเดียวกันจะทำลายการทดสอบหน่วยเดียว

ข้อผิดพลาดเดียวกันจะทำลายการทดสอบหน่วยเดียว

ตอนนี้เปรียบเทียบทั้งสองสถานการณ์

ข้อผิดพลาดเดียวกันจะทำลายการทดสอบหน่วยเดียว

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

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

ความแตกต่าง

การทดสอบการรวมระบบบอกว่าอะไรไม่ทำงาน แต่พวกเขาไม่มีประโยชน์ในการคาดเดาปัญหาที่อาจเกิดขึ้น

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

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

คำตอบนี้เป็นพื้นเป็นบทสรุปของสิ่งที่ผมเขียนนี่: การทดสอบหน่วยโกหกที่ว่าทำไมฉันรักพวกเขา


6
คำตอบที่ดีจริงๆ! อย่างไรก็ตามฉันแค่ต้องการเพิ่มว่าการเยาะเย้ยนั้นไม่ได้มีไว้สำหรับการทดสอบหน่วยเท่านั้น มันอาจจะมีประโยชน์มากในกรณีทดสอบการรวมระบบจำนวนมาก
n.Stenvang

1
คำตอบที่ดี! ฉันไม่เห็นด้วยกับประเด็นสองข้อ: 1) การทดสอบการรวมเป็น "ไม่มีประโยชน์ในการคาดเดาปัญหาที่อาจเกิดขึ้น"; และ 2) ว่า "การทดสอบหน่วยไม่ควรครอบคลุม 2 คลาส" ฉันสร้างการทดสอบการรวมจำนวนมากและเมื่อพวกเขาหยุดพักมักจะไม่ยากที่จะระบุแหล่งที่มาของปัญหาหากคุณได้รับการติดตามสแต็คเต็มรูปแบบหรือการยืนยันที่ล้มเหลวเดียว (ในกรณีนี้อาจหาแหล่งที่มาได้ยากขึ้น ไม่มากเนื่องจากการทดสอบการรวมให้บริบทที่มีอยู่สำหรับการดีบัก) (ดำเนินการต่อ)
Rogério

5
การทดสอบหน่วยสามารถออกกำลังกายหลายคลาสโดยไม่ต้องมีคลาสสาธารณะซึ่งควรมีการทดสอบหน่วยแยกต่างหาก กรณีหนึ่งคือเมื่อคลาสทดสอบสาธารณะใช้คลาสตัวช่วยอื่นที่ไม่ใช่แบบสาธารณะซึ่งมีอยู่เพื่อสนับสนุนคลาสสาธารณะเท่านั้น ในกรณีนี้ "หน่วย" ประกอบด้วยสองคลาสขึ้นไป อีกกรณีหนึ่งคือคลาสส่วนใหญ่ใช้คลาสบุคคลที่สาม (คลาส String / สตริงคลาสคอลเลกชัน ฯลฯ ) ซึ่งไม่สมเหตุสมผลที่จะถูกเยาะเย้ยหรือแยกออกจากกัน เราเพียง แต่พิจารณาว่ามันเป็นการพึ่งพาที่มั่นคงและเชื่อถือได้ซึ่งอยู่นอกขอบเขตการทดสอบ
Rogério

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

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

62

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

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


43

10 บิตของฉัน: D

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

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

เป็นบรรทัดที่สามารถเคลื่อนย้ายได้จริง .. ฉันอยากจะมุ่งเน้นไปที่การให้โค้ด damn ทำงานเต็มหยุด ^ _ ^


23

การทดสอบหน่วยใช้ mocks

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


ฉันรู้ว่านี่เป็นโพสต์เก่า แต่ฉันเพิ่งเจอมัน ถ้าคุณมีคลาสที่สามเรียกว่า Font ซึ่งคลาส Sentence โต้ตอบกับและคุณต้องการทดสอบการทำงานระหว่างคลาส Word และ Sentence คุณต้องจำลองคลาส Font แต่จะไม่ทำให้เป็นการทดสอบหน่วย ดังนั้นสิ่งที่ฉันพูดคือการใช้ mocks ไม่จำเป็นต้องทำให้เป็นการทดสอบหน่วย
n.Stenvang

2
แน่นอน mocks สามารถนำมาใช้ในการทดสอบการรวม แต่เพื่อให้การทดสอบหน่วยที่จริงจะเป็นทุกอย่างเช่นภายนอกไปยังหน่วยควรจะจำลอง หากการทดสอบการรวมใช้ mocks แสดงว่าเป็นการทดสอบการรวมบางส่วน (ถ้ามีคำดังกล่าว) แน่นอนว่าเป็นการทดสอบการรวมเข้าด้วยกันบางส่วนซึ่งเป็นการทดสอบจากบนลงล่างหรือจากล่างขึ้นบน ยุคหลังมักไม่ต้องการ mocks ในขณะที่อดีตทำ
Robert Koritnik

17

ฉันคิดว่าเมื่อคุณเริ่มคิดเกี่ยวกับการทดสอบการรวมคุณกำลังพูดถึงการข้ามระหว่างเลเยอร์ทางกายภาพมากกว่าเลเยอร์ตรรกะ

ตัวอย่างเช่นหากการทดสอบของคุณเกี่ยวข้องกับการสร้างเนื้อหานั่นเป็นการทดสอบหน่วย: หากการทดสอบของคุณเกี่ยวข้องกับการเขียนลงดิสก์ก็ยังเป็นการทดสอบต่อหน่วย แต่เมื่อคุณทดสอบทั้ง I / O และเนื้อหาของไฟล์ จากนั้นคุณมีแบบทดสอบการรวมเข้าด้วยกัน เมื่อคุณทดสอบเอาต์พุตของฟังก์ชันภายในเซอร์วิสมันเป็นการทดสอบหน่วย แต่เมื่อคุณทำการเรียกเซอร์วิสและดูว่าผลลัพธ์ของฟังก์ชันนั้นเหมือนกันหรือไม่นั่นคือการทดสอบการรวม

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


8
"ในทางเทคนิคคุณไม่สามารถทดสอบหน่วยเพียงชั้นเดียวได้แล้วถ้าชั้นเรียนของคุณประกอบไปด้วยคลาสอื่น ๆ ?" การทดสอบหน่วยที่ "เข้มงวด" จะเป็นการเยาะเย้ย / ต้นขั้วทั้งหมดอ้างอิง แต่ก็เป็นที่ถกเถียงกันว่านี้เป็นจริงเสมอ ...
sleske

2
นั่นเป็นความจริง - สิ่งสำคัญคือการสามารถพึ่งพาได้น้อยที่สุด
Jon Limjap

-1 การทดสอบหน่วยไม่ได้ทดสอบคุณสมบัติเดียว แต่ฟังก์ชั่นซอฟต์แวร์หรือคลาสเดียวนั่นคือการทดสอบหน่วยตรรกะของซอฟต์แวร์
CharlesB

12

ใช้การออกแบบความรับผิดชอบเดียวมันสีดำและสีขาว มากกว่า 1 ความรับผิดชอบการทดสอบบูรณาการ

โดยการทดสอบเป็ด (ดู, quacks, waddles, เป็นเป็ด), เป็นการทดสอบหน่วยที่มีวัตถุใหม่มากกว่า 1 ชิ้น

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


10

ลักษณะของการทดสอบของคุณ

การทดสอบหน่วยของโมดูล X เป็นการทดสอบที่คาดว่าจะเกิดปัญหา (และตรวจสอบ) เฉพาะในโมดูล X

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

นึกถึงลักษณะของการทดสอบของคุณในเงื่อนไขต่อไปนี้:

  • การลดความเสี่ยง : นั่นคือการทดสอบที่มีไว้สำหรับ การรวมกันของการทดสอบหน่วยและการทดสอบการรวมกันเท่านั้นที่สามารถลดความเสี่ยงได้อย่างสมบูรณ์เพราะการทดสอบแบบมือเดียวนั้นไม่สามารถทดสอบการมีปฏิสัมพันธ์ที่เหมาะสมระหว่างโมดูลและการทดสอบการรวมเข้าด้วยกันอื่น ๆ ในระดับเล็กน้อย
  • ความพยายามในการเขียนการทดสอบ : การทดสอบการรวมเข้าด้วยกันสามารถประหยัดความพยายามได้เนื่องจากคุณอาจไม่จำเป็นต้องเขียนสตับ / fakes / mocks แต่การทดสอบหน่วยสามารถประหยัดความพยายามได้เช่นกันเมื่อดำเนินการ (และบำรุงรักษา!) สิ่งที่ไม่เหมาะสมเหล่านั้นจะง่ายกว่าการกำหนดค่าการตั้งค่าการทดสอบโดยที่ไม่ต้องทำการทดสอบ
  • การทดสอบการดำเนินการล่าช้า : การทดสอบการรวมที่เกี่ยวข้องกับการดำเนินงานหนา (เช่นการเข้าถึงระบบภายนอกเช่นฐานข้อมูลหรือเซิร์ฟเวอร์ระยะไกล) มีแนวโน้มที่จะช้า (เอ้อ) ซึ่งหมายความว่าสามารถทำการทดสอบหน่วยบ่อยครั้งมากขึ้นซึ่งจะช่วยลดความพยายามในการดีบั๊กหากมีสิ่งใดล้มเหลวเนื่องจากคุณมีความคิดที่ดีกว่าว่าคุณเปลี่ยนแปลงอะไรในระหว่างนี้ สิ่งนี้มีความสำคัญอย่างยิ่งหากคุณใช้การพัฒนาที่ขับเคลื่อนด้วยการทดสอบ (TDD)
  • ความพยายามในการดีบัก : หากการทดสอบการรวมล้มเหลว แต่ไม่มีการทดสอบหน่วยใด ๆ สิ่งนี้อาจไม่สะดวกมากเนื่องจากมีรหัสจำนวนมากที่เกี่ยวข้องซึ่งอาจมีปัญหา นี่ไม่ใช่ปัญหาใหญ่หากคุณเปลี่ยนไปเพียงไม่กี่บรรทัดก่อนหน้านี้ แต่เมื่อการทดสอบการรวมทำงานช้าคุณอาจไม่ได้รันในช่วงเวลาสั้น ๆ เช่นนี้ ...

โปรดจำไว้ว่าการทดสอบการรวมระบบอาจยังไม่สมบูรณ์ / ปลอมแปลง / เลียนแบบการอ้างอิงบางส่วน สิ่งนี้จะให้ข้อมูลกลางระหว่างการทดสอบหน่วยและการทดสอบระบบ (การทดสอบการรวมระบบที่ครอบคลุมที่สุดการทดสอบระบบทั้งหมด)

วิธีปฏิบัติในการใช้ทั้งสองอย่าง

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


10

ในการทดสอบหน่วยคุณทดสอบทุกส่วนที่แยกได้: ป้อนคำอธิบายรูปภาพที่นี่

ในการทดสอบการรวมคุณจะทดสอบหลายโมดูลในระบบของคุณ:

ป้อนคำอธิบายรูปภาพที่นี่

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

ป้อนคำอธิบายรูปภาพที่นี่

แหล่งที่มา: source1 ที่มา 2


คุณมีสามภาพ แต่มีเพียงสองแหล่งเท่านั้น
gerrit

1
@gerrit ลองดูที่แหล่งข้อมูลแรก - มีสองภาพจากที่นั่น
Michu93

1
รักคำตอบนี้👏
Dzenis H.

8

ในความคิดของฉันคำตอบคือ "ทำไมมันถึงสำคัญ?"

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

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

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

เป็นเพราะการทดสอบหน่วยทดสอบหนึ่งหน่วยและการทดสอบบูรณาการทดสอบจำนวนหน่วย? ไม่แน่นอน สิ่งที่สำคัญในทางปฏิบัติคืออะไร? การอภิปรายเชิงทฤษฎีเกี่ยวกับขอบเขตของการทดสอบแบ่งย่อยในทางปฏิบัติต่อไปเพราะคำว่า "หน่วย" นั้นขึ้นอยู่กับบริบททั้งหมด ในระดับชั้นเรียนหน่วยอาจเป็นวิธีการ ในระดับการประกอบหน่วยอาจเป็นระดับและในระดับบริการหน่วยอาจเป็นส่วนประกอบ และแม้แต่คลาสก็ใช้คลาสอื่นด้วยซึ่งเป็นหน่วย?

มันไม่มีความสำคัญ

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


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

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

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

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

4

ฉันคิดว่าฉันจะยังคงเรียกชั้นเรียนที่มีการโต้ตอบสองครั้งที่การทดสอบหน่วยโดยที่การทดสอบหน่วยสำหรับ class1 นั้นเป็นการทดสอบคุณสมบัติของ class1 และการทดสอบหน่วยสำหรับ class2 กำลังทดสอบคุณสมบัติของมันและพวกเขาไม่ได้กดฐานข้อมูล

ฉันเรียกการทดสอบการทดสอบการรวมระบบเมื่อทำงานผ่านสแต็กส่วนใหญ่ของฉันและยังพบฐานข้อมูล

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


4

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

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

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


4

การทดสอบหน่วยเป็นวิธีการทดสอบที่ตรวจสอบว่าแต่ละหน่วยของซอร์สโค้ดทำงานอย่างถูกต้อง

Integration Testingเป็นขั้นตอนของการทดสอบซอฟต์แวร์ที่แต่ละโมดูลซอฟต์แวร์รวมและทดสอบเป็นกลุ่ม

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


4

การทดสอบการรวม: การทดสอบฐานข้อมูลมีอยู่
การทดสอบหน่วย: การเข้าถึงฐานข้อมูลถูกจำลอง มีการทดสอบวิธีการของรหัส


3

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

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

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


2

ฉันเรียกหน่วยทดสอบว่าการทดสอบกล่องสีขาวทดสอบคลาส การอ้างอิงใด ๆ ที่คลาสนั้นต้องการจะถูกแทนที่ด้วยของปลอม (mocks)

การทดสอบการรวมกันเป็นการทดสอบที่มีหลายคลาสและมีการทดสอบการโต้ตอบในเวลาเดียวกัน มีเพียงการอ้างอิงในบางกรณีเท่านั้นที่ถูกแกล้ง / เยาะเย้ย

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

การแยกการทดสอบสองประเภทนั้นมีประโยชน์สำหรับการทดสอบระบบในระดับต่างๆ นอกจากนี้การทดสอบการรวมมักจะใช้เวลานานและการทดสอบแบบหน่วยควรจะรวดเร็ว ความแตกต่างความเร็วการดำเนินการหมายความว่าพวกเขาดำเนินการแตกต่างกัน ในกระบวนการพัฒนาของเราการทดสอบหน่วยจะดำเนินการเมื่อทำการเช็คอิน (ซึ่งก็เพราะพวกมันเร็วมาก) และการทดสอบแบบรวมจะทำงานหนึ่งครั้ง / สองครั้งต่อวัน ฉันพยายามเรียกใช้การทดสอบการรวมระบบบ่อยที่สุดเท่าที่จะเป็นไปได้ แต่มักจะกดปุ่มฐานข้อมูล / เขียนไปยังไฟล์ / ทำให้ rpc's / etc ทำงานช้าลง

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


2

คำอธิบายอย่างง่ายพร้อมระบบอะนาล็อก

ตัวอย่างข้างต้นทำได้ดีมากและฉันไม่ต้องการทำซ้ำ ดังนั้นฉันจะเน้นการใช้ตัวอย่างเพื่อช่วยให้คุณเข้าใจ

การทดสอบบูรณาการ

การทดสอบการรวมระบบตรวจสอบว่าทุกอย่างทำงานร่วมกันหรือไม่ ลองนึกภาพชุดฟันเฟืองที่ทำงานร่วมกันในนาฬิกา การทดสอบการรวมจะเป็น: นาฬิกาบอกเวลาถูกต้องหรือไม่ มันยังบอกเวลาที่ถูกต้องใน 3 วัน?

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

ทดสอบหน่วย

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

ตัวอย่าง: ลองทำอย่างละเอียดในจุดนี้โดยใช้ตัวอย่าง:

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

การใช้สตับ

  • สมมติว่าการทดสอบการรวมรถของคุณล้มเหลว มันขับไม่สำเร็จไปยัง Echuca ปัญหาอยู่ที่ไหน

  • ตอนนี้ให้เราสมมติว่าเครื่องยนต์ของคุณใช้ระบบฉีดเชื้อเพลิงแบบพิเศษและการทดสอบหน่วยเครื่องยนต์นี้ก็ล้มเหลวเช่นกัน กล่าวอีกนัยหนึ่งทั้งการทดสอบการรวมและการทดสอบหน่วยเครื่องยนต์ล้มเหลว ปัญหาอยู่ที่ไหน (ให้เวลา 10 วินาทีในการรับคำตอบ)

  • เกิดปัญหากับเครื่องยนต์หรือระบบการฉีดน้ำมันเชื้อเพลิงหรือไม่?

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


1

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


1

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

ฉันคิดว่าใช่และใช่ การทดสอบหน่วยของคุณที่ครอบคลุม 2 คลาสกลายเป็นการทดสอบการรวม

คุณสามารถหลีกเลี่ยงได้โดยการทดสอบคลาสประโยคด้วยการใช้งานจำลอง - คลาส MockWord ซึ่งเป็นสิ่งสำคัญเมื่อส่วนต่าง ๆ ของระบบมีขนาดใหญ่พอที่จะนำไปใช้โดยนักพัฒนาที่แตกต่างกัน ในกรณีที่ Word ทดสอบโดยหน่วยเดียวประโยคจะถูกทดสอบโดยใช้หน่วยความจำของ MockWord และประโยคนั้นจะทำการทดสอบการรวมกับ Word

ความแตกต่างที่แท้จริงสามารถติดตามได้ 1) อาร์เรย์ขององค์ประกอบ 1,000,000 ชุดทดสอบได้ง่ายและทำงานได้ดี 2) BubbleSort สามารถทดสอบหน่วยต่างๆในอาร์เรย์จำลองขององค์ประกอบ 10 รายการได้อย่างง่ายดายและยังใช้งานได้ดี 3) การทดสอบการรวมแสดงให้เห็นว่ามีบางสิ่งที่ไม่ดี

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


1

นอกจากนี้สิ่งสำคัญคือต้องจำไว้ว่าทั้งการทดสอบหน่วยและการทดสอบการรวมสามารถเป็นแบบอัตโนมัติและเขียนโดยใช้ตัวอย่างเช่น JUnit ในการทดสอบการรวม JUnit เราสามารถใช้org.junit.Assumeคลาสเพื่อทดสอบความพร้อมใช้งานขององค์ประกอบสภาพแวดล้อม (เช่นการเชื่อมต่อฐานข้อมูล) หรือเงื่อนไขอื่น ๆ


0

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

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

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