จะทดสอบอย่างไร?


53

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

ฉันสามารถคิดถึงข้อผิดพลาดสามประเภทที่เป็นไปได้ในการทดสอบ:

  1. ข้อผิดพลาดเชิงตรรกะเมื่อโปรแกรมเมอร์เข้าใจผิดงานในมือและการทดสอบทำในสิ่งที่เขาคิดว่าพวกเขาควรทำซึ่งผิด

  2. ข้อผิดพลาดในกรอบการทดสอบพื้นฐาน (เช่น. การเยาะเย้ยสิ่งที่เป็นนามธรรม);

  3. ข้อบกพร่องในการทดสอบ: การทดสอบทำแตกต่างจากที่โปรแกรมเมอร์คิดไว้เล็กน้อย

ข้อผิดพลาดประเภท (1) ดูเหมือนว่าเป็นไปไม่ได้ที่จะป้องกัน (เว้นแต่ว่าโปรแกรมเมอร์เพิ่ง ... ฉลาดขึ้น) อย่างไรก็ตาม (2) และ (3) อาจถูกเวไนยได้ คุณจัดการกับข้อผิดพลาดประเภทนี้อย่างไร คุณมีกลยุทธ์พิเศษเพื่อหลีกเลี่ยงพวกเขาหรือไม่? ตัวอย่างเช่นคุณเขียนการทดสอบแบบ "ว่างเปล่า" เป็นพิเศษหรือไม่ซึ่งเป็นการตรวจสอบเพียงข้อสันนิษฐานของผู้เขียนทดสอบเท่านั้น นอกจากนี้คุณจะแก้ไขข้อบกพร่องในกรณีทดสอบอย่างไร


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

@ Carson63000 ถ้ามันเป็นการทดสอบง่ายๆที่ทดสอบบางอย่างด้วยการจำลองการทดสอบความซับซ้อนจะถูกแยกออกและอยู่ภายใต้การควบคุม (ฉันคิดว่า)
mlvljr

13
แต่คุณจะทดสอบการทดสอบอย่างไร
ocodo

+1 รายการ 1 อาจเป็นข้อผิดพลาดของข้อกำหนด สามารถป้องกันได้โดยการตรวจสอบข้อกำหนด อาจอยู่ในมือของโปรแกรมเมอร์หากไม่ได้เป็นนักวิเคราะห์ข้อกำหนด
MarkJ

@ocodo: วิธีเดียวกับที่คุณดู Watchers :)
Greg Burghardt

คำตอบ:


18

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

  1. มีเทคนิคบางอย่างที่ป้องกันคุณจากการเพิ่มข้อผิดพลาดเดียวกันทั้งในรหัสและการทดสอบของคุณ:

    1. ไคลเอ็นต์ควรเป็นบุคคลที่แตกต่างจากผู้ปฏิบัติ
    2. ก่อนอื่นให้เขียนการทดสอบแล้วจึงใช้รหัส
  2. คุณไม่จำเป็นต้องทดสอบแพลตฟอร์มพื้นฐาน การทดสอบไม่เพียงแค่ออกกำลังกายโค้ดที่คุณเขียนเท่านั้น แต่ยังทำการทดสอบโค้ดจากแพลตฟอร์มอีกด้วย ในขณะที่คุณไม่จำเป็นต้องการดักจับข้อบกพร่องในแพลตฟอร์มการทดสอบนั้นยากมากในการเขียนโค้ดและการทดสอบที่มักจะซ่อนข้อบกพร่องในแพลตฟอร์มในคำอื่น ๆ ยากที่จะมีข้อบกพร่องอย่างเป็นระบบทั้งในการทดสอบ / รหัสและ ในแพลตฟอร์มและความน่าจะเป็นจะลดลงเมื่อคุณทำการทดสอบแต่ละครั้ง แม้ว่าคุณจะพยายามทำสิ่งนี้คุณก็จะมีงานที่หนักมาก

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


คำตอบที่ดีมาก ฉันชอบความคิดของการวนซ้ำตัวเองเสริมระหว่างการทดสอบและรหัสและการสังเกตว่ามันยากที่จะเขียนการทดสอบที่ซ่อนข้อบกพร่องในแพลตฟอร์มพื้นฐานอย่างสม่ำเสมอ
Ryszard Szopa

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

24

ลองทำแบบทดสอบย่อย ๆ (สั้น) เท่าที่จะทำได้

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

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


3
เกิดอะไรขึ้นถ้าการทดสอบจำเป็นต้องมีการติดตั้งที่ค่อนข้างซับซ้อน? บางครั้งสิ่งเหล่านี้ไม่ได้อยู่ภายใต้การควบคุมของคุณ
Ryszard Szopa

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

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

2
การทดสอบของคุณควรล้มเหลวหากเงื่อนไขเริ่มต้นไม่ถูกต้องนั่นคือจุดรวม เมื่ออยู่ในสถานะที่คุณคาดหวังส่งผลให้เกิดA Bหากคุณไม่มีสถานะAการทดสอบควรล้มเหลว ณ จุดนี้คุณสามารถตรวจสอบสาเหตุที่ล้มเหลวเงื่อนไขเริ่มต้นไม่ดีหรือทดสอบไม่ดี แต่ควรล้มเหลวในทั้งสองกรณี ถึงแม้ว่าจะเป็นตามที่คุณพูดว่า "เล็กน้อยปิด" (คือ"A" => "B", "a" => "b"แต่ไม่เคย"a" => "B"หรือการทดสอบของคุณไม่ดี)
ดร. Hannibal Lecter

19

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

วิธีที่ครบถ้วนสมบูรณ์มากขึ้นในการทดสอบคุณภาพของชุดทดสอบคือการใช้การทดสอบการกลายพันธุ์


2
และว่าการทดสอบของคุณล้มเหลวสำหรับเหตุผลที่เหมาะสม
Frank Shearar

@ Frank - ใช่ ฉันจะเพิ่มเข้าไปในคำตอบ
Don Roby

และคุณกำลังเพิ่มการทดสอบใหม่สำหรับพฤติกรรมใหม่ที่จะทดสอบ อย่าเพิ่มการทดสอบที่มีอยู่
Huperniketes

@ DonRoby คุณพบว่าการทดสอบการกลายพันธุ์มีประโยชน์ในทางปฏิบัติหรือไม่ มีข้อบกพร่องอะไรบ้างที่คุณพบในกรณีทดสอบด้วย?
dzieciou

4

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

ดูวิดีโอนี้โดย Roy Osheroveเพื่อเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการเขียนการทดสอบหน่วยดี


โฆษณา # 3 - ฉันยอมรับว่าการทดสอบควรเรียบง่ายที่สุดและไม่ควรมีตรรกะใด ๆ อย่างไรก็ตามให้คิดถึงขั้นตอนการตั้งค่าของการทดสอบเมื่อคุณสร้างวัตถุที่ต้องการ คุณอาจสร้างวัตถุที่ผิดเล็กน้อย นี่คือปัญหาที่ฉันคิด
Ryszard Szopa

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

3

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


2

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

if (0 > printf("Hello, world\n")) {
  printf("Printing \"Hello, world\" failed\n");
}

แก้ไข: อัปเดตพร้อมคำอธิบายตามที่แนะนำโดยความคิดเห็น


-1 อะไรนะ ดูเหมือนว่าจะไม่มีความเกี่ยวข้อง
ทางเลือก

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

2
Process Brain ฟื้นคืนชีพ EInfiniteRecursion ในขณะที่พยายามคาดการณ์ข้อความของคุณ ...
Mason Wheeler

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

3
ตัวอย่างของคุณคือคนฟาง คุณกำลังทดสอบระบบย่อย printf () ในไลบรารี C ไม่ใช่โปรแกรมจริงที่เรียกใช้ printf () อย่างไรก็ตามฉันเห็นด้วยว่าในบางจุดเราต้องหยุดการทดสอบซ้ำแบบทดสอบซ้ำ
Tim Post

2

เฮ้
คุณต้องสมัคร:

  • ผลิตภัณฑ์ของคุณ
  • การทดสอบผลิตภัณฑ์ของคุณ

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

  • แอปพลิเคชันไม่ทำงานตามที่คุณคาดหวัง (ความคาดหวังนี้แสดงในการทดสอบของคุณ)
  • แอปพลิเคชันทำงานอย่างถูกต้องคุณเพิ่งไม่ได้บันทึกพฤติกรรมนี้อย่างถูกต้อง (ในการทดสอบของคุณ)

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

การทดสอบกำลังตรวจสอบบางส่วนของแอปพลิเคชันเท่านั้น ฉันทดสอบแอปพลิเคชันฉันทดสอบการทดสอบ


2

การทดสอบไม่ควร "ฉลาด" เพียงพอที่จะใช้ดักจับข้อบกพร่อง

รหัสที่คุณกำลังเขียนใช้ชุดข้อมูลจำเพาะ (ถ้า X เป็น Y ยกเว้น Z ในกรณีที่ Q เป็นต้น ฯลฯ ) การทดสอบทั้งหมดควรพยายามทำให้สำเร็จคือการพิจารณาว่า X จริงๆคือ Y ยกเว้น Z ในกรณีที่ถามซึ่งหมายความว่าการทดสอบทั้งหมดที่ควรทำคือการตั้งค่า X และการตรวจสอบ Y

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

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

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

TL: DR: ถ้าการทดสอบของคุณต้องการการทดสอบแสดงว่าคุณทำผิด เขียนทดสอบใบ้


0

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


0

คำตอบสั้น: รหัสการผลิตการทดสอบการทดสอบ

เปรียบเทียบสิ่งนี้กับโมเดลเครดิต / เดบิตที่ใช้ในเศรษฐศาสตร์ กลไกนั้นง่ายมาก - ถ้าเครดิตแตกต่างจากเดบิตมีบางอย่างผิดปกติ

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

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

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