คุณภาพของรหัสในการทดสอบหน่วย?


23

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

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


5
ความสามารถในการอ่านและบำรุงรักษาจะต้องเป็นจุดสนใจหลักของการทดสอบหน่วย
EL Yusubov

2
การทดสอบก็คือรหัสด้วย!
Grant Palin

มันยังคงเป็นส่วนหนึ่งของโครงการของคุณแม้ว่าจะไม่ได้ส่งมอบให้กับลูกค้า ปฏิบัติต่อมันอย่างเหมาะสม

คำตอบ:


11

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

การละเมิดกฎหมาย Demeter นั้นเป็นปัญหาอย่างหนึ่งในการทดสอบหน่วยของคุณด้วยเหตุผลนั้นเช่นเดียวกับคนอื่น ๆ อีก 2 คนที่หลุดจากใจฉัน:

  • หากการทดสอบของคุณผิดกฎหมายของ Demeter ในส่วนArrange หรือ Actของพวกเขาอาจเป็นสัญญาณว่ารหัสการผลิตของคุณก็ทำเช่นกันเนื่องจากการทดสอบหน่วยของคุณเป็นเพียงผู้บริโภครหัสของคุณอีกคนหนึ่งและอาจจะเรียกและดำเนินการชั้นเรียนภายใต้การทดสอบเดียวกัน วิธีการที่รหัสการผลิตอื่น ๆ จะทำ

  • หากการทดสอบของคุณผิดกฎของ Demeter ในส่วน Assert ของพวกเขา (เช่นคุณตรวจสอบค่าของบางสิ่งที่ซ้อนกันอย่างลึกลงไปในกราฟการพึ่งพาของวัตถุที่อยู่ภายใต้การทดสอบ) อาจเป็นได้ว่าเป็นการทดสอบบูรณาการมากกว่าการทดสอบหน่วย กล่าวอีกนัยหนึ่งถ้าใน TestA คุณยืนยันว่า ABCD เท่ากับอะไรบางอย่างมันอาจเป็นไปได้ว่าคุณกำลังพยายามทดสอบD และ Aมากกว่าแค่ A

โดยวิธีการเมื่อคุณพูด

ฉันทำผิดกฎของ Demeter บ่อยมากเพื่อการเขียนที่เร็วขึ้นและไม่ได้ใช้ตัวแปรมากมาย

คุณควรทราบว่าการเขียน

var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;

very.Deep();

ที่จริงแล้ว Demeter ไม่ฉลาดไปกว่านี้อีกแล้ว

myDependency.Grab.Something.Very.Deep();

ถ้านั่นคือสิ่งที่คุณหมายถึง


47

มันคุ้มค่าอย่างยิ่งที่ใช้เวลาเขียนโค้ดคุณภาพดีสำหรับการทดสอบหน่วย:

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

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


22

ใช่มันเป็นเรื่องสำคัญ มีเหตุผลหลายประการที่การทดสอบหน่วยควรจัดให้มีมาตรฐานที่เทียบเท่ากับรหัสอื่น:

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

  • การทดสอบหน่วยสามารถบั๊กกี้ได้เช่นกัน และข้อผิดพลาดจะปรากฏขึ้นเมื่อรหัสถูกเขียนอย่างดี

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

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


12

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

unittests โดยสุจริตควรมีผลลัพธ์ที่คาดหวัง; ทำขั้นตอน; รับผลจริง การทดสอบที่คาดหวังกับโครงสร้างที่แท้จริงซึ่งง่ายต่อการเขียนและเข้าใจ


1

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

หมายความว่า:

  • แยกการสร้างข้อมูลทดสอบลงในคลาสตัวสร้าง
  • แยกการยืนยันที่หลากหลายได้ลงในวิธีการยืนยันที่แยกต่างหาก
  • จงแม่นยำในการตั้งชื่อของคุณ Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56)ทำให้รู้สึกน้อยมากต่อผู้อ่านส่วนใหญ่

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


1

เหตุผลที่สำคัญที่สุดคือทุกครั้งที่คุณเปลี่ยนรหัสคุณเปลี่ยนการทดสอบหน่วย และถ้าคุณทำ TDD คุณจะต้องเปลี่ยนการทดสอบหน่วยก่อน

ทำสิ่งใดสิ่งหนึ่งในการทดสอบของคุณ:

  • รหัสซ้ำ
  • ลดความสามารถในการอ่าน
  • คลัปแน่น
  • การมีเพศสัมพันธ์ชั่วคราว
  • ความซับซ้อนของวงจรสูง (พึ่งพามาก)

และคุณอยู่ในการทำงานจำนวนมากเมื่อต้องการการเปลี่ยนแปลง

ปฏิบัติต่อการทดสอบของคุณตามที่คุณแนะนำและคุณจะต้องเสียใจกับมัน คุณอาจถึงข้อสรุปที่ผิด ๆ ว่า "TDD ไม่ทำงาน"


0

ขึ้นอยู่กับว่าการทดสอบหน่วยเหล่านี้เป็น "ชั่วคราว" หรือไม่ ถ้า

  1. การทดสอบจะถูกใช้บ่อย

  2. นักพัฒนาต้องทำงานกับการทดสอบหน่วยที่เขียนโดยนักพัฒนาคนอื่น ๆ

  3. การทดสอบส่วนใหญ่ทำได้โดยการทดสอบหน่วย

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

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


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