ฉันพยายามเริ่มต้นด้วยการทดสอบหน่วยใน Python และฉันสงสัยว่าใครบางคนสามารถอธิบายข้อดีและข้อเสียของ doctest และ unittest
คุณจะใช้เงื่อนไขอะไรในแต่ละเงื่อนไข
ฉันพยายามเริ่มต้นด้วยการทดสอบหน่วยใน Python และฉันสงสัยว่าใครบางคนสามารถอธิบายข้อดีและข้อเสียของ doctest และ unittest
คุณจะใช้เงื่อนไขอะไรในแต่ละเงื่อนไข
คำตอบ:
ทั้งสองมีคุณค่า ฉันใช้ทั้งหลักคำสอนและจมูกแทนสิ่งที่ไม่เหมาะสม ฉันใช้ doctest สำหรับกรณีที่การทดสอบให้ตัวอย่างของการใช้งานที่เป็นประโยชน์จริง ๆ เป็นเอกสาร โดยทั่วไปฉันไม่ได้ทำการทดสอบเหล่านี้ให้ครอบคลุมโดยมีวัตถุประสงค์เพื่อให้ข้อมูลเท่านั้น ฉันใช้ doctest แบบย้อนกลับอย่างมีประสิทธิภาพ: ไม่ทดสอบโค้ดของฉันถูกต้องตาม doctest ของฉัน แต่เพื่อตรวจสอบว่าเอกสารของฉันถูกต้องตามรหัส
เหตุผลก็คือฉันพบว่าคำสอนที่ครอบคลุมจะทำให้เอกสารของคุณยุ่งมากเกินไปดังนั้นคุณจะจบด้วยเอกสารที่ใช้ไม่ได้หรือการทดสอบที่ไม่สมบูรณ์
สำหรับการทดสอบรหัสจริง ๆเป้าหมายคือการทดสอบอย่างละเอียดทุกกรณีแทนที่จะแสดงสิ่งที่ทำโดยตัวอย่างซึ่งเป็นเป้าหมายที่แตกต่างซึ่งฉันคิดว่าตรงตามกรอบการทำงานอื่นดีกว่า
ฉันใช้ไม่ได้มากที่สุด
นาน ๆ ครั้งฉันจะใส่บางสิ่งใน docstring ที่สามารถใช้ได้โดย doctest
95% ของกรณีทดสอบไม่ได้ทดสอบ
ทำไม? ฉันชอบทำให้เอกสารค่อนข้างสั้นและตรงประเด็นมากขึ้น บางครั้งกรณีทดสอบช่วยชี้แจงเอกสาร ส่วนใหญ่กรณีทดสอบของแอปพลิเคชันนั้นยาวเกินไปสำหรับ docstring
docstring
และอะไรไม่ ฉันชอบ docstring ในระยะที่มันแสดงให้เห็นอย่างชัดเจนถึงวิธีการใช้อินเทอร์เฟซ แต่การใช้ทั้งสำหรับการทดสอบนั้นและการทดสอบหน่วยอาจไม่เหมาะสม
ข้อดีอีกอย่างของการสอนคือคุณต้องแน่ใจว่าโค้ดของคุณทำในสิ่งที่เอกสารของคุณระบุไว้ หลังจากผ่านไปครู่หนึ่งการเปลี่ยนแปลงซอฟต์แวร์สามารถทำให้เอกสารและรหัสของคุณทำสิ่งต่าง ๆ ได้ :-)
ฉันทำงานเป็นชีวสารสนเทศศาสตร์และโค้ดส่วนใหญ่ที่ฉันเขียนคือ "หนึ่งครั้งหนึ่งงาน" สคริปต์รหัสที่จะทำงานเพียงครั้งเดียวหรือสองครั้งและเรียกใช้งานที่เฉพาะเจาะจงเพียงครั้งเดียว
ในสถานการณ์เช่นนี้การเขียน unittests ขนาดใหญ่อาจ overkill และ doctests เป็นการประนีประนอมที่มีประโยชน์ พวกเขาเขียนได้เร็วกว่าและเนื่องจากโดยปกติแล้วพวกเขาจะรวมอยู่ในรหัสพวกเขาอนุญาตให้เฝ้าดูว่ารหัสควรทำงานอย่างไรโดยไม่ต้องเปิดไฟล์อื่น มีประโยชน์เมื่อเขียนสคริปต์ขนาดเล็ก
นอกจากนี้การสอนมีประโยชน์เมื่อคุณต้องส่งสคริปต์ของคุณไปยังนักวิจัยที่ไม่เชี่ยวชาญในการเขียนโปรแกรม บางคนพบว่าเป็นการยากที่จะเข้าใจว่าโครงสร้างของ unittests เป็นอย่างไร ในทางกลับกันการสอนเป็นตัวอย่างการใช้งานที่ง่ายดังนั้นผู้คนสามารถคัดลอกและวางเพื่อดูวิธีการใช้งาน
ดังนั้นเพื่อให้คำตอบของฉันกลับคืนมา: การสอนมีประโยชน์เมื่อคุณต้องเขียนสคริปต์เล็ก ๆ และเมื่อคุณต้องส่งมันหรือแสดงให้นักวิจัยที่ไม่ใช่นักวิทยาศาสตร์คอมพิวเตอร์
หากคุณเพิ่งเริ่มต้นด้วยแนวคิดการทดสอบหน่วยฉันจะเริ่มด้วยdoctest
เพราะมันใช้งานง่ายมาก นอกจากนี้ยังมีเอกสารบางระดับ และสำหรับการทดสอบที่ครอบคลุมมากขึ้นdoctest
คุณสามารถทำการทดสอบในไฟล์ภายนอกเพื่อไม่ให้เอกสารของคุณยุ่งเหยิง
ฉันขอแนะนำunittest
ว่าถ้าคุณมาจากพื้นหลังของการใช้ JUnit หรือสิ่งที่คล้ายกันซึ่งคุณต้องการที่จะสามารถเขียนการทดสอบหน่วยในลักษณะเดียวกับที่คุณเคยไปที่อื่น
doctest
เริ่มต้นด้วย) แต่ในที่สุดก็รู้สึกเสียใจ สำหรับกรณีทดสอบที่ไม่สำคัญฉันสูญเสียการเน้นไวยากรณ์และแก้ไขอัตโนมัติของฉัน เมื่อการทดสอบอยู่ในไฟล์แยกกันฉันไม่สามารถเรียกใช้มันได้โดยตรงจากเครื่องมือแก้ไข - ฉันจะต้องเปลี่ยนบริบทกลับไปเป็นไฟล์ต้นฉบับที่เกี่ยวข้องทุกครั้ง
ฉันใช้สิ่งที่ไม่สำคัญ ฉันคิดว่ากลุ่มที่สอนหลักคำสอนขึ้นโมดูลมากเกินไป นี่อาจเกี่ยวกับการเขียนการทดสอบอย่างละเอียด
การใช้ทั้งคู่เป็นตัวเลือกที่ถูกต้องและค่อนข้างง่าย doctest
โมดูลให้DoctTestSuite
และDocFileSuite
วิธีการที่สร้าง TestSuite UnitTest ได้จากโมดูลหรือแฟ้มตามลำดับ
ดังนั้นฉันจึงใช้ทั้งสองและโดยทั่วไปจะใช้ doctest สำหรับการทดสอบอย่างง่าย ๆ กับฟังก์ชั่นที่ต้องการการตั้งค่าเพียงเล็กน้อยหรือไม่มีเลย ฉันคิดว่าการทดสอบหลักคำสอนเพียงไม่กี่อย่างช่วยจัดทำเอกสารฟังก์ชั่นแทนที่จะเบี่ยงเบนออกไป
แต่สำหรับกรณีที่ซับซ้อนมากขึ้นและสำหรับชุดทดสอบที่ครอบคลุมมากขึ้นฉันใช้ unittest ซึ่งให้การควบคุมและความยืดหยุ่นที่มากขึ้น
ฉันไม่ได้ใช้ doctest เป็นสิ่งทดแทนสำหรับ unittest แม้ว่ามันจะทับซ้อนกันเล็กน้อย แต่โมดูลทั้งสองก็ไม่มีฟังก์ชั่นเหมือนกัน:
ฉันใช้unittest
เป็นกรอบการทดสอบหน่วยซึ่งหมายความว่ามันช่วยให้ฉันสามารถตรวจสอบผลกระทบของการดัดแปลงใด ๆ ในส่วนที่เหลือของรหัสได้อย่างรวดเร็ว
ฉันใช้doctest
เป็นหลักประกันว่าข้อคิดเห็น (คือเอกสาร) ยังคงเกี่ยวข้องกับรหัสรุ่นปัจจุบัน
unittest
ประโยชน์เอกสารกันอย่างแพร่หลายของการพัฒนาทดสอบขับเคลื่อนฉันได้รับจาก doctest
แก้ไขอันตรายที่ลึกซึ้งยิ่งขึ้นของการแสดงความคิดเห็นที่ล้าสมัยทำให้เข้าใจผิดการบำรุงรักษาโค้ด
ฉันแทบจะไม่เคยใช้คำสอน ฉันต้องการให้รหัสของฉันเป็นเอกสารด้วยตนเองและเอกสารนั้นให้เอกสารแก่ผู้ใช้ IMO การเพิ่มการทดสอบหลายร้อยบรรทัดในโมดูลทำให้เอกสารอ่านน้อยลง ฉันพบว่าการทดสอบหน่วยง่ายต่อการปรับเปลี่ยนเมื่อจำเป็น
Doctest
บางครั้งอาจนำไปสู่ผลลัพธ์ที่ผิด โดยเฉพาะอย่างยิ่งเมื่อเอาต์พุตมีลำดับ escape ตัวอย่างเช่น
def convert():
"""
>>> convert()
'\xe0\xa4\x95'
"""
a = '\xe0\xa4\x95'
return a
import doctest
doctest.testmod()
จะช่วยให้
**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
convert()
Expected:
'क'
Got:
'\xe0\xa4\x95'
**********************************************************************
1 items had failures:
1 of 1 in __main__.convert
***Test Failed*** 1 failures.
ยังไม่ได้ตรวจสอบประเภทของการส่งออก มันแค่เปรียบเทียบสตริงเอาต์พุต ตัวอย่างเช่นมันได้ทำให้ประเภทเหตุผลบางอย่างที่พิมพ์เหมือนจำนวนเต็มถ้ามันเป็นจำนวนเต็ม จากนั้นสมมติว่าคุณมีฟังก์ชั่นที่ส่งกลับเหตุผล ดังนั้นการสอนจะไม่แยกความแตกต่างถ้าเอาท์พุทเป็นจำนวนเต็มเหตุผลหรือจำนวนเต็ม
r""" ... """
) เพื่อแก้ไขปัญหาแรก
'\\xe0\\xa4\\x95'
ใน docstring ของคุณ
ฉันชอบระบบที่ใช้การค้นพบ ("จมูก" และ "py.test" โดยใช้ระบบเดิมในปัจจุบัน)
doctest นั้นดีเมื่อการทดสอบนั้นดีเหมือนเอกสารประกอบมิฉะนั้นพวกเขามักจะถ่วงโค้ดมากเกินไป