โดยปกติเมื่อพูดถึงมาตรฐานการเข้ารหัสเราอ้างถึงรหัสของโปรแกรม แต่สิ่งที่เกี่ยวกับการทดสอบหน่วย? มีแนวทางมาตรฐานการเข้ารหัสบางอย่างที่ไม่ซ้ำกับการทดสอบหน่วย? พวกเขาคืออะไร
โดยปกติเมื่อพูดถึงมาตรฐานการเข้ารหัสเราอ้างถึงรหัสของโปรแกรม แต่สิ่งที่เกี่ยวกับการทดสอบหน่วย? มีแนวทางมาตรฐานการเข้ารหัสบางอย่างที่ไม่ซ้ำกับการทดสอบหน่วย? พวกเขาคืออะไร
คำตอบ:
จากด้านบนของหัวของฉันฉันสามารถนึกถึงความแตกต่างสามแบบในการเขียนโค้ดสำหรับการทดสอบ
shouldDoSomethingWhenSomeConditionHolds
ในการตั้งชื่อวิธีการทดสอบผมตามรูปแบบของ
ในการทดสอบเป็นเรื่องปกติที่จะทำตามรูปแบบระยะห่างต่อไปนี้:
@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
// Some lines
// of setup code
// go here.
// The action being tested happens after a blank line.
// An assertion follows another blank line.
}
บางคนยืนยันในการยืนยันเพียงครั้งเดียวต่อการทดสอบ แต่สิ่งนี้อยู่ไกลจากความเป็นสากล
DRY (อย่าทำซ้ำตัวเอง) มีข้อพิจารณาในรหัสทดสอบน้อยกว่าในรหัสการผลิต ในขณะที่บางรหัสซ้ำควรอยู่ในวิธีการตั้งค่าหรือคลาส testUtils การมุ่งมั่นเพื่อเป็นศูนย์การทำซ้ำในรหัสทดสอบจะนำไปสู่การทดสอบคู่แน่นและไม่ยืดหยุ่นซึ่งกีดกันการปรับโครงสร้าง
Roy Osherove แนะนำรูปแบบต่อไปนี้สำหรับการตั้งชื่อการทดสอบของคุณ:
NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior()
ดูhttp://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx
NameOfMethodUnderTestStateUnderTestExpectedBehavior()
);
สิ่งสำคัญคือต้องจำไว้ว่าการทดสอบหน่วยเป็นข้อกำหนดขนาดเล็ก ซึ่งหมายความว่าการเน้นจะต้องอ่านได้เสมอ
ประการแรกหมายความว่าชื่อจะต้องสื่อสารอย่างชัดเจนถึงสิ่งที่อยู่ภายใต้การทดสอบและสิ่งที่ถูกยืนยัน
ประการที่สองซึ่งบางครั้งก็ถูกลืมก็คือว่าเป็นข้อกำหนดที่พวกเขาควรจะทำเพียงแค่นั้น - ระบุพฤติกรรม นั่นคือการทดสอบหน่วยไม่ควรมีตรรกะ - หรืออาจตกอยู่ในกับดักของการทำซ้ำฟังก์ชั่นของโปรแกรมมากกว่าการทดสอบ
บางครั้งการทดสอบจะเกี่ยวข้องกับวัตถุที่มีความซับซ้อนในการตั้งค่าที่คุณควรมุ่งมั่นที่จะเก็บชุดนี้ขึ้นตรรกะที่แยกต่างหากจากการทดสอบของคุณโดยใช้สิ่งที่ต้องการแม่ของวัตถุหรือสร้างข้อมูลการทดสอบ
ฉันจะปัดเศษด้วยคำแนะนำหนังสือไม่กี่:
รูปแบบการทดสอบ xUnit: การทดสอบการปรับโครงสร้างรหัสใหม่:หนังสือยอดเยี่ยมบางคนบอกว่ามันค่อนข้างแห้ง แต่ฉันไม่คิดอย่างนั้น อธิบายรายละเอียดมากมายเกี่ยวกับวิธีการทดสอบที่หลากหลายและวิธีการดูแลรักษา เกี่ยวข้องถ้าคุณกำลังใช้บางอย่างเช่น NUnit เป็นต้น
ศิลปะการทดสอบหน่วย: ด้วยตัวอย่างใน. Net : หนังสือที่ดีที่สุดเกี่ยวกับการเขียนและการบำรุงรักษาที่ดีที่สุด แม้จะเป็นเรื่องใหม่จริง ๆ แต่ฉันพบว่าส่วนที่ล้อเล่นล้าสมัยไปแล้วเล็กน้อยเนื่องจากไวยากรณ์ AAA ตอนนี้เป็นมาตรฐานที่ค่อนข้างดี
การพัฒนาซอฟต์แวร์เชิงวัตถุนำโดยการทดสอบ : หนังสือเล่มนี้น่าทึ่งมาก! หนังสือการทดสอบหน่วยที่ดีที่สุดและหนังสือขั้นสูงเพียงเล่มเดียวที่ทำให้การทดสอบหน่วยเป็นพลเมืองชั้นหนึ่งในกระบวนการออกแบบ ได้อ่านสิ่งนี้เมื่อมันเป็นเบต้าสาธารณะและได้รับการแนะนำตั้งแต่ ตัวอย่างการทำงานที่แท้จริงในโลกแห่งความเป็นเลิศใช้ตลอดทั้งเล่ม ขอแนะนำให้อ่านหนังสือของ Roy ก่อน
อย่าใส่ตรรกะในการทดสอบหน่วยของคุณ ตัวอย่างเช่นสมมติว่าคุณกำลังทดสอบวิธีการเพิ่มคุณอาจมีลักษณะดังนี้:
void MyTest_SaysHello()
{
string name = "Bob";
string expected = string.Format("Hello, {0}", name);
IMyObjectType myObject = new MyObjectType();
string actual = myObject.SayHello(name);
Assert.AreEqual(expected, actual);
}
โดยเฉพาะอย่างยิ่งในกรณีนี้คุณมีแนวโน้มที่จะทำซ้ำตรรกะเดียวกันกับสิ่งที่อยู่ในการทดสอบดังนั้นคุณจำเป็นต้องทดสอบ "1 + 1 == 1 + 1" มากกว่า "1 + 1 == 2" ซึ่งเป็น การทดสอบ "ของจริง" ดังนั้นสิ่งที่คุณต้องการให้โค้ดทดสอบของคุณมีลักษณะดังนี้คือ:
void MyTest_SaysHello()
{
string expected = "Hello, Bob";
IMyObjectType myObject = new MyObjectType();
string actual = myObject.SayHello("Bob");
Assert.AreEqual(expected, actual);
}
ชื่อเมธอดแบบยาวและเป็นคำอธิบาย จำไว้ว่าวิธีการทดสอบจะไม่ถูกเรียกจากรหัส (พวกมันถูกเรียกโดยนักทดสอบหน่วยที่ค้นพบและเรียกมันผ่านการสะท้อนกลับ) ดังนั้นจึงเป็นเรื่องปกติที่จะบ้าและมีชื่อวิธียาว 50-80 ตัว แบบแผนการตั้งชื่อที่เฉพาะเจาะจง (อูฐ - ตัวอักษรขีดล่าง "ควร", "ต้อง", "เมื่อ", "ให้", ฯลฯ ) ไม่สำคัญจริง ๆ ตราบเท่าที่ชื่อตอบคำถามสามข้อ:
วิธีการทดสอบควรจะสั้น
วิธีการทดสอบควรจะมีความเรียบง่ายโครงสร้างเชิงเส้น ไม่มีถ้าหรือวนรอบการสร้าง
วิธีการทดสอบควรทำตาม"จัด-กระทำยืนยัน" รูปแบบ
การทดสอบแต่ละครั้งควรทดสอบสิ่งหนึ่ง ซึ่งมักจะหมายถึงหนึ่งยืนยันต่อการทดสอบ การทดสอบเช่น{ Do A; Assert B; Assert C; }
นั้นควรปรับโครงสร้างเป็นสอง: { Do A; Assert B; }
และ{ Do A; Assert C; }
หลีกเลี่ยงข้อมูลแบบสุ่มหรือสิ่งต่าง ๆ เช่น 'DateTime.Now'
ตรวจสอบให้แน่ใจว่าสมาชิกทุกคนในฟิกซ์เจอร์ทดสอบจะกลับสู่สถานะเดิมเมื่อสิ้นสุดการทดสอบ (เช่นใช้การฉีกขาด )
แม้ว่าคุณจะลบการทำซ้ำอย่างไร้ความปราณีในรหัสการผลิตของคุณการทำสำเนารหัสในการติดตั้งการทดสอบนั้นเป็นสิ่งที่กังวลน้อยกว่ามาก
ค่อนข้างคล้ายกับที่ Farmboy พูดถึงแล้ว, รูปแบบชื่อเมธอดของฉัน
<MethodName>Should<actionPerformed>When<Condition>
เช่น
GetBalanceShouldReturnAccountBalance() {