ข้อแตกต่างที่สำคัญสำหรับฉันคือการทดสอบการรวมตัวแสดงให้เห็นว่าคุณลักษณะทำงานหรือเสียเนื่องจากพวกเขาเน้นรหัสในสถานการณ์ที่ใกล้เคียงกับความเป็นจริง พวกเขาเรียกใช้หนึ่งหรือมากกว่าหนึ่งวิธีการซอฟต์แวร์หรือคุณสมบัติและทดสอบว่าพวกเขาทำตามที่คาดไว้
ในทางตรงกันข้ามการทดสอบหน่วยการทดสอบวิธีการเดียวอาศัยสมมติฐาน (มักจะผิด) ว่าส่วนที่เหลือของซอฟต์แวร์ทำงานอย่างถูกต้องเพราะมันชัดเจน 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 คลาส
คำตอบนี้เป็นพื้นเป็นบทสรุปของสิ่งที่ผมเขียนนี่: การทดสอบหน่วยโกหกที่ว่าทำไมฉันรักพวกเขา