ฉันกำลังทำการทดสอบ JUnit บนฐานรหัสขนาดใหญ่และฉันตระหนักว่าบางครั้งฉันได้รับ "ข้อผิดพลาด" ในขณะที่บางครั้งฉันได้รับ "ความล้มเหลว" อะไรคือความแตกต่าง?
ฉันกำลังทำการทดสอบ JUnit บนฐานรหัสขนาดใหญ่และฉันตระหนักว่าบางครั้งฉันได้รับ "ข้อผิดพลาด" ในขณะที่บางครั้งฉันได้รับ "ความล้มเหลว" อะไรคือความแตกต่าง?
คำตอบ:
โอเคฉันเพิ่งสังเกตเห็นรูปแบบและคิดว่าฉันคิดออกแล้ว (แก้ไขฉันถ้าฉันผิด) สำหรับฉันแล้วดูเหมือนว่าความล้มเหลวคือเมื่อกรณีทดสอบของคุณล้มเหลวนั่นคือการยืนยันของคุณไม่ถูกต้อง ข้อผิดพลาดคือข้อผิดพลาดที่ไม่คาดคิดซึ่งเกิดขึ้นขณะพยายามเรียกใช้การทดสอบจริง - ข้อยกเว้น ฯลฯ
@Test
expected = SomeException.class
หากการทดสอบของคุณแสดงข้อยกเว้นที่ไม่เกิดฟองผ่าน Assertion framework ใน Junit จะได้รับรายงานว่าเป็นข้อผิดพลาด ตัวอย่างเช่น NullPointer หรือข้อยกเว้น ClassNotFound จะรายงานข้อผิดพลาด:
String s = null;
s.trim();
หรือ,
try {
// your code
} catch(Exception e) {
// log the exception
throw new MyException(e);
}
ต้องบอกว่าสิ่งต่อไปนี้จะรายงานความล้มเหลว:
Assert.fail("Failure here");
หรือ,
Assert.assertEquals(1, 2);
หรือแม้กระทั่ง:
throw new AssertionException(e);
ขึ้นอยู่กับรุ่น Junit ที่คุณใช้ Junit 4- จะทำให้ความแตกต่างระหว่างความล้มเหลวและข้อผิดพลาด แต่ Junit 4 ทำให้ง่ายขึ้นเป็นความล้มเหลวเท่านั้น
ลิงค์ต่อไปนี้ให้ข้อมูลที่น่าสนใจมากขึ้น:
จาก "Pragmatic Unit Testing ใน Java 8 ด้วย JUnit":
Assertions (หรือ asserts) ใน JUnit คือการเรียกวิธีการแบบคงที่ที่คุณใส่ลงในการทดสอบของคุณ การยืนยันแต่ละครั้งเป็นโอกาสในการตรวจสอบว่าเงื่อนไขบางอย่างเป็นจริง หากเงื่อนไขที่ยืนยันไม่เป็นจริงการทดสอบจะหยุดลงที่นั่นและ JUnit จะรายงานการทดสอบล้มเหลว
(อาจเป็นไปได้ว่าเมื่อ JUnit รันการทดสอบของคุณข้อยกเว้นจะถูกโยนทิ้งและไม่ถูกจับในกรณีนี้ JUnit จะรายงานข้อผิดพลาดในการทดสอบ)
ฉันได้แสดงความคิดเห็นในบรรทัดที่แสดงข้อผิดพลาดในการทดสอบและการทดสอบล้มเหลว
@Test
public void testErrorVsTestFailure() {
final String sampleString = null;
assertEquals('j', sampleString.charAt(0) );
//above line throws test error as you are trying to access charAt() method on null reference
assertEquals(sampleString, "jacob");
//above line throws Test failure as the actual value-a null , is not equal to expected value-string "jacob"
}
Junit จึงแสดงข้อผิดพลาดในการทดสอบทุกครั้งที่คุณได้รับข้อยกเว้นและทดสอบความล้มเหลวเมื่อค่าผลลัพธ์ที่คาดหวังไม่ตรงกับค่าจริงของคุณ
คลาสซอร์ส: JUnitReportReporter.java
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String defaultOutputDirectory) {
//......
for (ITestResult tr : (Set) entry.getValue()) {
TestTag testTag = new TestTag();
boolean isSuccess = tr.getStatus() == 1;
if (!(isSuccess)) {
if (tr.getThrowable() instanceof AssertionError)
++errors;
else {
++failures;
}
}
}
ดังที่คุณเห็นด้านล่างบรรทัดในวิธีการด้านบน
tr.getThrowable () อินสแตนซ์ของ AssertionError
จำนวนข้อผิดพลาดจะเพิ่มขึ้นเมื่อเป็นอินสแตนซ์ของ AssertionError มิฉะนั้น (Throwable ใด ๆ ) จะนับเป็นความล้มเหลว
คุณคิดถูกว่าความล้มเหลวมาจาก AssertionErrors ที่เกิดจากวิธีการยืนยัน JUnit หรือโดยการโยน AssertionError หรือโดยการโยนข้อยกเว้นที่คุณประกาศไว้ใน@Test
คำอธิบายประกอบของคุณและข้อผิดพลาดมาจากข้อยกเว้นอื่น ๆ ที่ไม่คาดคิด แต่มีความแตกต่างที่สำคัญระหว่างพวกเขา:
ความล้มเหลวหมายความว่าการทดสอบของคุณทำงานได้อย่างถูกต้องและระบุข้อบกพร่องในโค้ดของคุณ
ข้อผิดพลาดอาจหมายถึงข้อบกพร่องในโค้ดของคุณ แต่ข้อผิดพลาดที่คุณยังไม่ได้ทดสอบ นอกจากนี้ยังอาจหมายความว่าจุดบกพร่องอยู่ในการทดสอบ
ในระยะสั้นความล้มเหลวหมายความว่าคุณต้องเขียนโค้ดที่กำลังทดสอบใหม่ ข้อผิดพลาดหมายความว่าอาจเป็นการทดสอบหน่วยที่คุณต้องเขียนใหม่ อาจหมายถึงแม้ว่าความล้มเหลวจะอยู่ในโค้ดของคุณเช่น a NullPointerException
เนื่องจากคุณตรวจพบข้อบกพร่องที่คุณไม่ได้ทดสอบด้วยซ้ำดังนั้นจึงควรทดสอบเพื่อหาข้อบกพร่องนั้น
แดกดันจูนิทและเฟรมเวิร์กที่เกี่ยวข้องกับการทดสอบอื่น ๆ (testng, hamcrest) ให้การดำเนินการที่ยืนยันซึ่งตรวจสอบเงื่อนไขและหากล้มเหลวจะมีการ "ภายใต้ฝากระโปรง" java.lang.AssertionError ซึ่ง btw ขยาย java.lang.Error
แต่ไม่มีทางขัดแย้งกับคำตอบข้างต้นที่ถูกต้องแน่นอน ดังนั้นในการทำเครื่องหมายขั้นตอนการทดสอบที่เฉพาะเจาะจงว่าเป็นความล้มเหลวเราสามารถโยน AssertionError ได้อย่างไรก็ตามฉันไม่แน่ใจว่ามีการบันทึกไว้ในคู่มือที่เกี่ยวข้องจริง ๆ เนื่องจากเหมาะสมกว่าที่จะใช้ API ที่ใช้ล้มเหลวโดยเฉพาะ () ประเภทอื่น ๆ ของ Throwable จะถือเป็นข้อผิดพลาดไม่ใช่ความล้มเหลว
java.lang.AssertionError
ไปจะถูกแสดงเป็นความล้มเหลวในการทดสอบแทนที่จะเป็นข้อผิดพลาดในการทดสอบ คุณควรพิจารณายอมรับคำตอบของคุณเองเพราะถูกต้อง