การทดสอบแบบกำหนดพารามิเตอร์ - เมื่อใดและเพราะเหตุใดคุณจึงใช้งาน


15

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

สิ่งที่ฉันเคยเห็นคือการทดสอบอย่างน้อยก็ใช้ JUnit ภายใน Eclipse:

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

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


1
ปัญหาไม่ได้เกิดจากความคิด แต่เกิดจากห้องสมุดที่มีความคิดไม่ดี ใน C # ไวยากรณ์เป็นวิธีที่เป็นมิตรเมื่อคุณใช้คำพูด MbUnit ใช่มันเป็นความคิดที่ดี เพิ่มรหัสของคุณเองเพื่อทำให้กระบวนการนี้ง่ายขึ้น - อ่านสิ่งต่าง ๆ จากไฟล์ - ทำงานได้ทุกอย่าง ดูว่า MsTest จัดการกับเรื่องนี้อย่างไร
งาน

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

คำตอบ:


4

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

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

ความผิดปกติบางแห่งอาจไม่สามารถระบุได้ แต่โดยทั่วไปจะน้อยกว่าความผิดปกติ

วิธีการ DOE ให้วิธีการอย่างเป็นระบบในการเลือกค่าพารามิเตอร์ที่จะเปลี่ยนแปลง


ลิงก์ที่ให้ไว้เสียหาย
Josh Gust

1
@JoshGust แก้ไขได้อย่างง่ายดายโดยใช้ Google ขอบคุณสำหรับหัวขึ้น.
Peter K.

4

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


2

มีการทดสอบแบบกำหนดพารามิเตอร์อย่างน้อยสองรสชาติอย่างน้อยใน JUnit 4.8 การทดสอบพารามิเตอร์ ( @RunWith(Parameterized.class)) ซึ่งต้องใช้แหล่งข้อมูลซึ่งสร้าง / อ่านการกำหนดค่าพารามิเตอร์ที่กำหนดไว้ล่วงหน้าและทฤษฎี ( @RunWith(Theories.class)) ซึ่งกำหนดหนึ่งอินพุตที่เป็นไปได้หนึ่งชุดหรือมากกว่าต่อประเภทอาร์กิวเมนต์สามารถใช้สเปคของวิธีการที่กำหนด มันดูเหมือนมากน้อยกว่านี้:

  • ระบุค่าที่เป็นไปได้บางอย่าง ( @DataPoints) สำหรับอาร์กิวเมนต์สตริง (เช่นnull, สตริงว่าง, สตริงที่ไม่ว่างเปล่า, สตริงที่ยาวมาก)
  • ระบุค่าที่เป็นไปได้บางส่วน ( @DataPoints) สำหรับอาร์กิวเมนต์ระดับสัตว์ (เช่นnull, Dogตัวอย่างCatเช่นBirdเป็นต้น)
  • เตรียม@Theoryว่าจะยอมรับStringพารามิเตอร์และAnimalพารามิเตอร์ใด มันจะได้รับการดำเนินการกับการรวมกันที่เป็นไปได้ของค่าพารามิเตอร์ที่เป็นไปได้ (ในตัวอย่างที่กำหนดว่าจะเป็น 4x4 = 16 ชุดรวมถึง ( null, null))
  • หากวิธีการทดสอบไม่สามารถยอมรับชุดค่าผสมได้ให้ใช้Assume.assumeThatการนำเข้าแบบคงที่เพื่อกรองชุดค่าผสมที่ไม่ถูกต้อง (เช่นเมื่อคุณต้องการตรวจสอบพฤติกรรมของวิธีการสำหรับสตริงที่ไม่ว่างเปล่าหนึ่งในบรรทัดแรกจะเป็น "ถือว่าไม่มีค่าว่าง"

ตามที่เขียนไว้ก่อนหน้านี้ - มันไม่สมเหตุสมผลเลยที่จะทดสอบการรวมกันที่เป็นไปได้ของทุกวิธี (มันจะระเบิดชุดทดสอบลองจินตนาการการทดสอบด้วยพารามิเตอร์ 5 ตัวแต่ละอันมีค่าที่เป็นไปได้ 5 ค่า: 5 ** 5 -> !) แต่สำหรับวิธีการที่สำคัญต่อภารกิจ (เช่นวิธีการ API) ฉันขอแนะนำเพียงเพื่อให้ปลอดภัย ...


1

ตัวอย่างทั่วไป:

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

  • ใช้สถานการณ์เดียวกันกับข้อโต้แย้งที่แตกต่างกัน เรามีสถานการณ์ที่ทำงานร่วมกับที่Animalวัตถุและมีจำนวนมากของ subclasses เช่นDog, ,Cat Birdสร้างรายการของสัตว์ที่มีอยู่และทดสอบสถานการณ์ในพวกเขา

คอนกรีตสำหรับบริการเว็บ:

  • จากตัวอย่างอาร์กิวเมนต์ของสตริงด้านบน ทดสอบสิ่งที่เกิดขึ้นกับอาร์กิวเมนต์ที่ต่างกันในประเภทเดียวกัน แต่มีค่าต่างกัน

0

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

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


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

1
คำตอบของคุณให้ข้อมูลมากกว่าคำตอบ 5 ข้ออื่น ๆ อย่างไร
Adam Zuckerman

-2

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

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


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