เราควรทดสอบวิธีการทั้งหมดของเราหรือไม่?


61

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

SomeClass getSomething(parameters) {
    return myDao.findSomethingBySomething(parameters);
}

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

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

  • getters และ setters (ยกเว้นว่าพวกเขามีเหตุผลบางอย่างในตัวพวกเขา)
  • รหัส "สำเร็จรูป"

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

มีเหตุผลหรือไม่ "ติดไฟ" เหตุผลที่ทำไมควรทดสอบทุกบรรทัดเดียว (หรือมากที่สุดเท่าที่เขาสามารถ) รหัส?


2
ฉันยังคงคิดคำถามนี้อยู่ แต่นี่เป็นคำพูดของคนที่ตัดสินใจว่าคำตอบคือ "ไม่" เอียนคูเปอร์: TDD มันผิดพลาดไปไหนเพื่อสรุปคำปราศรัยที่ยิ่งใหญ่นี้คุณควรทดสอบภายนอกและทดสอบพฤติกรรมใหม่ไม่ใช่วิธีการใหม่
Daniel Kaplan

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


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

คำตอบ:


48

ฉันไปตามกฎง่ายๆของ Kent Beck:

ทดสอบทุกอย่างที่อาจทำลายได้

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

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


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

5
@ Zenzen: "สิ่งที่สามารถทำลายที่นี่หรือไม่ไม่มาก" - ดังนั้นมันสามารถแตก แค่พิมพ์เล็ก ๆ หรือบางคนเพิ่มรหัสบางอย่าง หรือความยุ่งเหยิงขึ้นอยู่กับการพึ่งพา ฉันคิดว่าเบ็คจะอ้างว่าตัวอย่างหลักของคุณมีคุณสมบัติเปราะบาง Getters และ setters น้อยกว่านั้นถึงแม้ว่าฉันจะทำให้ตัวเองมีข้อผิดพลาดในการคัดลอก / วางแม้แล้ว คำถามจริงคือถ้ามันเล็กเกินไปที่จะเขียนการทดสอบทำไมมันถึงมีอยู่?
pdr

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

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

7
การทดสอบทุกอย่างที่สุ่มสี่สุ่มห้าอาจทำให้ไม่เข้าใจ จำเป็นต้องมีกลยุทธ์ที่จะต้องทดสอบองค์ประกอบที่มีความเสี่ยงสูงก่อน
CodeART

12

การทดสอบหน่วยมีไม่กี่ประเภท:

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

หากคุณต้องเขียนการทดสอบของคุณก่อนมันจะเหมาะสมกว่า - อย่างที่คุณคาดว่าจะเรียก data access layer การทดสอบจะล้มเหลวในขั้นต้น จากนั้นคุณจะเขียนรหัสการผลิตเพื่อทำแบบทดสอบ

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

  • ตรวจสอบว่าฉันเรียก data access layer พร้อมพารามิเตอร์ที่แน่นอนซึ่งส่งผ่านมา
  • ตรวจสอบว่ามันถูกเรียกเพียงครั้งเดียว
  • ตรวจสอบว่าฉันส่งคืนสิ่งที่มอบให้ฉันโดย data access layer มิฉะนั้นฉันก็อาจกลับมาเป็นโมฆะ

ขณะนี้ไม่มีตรรกะอยู่ที่นั่น แต่มันจะไม่เป็นเช่นนั้นเสมอไป

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

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

ต้องบอกว่าทั้งหมดนี้ - ฉันจะไม่ทดสอบทุกอย่างสุ่มสี่สุ่มห้า ฉันจะสร้างฮอตสปอต (ส่วนประกอบที่มีความซับซ้อนสูงและมีความเสี่ยงสูงที่จะแตกหัก) ฉันจะให้ความสนใจกับส่วนประกอบเหล่านี้ ไม่มีจุดใดที่จะมี codebase ที่ 90% ของ codebase นั้นค่อนข้างตรงไปตรงมาและถูกครอบคลุมโดยการทดสอบหน่วยเมื่อเหลือ 10% จะเป็นตัวแทนหลักตรรกะของระบบและไม่ครอบคลุมการทดสอบหน่วยเนื่องจากความซับซ้อน

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


ทำไมคุณถึงตรวจสอบว่า DAL ของคุณถูกเรียกเพียงครั้งเดียว
Marjan Venema

9

นี่คือวิธีที่ดีในการคิดเกี่ยวกับคุณภาพของซอฟต์แวร์ของคุณ:

  1. การตรวจสอบชนิดเป็นการจัดการส่วนหนึ่งของปัญหา
  2. การทดสอบจะจัดการกับส่วนที่เหลือ

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


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

6

ในความเห็นของฉันความซับซ้อนตามวัฏจักรเป็นพารามิเตอร์ หากวิธีการไม่ซับซ้อนพอ (เช่น getters และ setters) ไม่จำเป็นต้องทำการทดสอบหน่วย ระดับความซับซ้อน Cyclomatic ของ McCabe ควรมากกว่า 1 คำอื่นควรมีคำสั่งบล็อกอย่างน้อย 1 คำ


จำ getters หรือ setters บางอย่างที่มีผลข้างเคียง (แม้ว่าจะท้อแท้และถือว่าการปฏิบัติที่ไม่ดีในกรณีส่วนใหญ่) ดังนั้นการเปลี่ยนแปลงในซอร์สโค้ดของคุณอาจส่งผลกระทบต่อมัน
Andrzej Bobak

3

YES ที่ดังก้องด้วย TDD (และมีข้อยกเว้นเล็กน้อย)

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

สำหรับฉันคำตอบคือดังก้องใช่ถ้าคุณทำตาม TDD หากคุณไม่ได้ไม่ใช่คำตอบที่เป็นไปได้

DDD ใน TDD

TDD มักอ้างว่าให้ประโยชน์หลักแก่เจ้า

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

แยกความรับผิดชอบจากการปฏิบัติ

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

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

มันสำคัญกว่าการสะกดว่าวัตถุควร:

อนุญาตให้ลูกค้าเปลี่ยนสถานะ

และ

อนุญาตให้ไคลเอนต์เพื่อสอบถามสถานะ

ดังนั้นวิธีการจัดเก็บสถานะนี้จริง ๆ (ซึ่งเป็นแอตทริบิวต์ที่พบมากที่สุด แต่ไม่ใช่วิธีเดียว)

การทดสอบเช่น

(The Painter class) should store the provided colour

เป็นสิ่งสำคัญสำหรับส่วนเอกสารของ TDD

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

ขาดวิศวกรรมไปกลับ ...

หนึ่งในปัญหาสำคัญในโลกของการพัฒนาระบบคือการขาด วิศวกรรมไปกลับ1 - กระบวนการพัฒนาของระบบถูกแยกส่วนเป็นกระบวนการย่อยที่แยกจากกันซึ่งเป็นสิ่งประดิษฐ์ที่ (เอกสาร, รหัส) มักไม่สอดคล้องกัน

1 Brodie, Michael L. "John Mylopoulos: การเย็บเมล็ดของการสร้างแบบจำลองแนวคิด" การสร้างแบบจำลองแนวคิด: รากฐานและการประยุกต์ Springer Berlin Heidelberg, 2009. 1-9.

... และวิธีการแก้ปัญหาของ TDD

เป็นส่วนเอกสารของ TDD ที่ทำให้มั่นใจได้ว่าข้อกำหนดของระบบและรหัสของมันสอดคล้องกันเสมอ

ออกแบบก่อนใช้ในภายหลัง

ภายใน TDD เราเขียนการทดสอบการยอมรับที่ล้มเหลวก่อนจากนั้นเขียนโค้ดที่ให้พวกเขาผ่าน

ภายใน BDD ระดับสูงกว่าเราเขียนสถานการณ์ก่อนจากนั้นจึงทำให้มันผ่าน

เหตุใดคุณจึงควรยกเว้นผู้ตั้งค่าและผู้ทะเยอทะยาน?

ในทางทฤษฎีมันเป็นไปได้อย่างสมบูรณ์แบบใน TDD สำหรับคนคนหนึ่งที่จะเขียนการทดสอบและอีกคนหนึ่งที่จะใช้รหัสที่ทำให้มันผ่าน

ดังนั้นถามตัวเอง:

บุคคลที่เขียนแบบทดสอบสำหรับชั้นเรียนควรพูดถึงผู้ได้รับและผู้ตั้งตัว

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

เห็นได้ชัดว่าถ้าคุณเขียนรหัสก่อนคำตอบอาจไม่ชัดเจน

ข้อยกเว้น

มีข้อยกเว้นบางประการที่ชัดเจนสำหรับกฎนี้ - ฟังก์ชั่นที่มีรายละเอียดการนำไปใช้งานที่ชัดเจนและไม่ได้เป็นส่วนหนึ่งของการออกแบบระบบอย่างชัดเจน

ตัวอย่างเช่นวิธีโลคอล 'B ()':

function A() {

    // B() will be called here    

    function B() {
        ...
    }
} 

หรือฟังก์ชั่นส่วนตัวsquare()ที่นี่:

class Something {
private:
    square() {...}
public:
    addAndSquare() {...}
    substractAndSquare() {...}
}

หรือฟังก์ชั่นอื่น ๆ ที่ไม่ได้เป็นส่วนหนึ่งของส่วนpublicต่อประสานที่ต้องการการสะกดคำในการออกแบบส่วนประกอบของระบบ


1

เมื่อต้องเผชิญกับคำถามทางปรัชญาให้ถอยกลับไปที่ข้อกำหนดการขับขี่

เป้าหมายของคุณคือการผลิตซอฟต์แวร์ที่มีความน่าเชื่อถือในราคาที่เหมาะสมหรือไม่?

หรือว่าจะผลิตซอฟต์แวร์ที่มีความน่าเชื่อถือสูงสุดเท่าที่จะเป็นไปได้โดยไม่คำนึงถึงต้นทุน

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

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

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

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


0

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

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


0

มันเป็นคำถามที่ยุ่งยาก

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

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

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

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


-1

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

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

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

คิดในคุณสมบัติ / พฤติกรรมที่ไม่ได้อยู่ในคลาสเมธอดฉันไม่สามารถทำซ้ำครั้งนี้ได้


-4

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

ใช่นึกคิด 100% แต่บางสิ่งไม่สามารถทดสอบได้

getters และ setters (ยกเว้นว่าพวกเขามีเหตุผลบางอย่างในตัวพวกเขา)

Getters / Setters เป็นคนโง่ - อย่าใช้มัน ให้วางตัวแปรสมาชิกของคุณลงในส่วนสาธารณะ

รหัส "สำเร็จรูป"

รับรหัสทั่วไปและทดสอบหน่วย นั่นควรจะง่ายอย่างที่คิด

มีเหตุผลหรือไม่ "ติดไฟ" เหตุผลที่ทำไมควรทดสอบทุกบรรทัดเดียว (หรือมากที่สุดเท่าที่เขาสามารถ) รหัส?

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

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


ทีนี้ลองทำสิ่งหนึ่งให้ตรง: ฉันไม่ได้หมายความว่าฉันไม่ได้ใช้การทดสอบ TDD / การเขียน ค่อนข้างตรงกันข้าม ฉันรู้ว่าการทดสอบอาจพบข้อบกพร่องที่ฉันไม่ได้คิดถึง แต่จะมีการทดสอบอะไรที่นี่บ้าง ฉันแค่คิดว่าวิธีการดังกล่าวเป็นหนึ่งใน "ไม่ทดสอบหน่วย" ดังที่PéterTörökพูด (อ้างถึง Kent Beck) คุณควรทดสอบสิ่งของที่อาจแตกหักได้ สิ่งที่อาจแตกที่นี่ ไม่มาก (มีเพียงการมอบหมายอย่างง่ายในวิธีนี้) ฉันสามารถเขียนการทดสอบหน่วย แต่มันจะมีการเยาะเย้ยของ DAO และยืนยันการทดสอบไม่มาก สำหรับ getters / setters เฟรมเวิร์กบางตัวต้องการมัน
Zenzen

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

20
-1 สำหรับ"Getters / Setters นั้นโง่ - อย่าใช้มันแทนให้ใส่ตัวแปรสมาชิกของคุณไปยังส่วนสาธารณะ" - ผิดมาก นี้ได้รับการกล่าวถึงหลายครั้ง ในดังนั้น การใช้ฟิลด์สาธารณะในทุกที่นั้นแย่กว่าการใช้ getters และ setters ทุกที่
PéterTörök
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.