การทดสอบหน่วยกล่องดำคืออะไร


11

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

Unit Testing is considered:
a. White-box Testing
b. Black-box Testing
c. Either

ในประสบการณ์การพัฒนาซอฟต์แวร์ 7 ปีของฉันการทดสอบหน่วยได้ใช้แนวทางกล่องสีขาวเสมอ ผู้ทดสอบมีความรู้เต็มรูปแบบเกี่ยวกับการใช้งานหน่วยการเรียนรู้ในขณะที่เขียนการทดสอบ การทดสอบกล่องดำมาในภายหลังในรูปแบบของการรวมระบบและการทดสอบการยอมรับ

อย่างไรก็ตามคำตอบที่ถูกต้องในการสอบ (ตามอาจารย์) คือการทดสอบหน่วยสามารถเป็นการทดสอบกล่องสีขาวหรือกล่องดำ

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

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


4
อาจารย์อธิบายได้อย่างไรเมื่อคุณถามพวกเขาเกี่ยวกับเรื่องนี้ (ดูเพิ่มเติมทำไมคำถามสัมภาษณ์ทำให้วิศวกรรมซอฟต์แวร์ไม่ดีคำถาม
SE

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

@Jesper ขอโทษ ฉันหมายถึงการพูดว่า "ซอร์สโค้ดจะถูกนำไปใช้อย่างไร" ฉันได้แก้ไขมันแล้วในคำถาม
backcab

2
While the implementation does not yet exist, whoever is writing the test generally has a pretty good idea about how the source code is going to be implemented.- ใช่ แต่การทดสอบไม่ได้ การทดสอบกล่องขาวหมายถึงการทดสอบบางอย่างภายในเมธอดหรือคลาสเช่นค่าของตัวแปร ไม่ได้หมายความว่าผู้เขียนทดสอบรู้ว่าโค้ดภายใต้การทดสอบมีลักษณะอย่างไร
Robert Harvey

คำตอบ:


20

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

ด้วยการทดสอบกล่องดำคุณจะเห็นเฉพาะอินเทอร์เฟซและ (ถ้ามี) ข้อกำหนดสำหรับส่วนประกอบ เมื่อฟังก์ชั่นมีลายเซ็นต์int foo(int a, int b)ฉันก็สามารถสร้างกรณีทดสอบเพียงไม่กี่กรณีโดยการทดสอบจำนวนเต็มที่น่าสนใจ: ศูนย์หนึ่งลบหนึ่งตัวเลขหลายหลัก INT_MAX, INT_MAX - 1 และอื่น ๆ การทดสอบกล่องดำนั้นดีมากเพราะเป็นอิสระจากการใช้งาน แต่พวกเขาอาจพลาดกรณีสำคัญ

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

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


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

4

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

ท้ายที่สุดเมื่อคุณเขียนการทดสอบคุณจะทดสอบอะไร วิธีการ / ฟังก์ชั่นสาธารณะ

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

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

พิจารณา'การทดสอบในห้องน้ำ - พฤติกรรมการทดสอบที่ไม่ได้นำไปใช้'ซึ่งการใช้งานในชั้นเรียนจะเปลี่ยนไป แต่การทดสอบควรจะยังคงถูกต้อง

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


2
If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right?- ไม่แน่นอน สัญญา API ส่วนใหญ่จะระบุเฉพาะลายเซ็นวิธีเท่านั้นไม่ใช่ความหมายหรือพฤติกรรม
Robert Harvey

คุณถูก; ฉันใช้มันเป็นอินเทอร์เฟซของคุณที่จะรวมข้อมูลจำเพาะที่มันถูกเขียนไม่ใช่แค่ข้อความของ MyClassInterface
AdamJS

@RobertHarvey มันเป็นความจริงที่ว่าอินเตอร์เฟสส่วนใหญ่ไม่ได้อธิบายความหมายหรือพฤติกรรมอย่างชัดเจน แต่ฉันคิดว่ามันมีนัยโดยปริยาย หากไม่มีโค้ดที่ต้องการซีแมนทิกส์บางอย่างจะไม่สามารถพึ่งพาสิ่งที่เป็นนามธรรมได้ และไม่มีอะไรที่จะหยุดอินเทอร์เฟซรวมถึงรายละเอียดของความหมายและพฤติกรรมเป็นความคิดเห็น / docblocs ตัวอย่างเช่นดูgithub.com/php-fig/http-message/blob/master/src/
......

3

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

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

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


1

ฉันอยู่ในขั้นตอนของการเขียนการทดสอบหน่วยซึ่งทำการทดสอบกล่องดำ นั่นคือฉันกำลังทดสอบวิธีสาธารณะในชั้นเรียนและโดยนัยของตรรกะการทดสอบผลลัพธ์ในวิธีส่วนตัวที่พวกเขาเรียก

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

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

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