มันจะมีประโยชน์กับวิธีการทดสอบหน่วยที่ตรรกะเพียงอย่างเดียวคือยาม?


12

ว่าฉันมีวิธีเช่นนี้

public void OrderNewWidget(Widget widget)
{
   if ((widget.PartNumber > 0) && (widget.PartAvailable))
   {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

ฉันมีวิธีการหลายอย่างในรหัสของฉัน (ครึ่งหน้ากับการเรียกใช้ async Web Service)

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

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

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

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

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

ฉันเห็นข้อดีข้อเสียในทั้งสองวิธี ดังนั้นฉันคิดว่าฉันจะถามสิ่งที่คนอื่นทำ


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

9
นี่เป็นหัวข้อนอก แต่ฉันจะเปลี่ยนตรรกะเพื่อโยนข้อยกเว้นถ้าหมายเลขชิ้นส่วนเป็น 0 หรือน้อยกว่าหรือถ้าไม่มีส่วนเช่นในความคิดของฉันมันจะเป็นข้อผิดพลาดที่จะช่วยให้คนที่จะเรียกวิธีการที่มี วิดเจ็ตปลอม, ปิดบังปัญหาอื่นอย่างเงียบ ๆ
Matthew

2
@ Matewew เป็นจุดที่ดีมาก ฟังก์ชั่นนี้ตั้งอยู่ การตั้งชื่อจะบอกคุณว่าจะสั่งบางอย่าง และมันก็ไม่ได้ แต่คุณจะไม่มีทางรู้ยกเว้นว่าคุณใช้ตรรกะแบบเดียวกับที่อยู่ข้างในซึ่ง iviolates DRY กล่าวอีกนัยหนึ่ง: หากการออกแบบมีการเปลี่ยนแปลงให้ถูกต้องมากขึ้นคำถามนี้อาจจะไม่ถูกถามในตอนแรก
stijn

2
but it is not worth the time" (I am on a project that is already behind schedule).เราเป็นนักพัฒนาซอฟต์แวร์ เวลาเดียวที่เราอยู่ในตารางคือเมื่อเราตาย :)
maple_shaft

คำตอบ:


26

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

มันเป็นการทดสอบสั้น ๆ สามครั้ง คุณใช้เวลาถามตัวเองมากพอ

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

ฟังด้านนี้

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

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

ส่วนแรกของคุณผิดธรรมดา ให้ลูบหลังส่วนที่สองแล้วหยุดคิดถึงมัน


+1 สำหรับความรัดกุมแม้ว่าฉันจะเขียนคำตอบด้วยเหอ ๆ
Jimmy Hoffa

3
+1 ใช่หากข้อกำหนดมีการเปลี่ยนแปลงการทดสอบบางอย่างจะต้องมีการปรับ
Olivier Jacot-Descombes

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

@Vaccano: ยิ่งคุณต้องเขียนมากเท่าไหร่ก็จะยิ่งมีตรรกะมากขึ้นเท่านั้นและคุณไม่จำเป็นต้องทำการทดสอบ
pdr

9

มันจะทำให้การทดสอบหน่วยทำได้ง่ายขึ้นถ้าลอจิกของ Guard และการสั่งซื้อจริงเป็นวิธีการแยกต่างหาก

ในWidgetชั้นเรียน

public bool IsReadyForOrdering { get { return PartNumber > 0 && PartAvailable; } }

หรือวิธีอื่นที่เทียบเท่า

public bool IsWidgetReadyForOrdering(Widget widget)
{
    return widget.PartNumber > 0 && widget.PartAvailable;
}

วิธีการสั่งซื้อ

public void OrderNewWidget(Widget widget)
{
   if (IsWidgetReadyForOrdering(widget)) {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

การทดสอบIsWidgetReadyForOrderingเป็นเรื่องง่าย อย่าคิดมากเกี่ยวกับเรื่องนี้อีกต่อไป ทดสอบ!


1
Oof ตรรกะ stateful ในคุณสมบัติ .. -1 ที่ควรเป็นวิธีการและควรใช้ PartNumber, PartAvailable เนื่องจากเป็นความเรียบง่าย ทำให้ได้รับการปกป้องหากไม่จำเป็นต้องเป็นส่วนหนึ่งของ API สาธารณะ แต่ไม่ใช่ทรัพย์สิน .. และโดยทั่วไปฉันไม่เห็นด้วย ตรรกะยามในวิธีนั้นดีมากและในสายตาของฉันดีขึ้นเพราะมันเป็นวิธีการขนาดเล็กที่คุณแค่ทำให้ชั้นเรียนสกปรกเพื่อทำให้วิธีการขนาดเล็กมีขนาดเล็กลงแล้ว เพิ่มลงในคลาสในกรณีนี้ก็ต่อเมื่อมันเป็นตรรกะซ้ำ
จิมมี่ฮอฟฟา

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

8
@JimmyHoffa: คุณเห็นตรรกะลอจิกใด ๆ ในความเป็นจริงตัวอย่างแสดงวิธีการแยกตรรกะการเปลี่ยนสถานะ (OrderNewWidget) จากตรรกะที่ไม่ใช่การเปลี่ยนสถานะ (ReadyForOrdering) และฉันเป็นผู้เชื่อที่แข็งแกร่งที่แยกแม้กระทั่งฟังก์ชั่นเล็ก ๆ ที่จะปรับปรุงรหัสและไม่ทำให้แย่ลงตามที่คุณระบุ ดังนั้น +1
Doc Brown

2
OrderNewWidgetอาจเป็นวิธีการในชั้นเรียนอื่นกว่าWidgetเพราะมันมีWidgetข้อโต้แย้ง เนื่องจากวิธีนี้ไม่มีค่าส่งคืนการทดสอบจึงไม่ชัดเจน คุณจะต้องฉีด - WigdetOrderingServiceจำลองที่ติดตามการOrderNewWidgetAsyncโทร
Olivier Jacot-Descombes

2
@JimmyHoffa: จริง ๆ แล้วนิยามของคุณของ "stateless" หมายถึง "static" ใน C # ดังนั้นสิ่งที่คุณพูดคือ "คุณสมบัติไม่ควรเข้าถึงสถานะของวัตถุ" แต่ถึงกระนั้นก็ยังสามารถเข้าถึงตัวแปรสถานะได้ดังนั้นจะหมายถึง "เขียนเฉพาะคุณสมบัติคงที่" ซึ่งดูเหมือนจะไม่สมเหตุสมผล
Doc Brown

6

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

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


0

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


-5

รหัสคือรหัส คุณควรลองรับความคุ้มครอง 100% เมื่อทำการทดสอบ ถ้ามันไม่สำคัญมันจะไม่อยู่ที่นั่น

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