การทดสอบหน่วยของคุณลึกแค่ไหน?


88

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

คำถามของฉันคือคุณเขียนแบบทดสอบหน่วยให้ละเอียดระดับใด

.. และมีกรณีทดสอบมากเกินไปหรือไม่?

คำตอบ:


221

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

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


40
โลกไม่คิดว่า Kent Beck จะพูดแบบนี้! มีนักพัฒนาหลายกลุ่มที่ปฏิบัติตามความคุ้มครอง 100% เพราะพวกเขาคิดว่านี่คือสิ่งที่ Kent Beck จะทำ! ฉันได้บอกหลายคนที่คุณพูดในหนังสือ XP ของคุณว่าคุณไม่ได้ปฏิบัติตาม Test First อย่างเคร่งครัดเสมอไป แต่ฉันก็แปลกใจเหมือนกัน
Charlie Flowers

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

2
ฉันไม่สนใจความคุ้มครอง ฉันสนใจมากว่า Mr Beck ส่งรหัสที่ไม่ได้เขียนขึ้นเพื่อตอบสนองต่อการทดสอบที่ล้มเหลวบ่อยเพียงใด
sheldonh

1
@RicardoRodrigues คุณไม่สามารถเขียนการทดสอบเพื่อปกปิดโค้ดที่คนอื่นจะเขียนในภายหลังได้ นั่นคือความรับผิดชอบของพวกเขา
Kief

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

20

เขียนการทดสอบหน่วยสำหรับสิ่งที่คุณคาดว่าจะพังและสำหรับกรณีขอบ หลังจากนั้นควรเพิ่มกรณีทดสอบเมื่อมีรายงานข้อบกพร่องเข้ามาก่อนที่จะเขียนการแก้ไขข้อบกพร่อง จากนั้นนักพัฒนาสามารถมั่นใจได้ว่า:

  1. แก้ไขข้อบกพร่องแล้ว
  2. ข้อบกพร่องจะไม่ปรากฏขึ้นอีก

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


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

@ จอห์นโนแลน: การอ่านการทดสอบสำคัญทั้งหมดหรือไม่? IMHO ไม่ใช่อย่างน้อยสำหรับการทดสอบการถดถอยเฉพาะจุดบกพร่องเหล่านี้ หากคุณเขียนการทดสอบใหม่บ่อยๆคุณอาจกำลังทดสอบในระดับที่ต่ำเกินไป - โดยหลักการแล้วอินเทอร์เฟซของคุณควรจะค่อนข้างเสถียรแม้ว่าการใช้งานของคุณจะเปลี่ยนไปก็ตามและคุณควรทำการทดสอบที่ระดับอินเทอร์เฟซ (แม้ว่าฉันจะตระหนักว่าโลกแห่งความจริงมักจะไม่อยู่ก็ตาม t เช่นนั้น ... : - /) หากอินเทอร์เฟซของคุณมีการเปลี่ยนแปลงครั้งใหญ่ฉันขอแนะนำให้ทิ้งการทดสอบเฉพาะจุดบกพร่องเหล่านี้ส่วนใหญ่หรือทั้งหมดทับการเขียนใหม่
j_random_hacker

@j_random_hacker ใช่แน่นอนความสามารถในการอ่านเป็นสิ่งสำคัญ การทดสอบเป็นรูปแบบของเอกสารและมีความสำคัญพอ ๆ กับรหัสการผลิต ฉันยอมรับว่าการทิ้งการทดสอบสำหรับการเปลี่ยนแปลงที่สำคัญเป็นสิ่งที่ดี (tm) และควรทำการทดสอบที่ระดับอินเทอร์เฟซ
Johnno Nolan

19

ทุกอย่างควรทำให้เรียบง่ายที่สุด แต่ไม่ง่ายกว่านั้น - อ. ไอน์สไตน์

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


ใช่มันคลุมเครือ ... นี่หมายความว่าตัวสร้างไม่ใช่พฤติกรรมส่วนหนึ่งที่เราไม่ควรทดสอบ แต่ฉันควรจะทดสอบ MyClass.DoSomething ()?
Johnno Nolan

ขึ้นอยู่กับ: P ... การทดสอบการก่อสร้างมักเป็นการเริ่มต้นที่ดีเมื่อพยายามทดสอบรหัสเดิม แต่ฉันอาจจะ (ในกรณีส่วนใหญ่) ออกจากการทดสอบการก่อสร้างเมื่อเริ่มออกแบบบางสิ่งตั้งแต่เริ่มต้น
kitofr

มันขับเคลื่อนการพัฒนาไม่ใช่ขับเคลื่อนการออกแบบ ความหมายรับพื้นฐานการทำงานเขียนการทดสอบเพื่อตรวจสอบฟังก์ชันการทำงานก้าวไปข้างหน้าด้วยการพัฒนา ฉันมักจะเขียนการทดสอบของฉันก่อนที่ฉันจะแยกตัวประกอบโค้ดเป็นครั้งแรก
Evan Plaice

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

15

สำหรับผู้ที่เสนอการทดสอบ "ทุกอย่าง" โปรดทราบว่า "การทดสอบอย่างสมบูรณ์" วิธีการเช่นนี้int square(int x)ต้องใช้กรณีทดสอบประมาณ 4 พันล้านกรณีในภาษาทั่วไปและสภาพแวดล้อมทั่วไป

ในความเป็นจริงก็จะยิ่งแย่ไปกว่านั้น: วิธีการที่void setX(int newX)ยังมีภาระผูกพันที่ไม่ได้ที่จะปรับเปลี่ยนค่าของสมาชิกคนอื่น ๆ นอกเหนือจากx- คุณกำลังทดสอบว่าobj.y, obj.zฯลฯ ทั้งหมดยังคงไม่เปลี่ยนแปลงหลังจากเรียกobj.setX(42);?

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


9

คำตอบคลาสสิกคือ "ทดสอบอะไรก็ได้ที่อาจแตกได้" ฉันตีความว่าหมายความว่าการทดสอบ setters และ getters ที่ไม่ได้ทำอะไรเลยนอกจาก set หรือ get อาจเป็นการทดสอบมากเกินไปไม่จำเป็นต้องใช้เวลา เว้นแต่ IDE ของคุณจะเขียนสิ่งเหล่านี้ให้คุณคุณก็อาจทำได้เช่นกัน

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


ใช่และนี่คือการผูกสำหรับคลาสที่มีคุณสมบัติมากมายและคอนสเตอร์จำนวนมาก
Johnno Nolan

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

5

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

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


5

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

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


4

ในกรณีส่วนใหญ่ฉันจะบอกว่าถ้ามีตรรกะอยู่ให้ทดสอบ ซึ่งรวมถึงตัวสร้างและคุณสมบัติโดยเฉพาะอย่างยิ่งเมื่อมีการตั้งค่ามากกว่าหนึ่งสิ่งในคุณสมบัติ

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

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

ดังนั้นไม่ - ฉันจะบอกว่าไม่มีการทดสอบ "มากเกินไป" ในความหมายทั่วไปสำหรับบุคคลทั่วไปเท่านั้น


3

Test Driven Development หมายความว่าคุณจะหยุดเขียนโค้ดเมื่อการทดสอบทั้งหมดผ่าน

หากคุณไม่มีการทดสอบคุณสมบัติแล้วทำไมคุณถึงต้องติดตั้ง? หากคุณไม่ทดสอบ / กำหนดพฤติกรรมที่คาดหวังในกรณีที่มีการมอบหมายงาน "ผิดกฎหมาย" คุณสมบัติควรทำอย่างไร?

ดังนั้นฉันจึงทดสอบพฤติกรรมทุกอย่างที่ชั้นเรียนควรแสดง รวมถึงคุณสมบัติ "ดั้งเดิม"

เพื่อให้การทดสอบนี้ง่ายขึ้นฉันได้สร้าง NUnit แบบง่ายTestFixtureที่ให้จุดส่วนขยายสำหรับการตั้งค่า / รับค่าและรับรายการค่าที่ถูกต้องและไม่ถูกต้องและมีการทดสอบเพียงครั้งเดียวเพื่อตรวจสอบว่าคุณสมบัตินั้นทำงานถูกต้องหรือไม่ การทดสอบคุณสมบัติเดียวอาจมีลักษณะดังนี้:

[TestFixture]
public class Test_MyObject_SomeProperty : PropertyTest<int>
{

    private MyObject obj = null;

    public override void SetUp() { obj = new MyObject(); }
    public override void TearDown() { obj = null; }

    public override int Get() { return obj.SomeProperty; }
    public override Set(int value) { obj.SomeProperty = value; }

    public override IEnumerable<int> SomeValidValues() { return new List() { 1,3,5,7 }; }
    public override IEnumerable<int> SomeInvalidValues() { return new List() { 2,4,6 }; }

}

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

PS: อาจเป็นไปได้ว่า PropertyTest ควรมีวิธีตรวจสอบว่าคุณสมบัติอื่น ๆบนวัตถุไม่เปลี่ยนแปลง อืม .. กลับไปที่กระดานวาดภาพ


ฉันไปนำเสนอใน mbUnit มันดูดี.
Johnno Nolan

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

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

ที่กล่าวว่าฉันพยายามที่จะมีการทดสอบที่ง่ายกว่าโค้ดที่ทดสอบและรายละเอียดระดับนี้อาจคุ้มค่าในการทดสอบการรวมระบบที่เครื่องกำเนิดโมดูลกฎทางธุรกิจและตัวตรวจสอบความถูกต้องทั้งหมดมารวมกัน
David Schmitt

1

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

หลังจากเสร็จสิ้นการทดสอบการเขียนที่ไม่ชัดเจนฉันมักจะเขียนกรณีทดสอบหนึ่งครั้งเพื่อสร้างข้อบกพร่องแต่ละข้อ

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


1

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

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


0

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

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


0

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


0

ฉันไม่ได้ทดสอบหน่วยวิธี setter / getter ง่ายๆที่ไม่มีผลข้างเคียง แต่ฉันทดสอบหน่วยทุกวิธีสาธารณะอื่น ๆ ฉันพยายามสร้างการทดสอบสำหรับเงื่อนไขขอบเขตทั้งหมดใน algorthims ของฉันและตรวจสอบความครอบคลุมของการทดสอบหน่วยของฉัน

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

คุณไม่ได้บอกว่าทำไมสถาปัตยกรรมคุณถึงเขียนโค้ดด้วย แต่สำหรับ Java ผมใช้Maven 2 , JUnit , DbUnit , CoberturaและEasyMock


ฉันไม่ได้บอกว่ามันเป็นคำถามที่ไม่เข้าใจเรื่องภาษา
Johnno Nolan

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

0

ยิ่งฉันอ่านมากเท่าไหร่ฉันก็ยิ่งคิดว่าการทดสอบหน่วยการเรียนรู้บางอย่างก็เหมือนกับรูปแบบบางอย่างนั่นคือกลิ่นของภาษาที่ไม่เพียงพอ

เมื่อคุณต้องการทดสอบว่า trivial getter ของคุณส่งคืนค่าที่ถูกต้องจริงหรือไม่นั่นเป็นเพราะคุณอาจ intermix getter name และชื่อตัวแปรสมาชิก ป้อน 'attr_reader: name' ของทับทิมซึ่งจะไม่เกิดขึ้นอีก ไม่สามารถทำได้ใน java

หากผู้เริ่มต้นของคุณทำตัวไม่สำคัญคุณยังสามารถเพิ่มการทดสอบได้


ฉันยอมรับว่าการทดสอบ getter เป็นเรื่องเล็กน้อย อย่างไรก็ตามฉันอาจจะโง่พอที่จะลืมตั้งค่าไว้ในตัวสร้าง ดังนั้นจึงจำเป็นต้องมีการทดสอบ ความคิดของฉันเปลี่ยนไปตั้งแต่ฉันถามคำถาม ดูคำตอบของฉันstackoverflow.com/questions/153234/how-deep-are-your-unit-tests/…
Johnno Nolan

1
อันที่จริงฉันขอยืนยันว่าในบางกรณีการทดสอบหน่วยโดยรวมเป็นปัญหาทางภาษา ภาษาที่รองรับสัญญา (เงื่อนไขก่อน / หลังเกี่ยวกับวิธีการ) เช่น Eiffel ยังต้องมีการทดสอบหน่วย แต่ต้องการน้อยกว่า ในทางปฏิบัติแม้แต่สัญญาง่ายๆก็ทำให้ง่ายต่อการค้นหาจุดบกพร่อง: เมื่อสัญญาของเมธอดขาดข้อผิดพลาดมักจะอยู่ในวิธีนั้น
Damien Pollet

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

0

ทดสอบซอร์สโค้ดที่ทำให้คุณกังวล

ไม่มีประโยชน์ในการทดสอบโค้ดบางส่วนที่คุณมั่นใจมากตราบเท่าที่คุณไม่ทำผิดพลาด

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

ทดสอบเพื่อให้มั่นใจในส่วนของรหัสที่ไม่ชัดเจนเพื่อให้คุณสร้างความรู้

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


0

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

  1. กำหนดค่า Cyclomatic Complexity ของวิธีการของคุณที่คุณต้องการทดสอบหน่วย (ตัวอย่างเช่น Visual Studio 2010 Ultimate สามารถคำนวณสิ่งนี้ให้คุณด้วยเครื่องมือวิเคราะห์แบบคงที่มิฉะนั้นคุณสามารถคำนวณด้วยมือโดยใช้วิธีการไหล - http://users.csc calpoly.edu/~jdalbey/206/Lectures/BasisPathTutorial/index.html )
  2. แสดงรายการชุดพื้นฐานของเส้นทางอิสระที่ไหลผ่านวิธีการของคุณ - ดูลิงก์ด้านบนสำหรับตัวอย่างโฟลว์กราฟ
  3. เตรียมการทดสอบหน่วยสำหรับแต่ละเส้นทางพื้นฐานอิสระที่กำหนดในขั้นตอนที่ 2

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