كتابة اختبارات الـ JUnit اسهل مع الـ JUnitMatchers

Mohammad Laifمنذ 6 سنوات

بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته

في هذه المقالة سنتعلم كيفية استخدام الـ JUnitMatchers, لتسهيل كتابة الاختبارات وقرائتها (وخاصة الدالة "assertThat" والتي هي صلب الموضوع). وهو يأتي مع مكتبة الـ JUnit بشكل اساسي, حيث انك لاتحتاج لتثبيت اي ملف jar او اضافة اي اعتمادية لمشروعك.

 

المواضيع السابقة (مهمة لفهم هذا المقال)

هذه هي المقالات السابقة والتي تعتبر ضروريه لفهم هذا المقال فاذا لم تكن لديك خلفيه مع الـ JUnit انصحك بقرائتها قبل هذا الموضوع والذي يعتبر المقال الثالث من اصل ستة مقالات.

https://3alam.pro/index.php/articles/android/junit-in-java/

 

https://3alam.pro/index.php/articles/java/junit-in-java-part2/

 

رابط المشروع

https://github.com/mzdhr/KidCalculator-JUnit

وتوجد كلاس هذه المقالة باسم: MatcherAssertThatTest.java في المشروع. واذا اردت الاطلاع على كلاس الـموديل فهذه هي Calculator.java.

 

ماذا سوف تقرئ في هذه المقالة
ماهي انواع الـ Matchers المدعومة في الـ Junit؟ كيفية استخدام الـ JUnitMatchers وبالذات الدالة assertThat؟ كيفية التحقق من كلاس العنصر, وعكس ذلك؟ التحقق من ان العنصر ليس null؟ وايضاً ماهي الطريقة للتحقق من وجود عنصر نصي (string) بداخل عنصر نصي (string) اخر؟ هل هو في البداية ام في النهاية؟ وكيفية التحقق من عناصر الـ boolean؟ واخيراً كيفية التحقق من ان ArrayList تحتوي على عنصر محدد مسبقاً؟

 

انواع الـ Matchers في الـ JUnit

  1. JUnitMatchers والمسمى ايضاً بـ JUnit CoreMatchers وهذا ماسيتم شرحة في هذه المقالة.
  2. Hamcrest CoreMatchers لن يتم شرحة, ولكنه مشابه بشكل كبير للسابق, فالاثنين يحتويات على دالة assertThat. وهذا يسبب مشاكل, فاذا قمت بتثبيته ستواجة اختلاط في كتابة الاختبارات, فأنصح كبداية باستخدام النوع الاول اما اذا اردت التعمق فأنصح باستخدام النوع الثاني.

ملاحظة: تم بناء النوع الاول وهو JUnitMatchers على النوع الثاني وهو Hamcrest ثم دعمة بشكل رسمي في الـ JUnit.

 

استخدام الـ JUnitMatchers في الـ JUnit
في الطريقة التقليدية القديمة تعودنا على كتابة الاختبارات بأستخدام الدالة assertEquals, اما الان فسوف نكتبها بالطريقة الجديدة باستخدام دالة الـ assertThat.

مثال: الطريقة القديمة


    @Test
    public void assert_old_way(){
        // Action
        int result = calculator.addition(10, 4);
        // Assert
        assertEquals(result, 14);
    }

 

مثال: الطريقة الجديدة


    @Test
    public void assert_that_test() {
        // Action
        int result = calculator.addition(10, 4);
        // Assert
        assertThat(result, is(14));
    }

تعقيب

في الطريقة الجديدة استخدمنا دالة assertThat مع دالة is وهذا يسهل علينا الامر كثيراً. وكأننا نقول هل قيمة الـ result هي 14؟ اذا نعم فالاختبار يعتبر ناجح. وايضاً يمكننا اضافة تعليق لها كما سيأتي.

 

اضافة تعليق للإختبار


    @Test
    public void assert_with_message_test(){
        // Action
        int result = calculator.addition(10, 10);
        // Assert
        assertThat("This is a message, shows when test failed!", result, is(20));
    }

تعقيب

عند فشل الاختبار فسوف تظهر هذه الرسالة, حيث اننا نستطيع استخدامها لتسهيل علينا تتبع الفشل, كما بالمقال الاول.

 

التحقق من كلاس العنصر


    @Test
    public void assert_is_type_x_class_test(){
        // Action
        int result = calculator.addition(10, 5);
        // Assert
        assertThat(result, isA(Integer.class));
    }

تعقيب
باستخدام الدالة isA بداخل الدالة assertThat قمنا بالتحقق هل العنصر result هو في الحقيقة من نوع الـ Integer ام لا. وعكس ذلك كما سيأتي لاحقاً.

 

التحقق ان العنصر ليس من كلاس محدده


    @Test
    public void assert_not_type_x_class_test(){
        // Action
        int result = calculator.addition(10, 4);
        // Assert
        assertThat(result, is(not(instanceOf(Double.class))));
    }

تعقيب
قمنا بالتحقق هل العنصر result ليس من كلاس Double؟ وتم هذا التحقيق باستخدام الدالة is مع دالة النفي not ومن ثم دالة instanceOf التي بدورها تأخد نوع الكلاس المراد التحقق منها.

 

التحقق ان العنصر لايحمل null كقيمة له


    @Test
    public void assert_not_null_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, is(notNullValue()));
    }

تعقيب
قمنا بالتحقق باستخدام الدالة is والدالة  notNullValue, اي كاننا نقول هل العنصر result لا يحمل قيمة null. يوجد عكس هذه الداله وهي nullValue اذا اردت ان تتحقق من ان العنصر يحمل بالفعل قيمة null.

 

التحقق ان عنصر String يحتوي على عنصر String اخر


    @Test
    public void assert_contains_string_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, containsString("e"));
    }

تعقيب
باستخدام الدالة containsString, قمنا بالتحقق من العنصر color هل يحتوي على حرف الـ e بداخله. طبعاً سينجح الاختبار لإن color يحتوي على قيمة "Red" مسبقاً.

 

التحقق بان العنصر String يحتوي على اي من هذه العناصر الاخرى


    @Test
    public void assert_contains_any_with_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, anyOf(containsString("S"), containsString("B"), containsString("d")));
    }

تعقيب
في هذا المثال استخدمنا الدالة anyOf ثم اتينا بسلسه من الدوال containsString للتحقق من اذا كان العنصر color يحتوي على اي منهم. طبعاً سينجح الاختبار لإن اللون color هو عنصر String يحتوي على قيمة "Red" و لإن الاختبار سيرى قيمة "d" بداخله.

 

التحقق ان العنصر String يبدئ بهذه الحروف


    @Test
    public void assert_start_with_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, startsWith("R")); // there is also -> endsWith()
    }

تعقيب
مشابه للسابقين, ولكن هنا تحققنا ان العنصر color يبدئ بالحرف R باستخدام الدالة startsWith. وايضاً توجد دالة اخرى تقوم بالعكس وهي الدالة endsWith. طبعاً سينجح الاختبار لإن عنصرنا color والذي يحتوي على قيمة "Red" يوجد به حرف "R" في بدايته.

 

التحقق من عنصر boolean هل هو true


    @Test
    public void assert_true_test(){
        // Action
        calculator.setOn();
        boolean power = calculator.getPower();
        // Assert
        assertThat(power, is(true));
    }

تعقيب
باستخدام كلمة true بداخل الدالة is, قمنا بالتحقق هل ان العنصر power يحمل قيمة true بداخله. والعكس صحيح بالنسبه للتحقق من قيمة الـ false.

 

التحقق من ان ArrayList تحتوي على عنصر محدد


    @Test
    public void assert_list_test(){
        // Action
        int number01 = calculator.addition(1, 1);
        int number02 = calculator.addition(1, 2);
        int number03 = calculator.addition(1, 3);
        int number04 = calculator.addition(1, 4);

        ArrayList<Integer> myList = new ArrayList<>();
        myList.add(number01);
        myList.add(number02);
        myList.add(number03);
        myList.add(number04);

        int itemWanted = 5;

        // Assert
        assertThat(myList, hasItem(itemWanted));
    }

تعقيب
قمنا بانشاء اربعة عناصر باستخدام المودل calculator, ثم أضفناهم الى قائمة بأسم myList, وفي النهاية قمنا بانشاء عنصرنا المراد التحقق منه وهو itemWanted.
وبأستخدام الدالة hasItem قمنا بهذا التحقق.

 

الكلاس كاملة


package com.company;

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class MatcherAssertThatTest {

    // Fields
    private Calculator calculator;

    @Before
    public void setUp() {
        // Arrange
        calculator = new Calculator("Red");
    }


    @Test
    public void assert_old_way(){
        // Action
        int result = calculator.addition(10, 4);
        // Assert
        assertEquals(result, 14);
    }

    @Test
    public void assert_that_test() {
        // Action
        int result = calculator.addition(10, 4);
        // Assert
        assertThat(result, is(14));
    }

    @Test
    public void assert_with_message_test(){
        // Action
        int result = calculator.addition(10, 10);
        // Assert
        assertThat("This is a message, shows when test failed!", result, is(20));
    }

    @Test
    public void assert_is_type_x_class_test(){
        // Action
        int result = calculator.addition(10, 5);
        // Assert
        assertThat(result, isA(Integer.class));
    }

    @Test
    public void assert_not_type_x_class_test(){
        // Action
        int result = calculator.addition(10, 4);
        // Assert
        assertThat(result, is(not(instanceOf(Double.class))));
    }

    @Test
    public void assert_not_null_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, is(notNullValue()));
    }

    @Test
    public void assert_contains_string_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, containsString("e"));
    }

    @Test
    public void assert_contains_any_with_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, anyOf(containsString("S"), containsString("B"), containsString("d")));
    }

    @Test
    public void assert_start_with_test(){
        // Action
        String color = calculator.getColor();
        // Assert
        assertThat(color, startsWith("R")); // there is also -> endsWith()
    }

    @Test
    public void assert_true_test(){
        // Action
        calculator.setOn();
        boolean power = calculator.getPower();
        // Assert
        assertThat(power, is(true));
    }

    @Test
    public void assert_list_test(){
        // Action
        int number01 = calculator.addition(1, 1);
        int number02 = calculator.addition(1, 2);
        int number03 = calculator.addition(1, 3);
        int number04 = calculator.addition(1, 4);

        ArrayList<Integer> myList = new ArrayList<>();
        myList.add(number01);
        myList.add(number02);
        myList.add(number03);
        myList.add(number04);

        int itemWanted = 5;

        // Assert
        assertThat(myList, hasItem(itemWanted));
    }

}

 

وكانت هذه اغلب الامثلة والدوال المهمة التي سوف تحتاجها في كتابة اختبارات أسهل بأستخدام دالة الـ assertThat بداخل الـ JUnitMatchers في اجراء الاختبارات مع مكتبة الـ JUnit. وللمزيد من المعلومات حول الـ matchers.

كلمات دليلية:
1
إعجاب
3859
مشاهدات
0
مشاركة
0
متابع
متميز
محتوى رهيب

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !