جارٍ تحميل الدرس...
في نافذة الطباعة اختر «حفظ كملف PDF» كوجهة.
معمل 4
JUnit 5الأطر، التعليقات التوضيحية (Annotations)، دورة الحياة، وأمثلة عملية على JUnit 5
Unit Testing)Method)، أو إجراء، أو وحدة برمجية (Module)، أو كائنا| الأداة | الوصف |
|---|---|
JUnit | أداة اختبار مجانية لجافا، توفر تأكيدات (Assertions) لتحديد توابع الاختبار |
NUnit | مستخدمة على نطاق واسع للغات .NET، مفتوحة المصدر، تدعم اختبارات موازية قائمة على البيانات |
JMockit | مفتوحة المصدر، تقدم المحاكاة (Mocking) بالإضافة إلى مقاييس تغطية الأسطر/المسارات/البيانات |
EMMA | عدة تغطية جافا مفتوحة المصدر (دالة، سطر، كتلة أساسية)، بلا اعتماديات خارجية |
PHPUnit | أداة اختبار وحدة للغة PHP، تختبر أجزاء صغيرة من الكود منفصلة بتأكيدات محددة مسبقا |
JUnit 5 هو إطار اختبار جافا الأكثر استخداما، بني ليتبنى أسلوب Java 8+ في الكتابة (تعبيرات لامدا)؛ يتطلب Java 8 أو أحدثJUnit 3 وJUnit 4 القديمةJUnit 5
Platform
واجهة TestEngine
Jupiter
النموذج الجديد
Vintage
توافق JUnit 3/4
TestEngine، ويوفر مشغل طرفية (Console Launcher) وإضافات بناء لـ Gradle/MavenTestEngineJUnit 3/4 القديمة على منصة JUnit 5 للتوافق الرجعي| التعليق التوضيحي | الوصف |
|---|---|
@Test | يعلم تابعا بأنه اختبار |
@BeforeEach / @AfterEach | يعملان قبل/بعد كل تابع اختبار |
@BeforeAll / @AfterAll | يعملان مرة واحدة للصنف بأكمله (يجب أن يكونا ساكنين static) |
@DisplayName | اسم مخصص وسهل القراءة لصنف أو تابع اختبار |
@Disabled | تخطي صنف أو تابع اختبار |
@RepeatedTest / @ParameterizedTest | تكرار اختبار، أو تشغيله بمجموعات مدخلات متعددة |
@Nested | تجميع اختبارات مترابطة داخل أصناف داخلية |
@Tag | تصفية/اكتشاف الاختبارات حسب وسم |
@BeforeAll
مرة واحدة
@BeforeEach
@Test
@AfterEach
@AfterAll
مرة واحدة
public class Calculator {
public int add(int a, int b) { return a + b; }
public double divide(int a, int b) {
if (b == 0) throw new IllegalArgumentException("Cannot divide by zero");
return (double) a / b;
}
}
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void init() { calculator = new Calculator(); }
@Test
@DisplayName("Test Addition: 5 + 3 = 8")
void testAddition() {
assertEquals(8, calculator.add(5, 3), "5 + 3 should equal 8");
}
@Test
void testDivisionByZero() {
assertThrows(IllegalArgumentException.class,
() -> calculator.divide(10, 0));
}
}Calculator بسيط، وصنف CalculatorTest الذي يفحصه.assertEquals(10, 5 * 2, "5 * 2 should equal 10");
assertEquals(3.14, 3.141, 0.01); // مقارنة بهامش (delta)
assertTrue(5 > 3);
assertNull(nullString);
assertArrayEquals(expected, actual);
assertSame(a, c); // نفس مرجع الكائن
assertThrows(IllegalArgumentException.class, () -> calculator.divide(10, 0));
assertTimeout(Duration.ofMillis(100), () -> Thread.sleep(50));
assertAll("Calculator Operations",
() -> assertEquals(8, calculator.add(5, 3)),
() -> assertEquals(2, calculator.subtract(5, 3))
);assertEquals تفحص تساوي القيم؛ assertSame تفحص هوية المرجعassertAll تجمع تأكيدات متعددة بحيث تعمل جميعها حتى لو فشل أحدها@ParameterizedTest(name = "{0} + {1} = {2}")
@CsvSource({
"1, 2, 3",
"5, 7, 12",
"-5, 5, 0"
})
void testAdditionWithCsvSource(int a, int b, int expected) {
assertEquals(expected, new Calculator().add(a, b));
}
@ParameterizedTest
@MethodSource("factorialProvider")
void testFactorial(int input, int expected) {
assertEquals(expected, new Calculator().factorial(input));
}
static Stream<Arguments> factorialProvider() {
return Stream.of(Arguments.of(0, 1), Arguments.of(5, 120));
}@CsvSource تضمن بيانات الاختبار مباشرة؛ @MethodSource تسحبها من تابع مصنع ساكن (static)@RepeatedTest(value = 5, name = "Repetition {currentRepetition} of {totalRepetitions}")
void testAdditionCommutative() {
int a = random.nextInt(100), b = random.nextInt(100);
assertEquals(calculator.add(a, b), calculator.add(b, a));
}@RepeatedTest(n) تعيد تشغيل اختبار n مرة - مفيدة للفحوصات العشوائية/على غرار الخصائص@TestMethodOrder(MethodOrderer.OrderAnnotation.class) مع @Order(n) على كل @Test يفرض ترتيب تنفيذ محدد (الاختبارات مستقلة افتراضيا - استخدم هذا بحذر)<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>Maven: mvn test · Gradle: gradle test (مع تفعيل useJUnitPlatform())IntelliJ، Eclipse، VS Code) تشغل الاختبارات بالنقر بزر الفأرة الأيمن ← Run، أو زر التشغيل الأخضر بجانب كل تابع اختبارJUnit 5 = Platform (واجهة TestEngine) + Jupiter (التعليقات التوضيحية/النموذج الجديد) + Vintage (توافق JUnit 3/4)@BeforeAll/@BeforeEach/@AfterEach/@AfterAll) تحيط كل اختبار بإعداد وتنظيف متسقين@ParameterizedTest (@CsvSource، @MethodSource) و@RepeatedTest تضاعف التغطية من تابع اختبار واحدassertEquals، assertThrows، assertAll، assertTimeout) تعبر عن السلوك المتوقع بدقةMahmoud Abas|المعمل 4: اختبار الوحدة باستخدام جافا وJUnit 5