سؤال

ما هي أفضل الممارسات لاختبار قواعد سال لعابه مع Junit؟

حتى الآن استخدمنا Junit مع DBUnit لاختبار القواعد. كان لدينا عينة بيانات تم وضعها على HSQLDB. كان لدينا بضع حزم القواعد ، وبحلول نهاية المشروع ، من الصعب جدًا إجراء مدخلات اختبار جيدة لاختبار بعض القواعد وعدم إطلاق النار على الآخرين.

لذا فإن السؤال الدقيق هو كيف يمكنني تقييد الاختبارات في Junit على واحدة أو أكثر من القواعد (قواعد) معينة للاختبار؟

هل كانت مفيدة؟

المحلول

أنا شخصياً أستخدم اختبارات الوحدة لاختبار القواعد المعزولة. لا أعتقد أن هناك أي شيء خاطئ للغاية في ذلك ، طالما أنك لا تقع في إحساس زائف بالأمان بأن قاعدة المعرفة الخاصة بك تعمل لأن القواعد المعزولة تعمل. اختبار قاعدة المعرفة بأكملها أكثر أهمية.

يمكنك كتابة الاختبارات المعزولة مع جدول أعمال وزملاؤه

StatelessSession session = ruleBase.newStatelessSesssion();

session.setAgendaFilter( new RuleNameMatches("<regexp to your rule name here>") );

List data = new ArrayList();
... // create your test data here (probably built from some external file)

StatelessSessionResult result == session.executeWithResults( data );

// check your results here.

مصدر الرمز: http://blog.athico.com/2007/07/my-rules-dont-work-as-expected-what-can.html

نصائح أخرى

لقد قمت بإنشاء مكتبة بسيطة تساعد على كتابة اختبارات الوحدة للسيلر. واحدة من الميزات هي بالضبط ما تحتاجه: إعلان ملفات DRL معينة التي تريد استخدامها لاختبار الوحدة الخاص بك:

@RunWith(DroolsJUnitRunner.class)
@DroolsFiles(value = "helloworld.drl", location = "/drl/")
public class AppTest {

    @DroolsSession
    StatefulSession session;

    @Test
    public void should_set_discount() {
        Purchase purchase = new Purchase(new Customer(17));

        session.insert(purchase);
        session.fireAllRules();

        assertTrue(purchase.getTicket().hasDiscount());
    }
}

لمزيد من التفاصيل ، إلقاء نظرة على منشور المدونة: http://maciejwalkowiak.pl/blog/2013/11/24/jboss-drools-unit-testing-with-junit-drools/

لا تحاول الحد من تنفيذ القاعدة على قاعدة واحدة للاختبار. على عكس فئات OO ، فإن القواعد المفردة ليست مستقلة عن القواعد الأخرى ، لذلك ليس من المنطقي اختبار قاعدة في عزلة بنفس الطريقة التي تختبر بها فئة واحدة باستخدام اختبار الوحدة. وبعبارة أخرى ، لاختبار قاعدة واحدة ، اختبر أن لها التأثير الصحيح مع القواعد الأخرى.

بدلاً من ذلك ، قم بإجراء اختبارات بكمية صغيرة من البيانات عن جميع قواعدك ، أي مع الحد الأدنى من الحقائق في جلسة القاعدة ، واختبار النتائج وربما تم إطلاق قاعدة معينة. والنتيجة ليست في الواقع مختلفة كثيرًا عما يدور في ذهنك ، لأن الحد الأدنى من بيانات الاختبار قد ينشط فقط قاعدتين أو قاعدتين.

أما بالنسبة لبيانات العينة ، فأنا أفضل استخدام بيانات ثابتة وتحديد الحد الأدنى من بيانات الاختبار لكل اختبار. هناك طرق مختلفة للقيام بذلك ، لكن إنشاء كائنات وقائع في Java برمجيًا قد يكون جيدًا بما فيه الكفاية.

لا يعمل اختبار الوحدة مع DBUNIT حقًا. اختبار التكامل مع DBUnit يفعل. إليك السبب: - يجب أن يكون اختبار الوحدة سريعًا. - قاعدة بيانات DBUNIT بطيئة. يستغرق 30 ثانية بسهولة. -تطبيق العالم الحقيقي لديه العديد من الأعمدة الفارغة. لذا فإن البيانات ، المعزولة لميزة واحدة ، لا تزال تستخدم بسهولة نصف جداول قاعدة البيانات. - يجب عزل اختبار الوحدة. -استعادة قاعدة بيانات DBUNIT لكل اختبار للحفاظ على عزلها لها عيوب: --- تشغيل جميع الاختبارات يستغرق ساعات (خاصة مع نمو التطبيق) ، لذلك لا أحد يديرها ، لذلك يكسرون باستمرار ، لذلك يتم تعطيلهم ، لذلك هناك لا يوجد اختبار ، لذلك أنت مليء بالأخطاء. --- إنشاء نصف قاعدة بيانات لكل اختبار الوحدة هو الكثير من أعمال الإنشاء ، والكثير من أعمال الصيانة ، يمكن أن يصبح بسهولة غير صالحة (فيما يتعلق بالتحقق من صحة مخطط قاعدة البيانات لا تدعمها ، راجع صحة السبات) ويقوم USILAY بعمل سيء للغاية وظيفة تمثيل الواقع.

بدلاً من ذلك ، اكتب اختبارات التكامل باستخدام DBUNIT: - واحد dbunit ، وهو نفسه لجميع الاختبارات. قم بتحميله مرة واحدة فقط (حتى لو قمت بإجراء 500 اختبار). - لف كل اختبار في معاملة وتراجع قاعدة البيانات بعد كل اختبار. معظم الطرق تستخدم الانتشار المطلوب على أي حال. اضبط TestData Dirty فقط (لإعادة تعيينه في الاختبار التالي إذا كان هناك اختبار التالي) فقط عندما يكون الانتشار يتطلب _new. - املأ قاعدة البيانات هذه بحالات الزاوية. لا تضيف حالات أكثر شيوعًا مما هو مطلوب تمامًا لاختبار قواعد عملك ، لذلك فالحضتين الشائعين فقط (لتكون قادرًا على اختبار "واحد إلى كثير"). - اكتب اختبارات مقاومة في المستقبل:- لا تختبر عدد القواعد المنشطة أو عدد الحقائق المدرجة. - بدلاً من ذلك ، اختبر ما إذا كانت هناك حقيقة تم إدراجها موجودة في النتيجة. قم بتصفية النتيجة على خاصية معينة تم تعيينها على X (تختلف عن القيمة المشتركة لتلك الخاصية) واختبار عدد الحقائق المدرجة مع تلك الخاصية المعينة على X.

لماذا لا نختار نفس النهج كما لدينا لرمز Java مع اختبارات الوحدة والتكامل؟ اختبار الوحدة يدور حول أخذ الحد الأدنى من الكود واختبار جميع الأوعية المحتملة المحتملة لتحديد المواصفات. مع اختبارات التكامل ، فإن هدفك ليس كل ما يمكن أن يكون مستمياً ولكن دمج عدة وحدات تعمل معًا. افعل الشيء نفسه مع القواعد. فصل القواعد حسب معنى العمل والغرض. يمكن أن تكون أبسط "وحدة ضمن الاختبار" ملفًا مع واحد أو عملة عالية مجموعة من القواعد وما هو مطلوب للعمل (إن وجد) ، مثل ملف تعريف DSL المشترك وجدول القرار. لاختبار التكامل ، يمكنك أخذ مجموعة فرعية ذات معنى أو جميع قواعد النظام.

مع هذا النهج ، سيكون لديك العديد من اختبارات الوحدة المعزولة التي لن تتأثر ولن تتطلب الدعم عندما تضيف قواعد جديدة لأنه سيكون لديك مجموعة من قواعد العمل مع مجموعة فرعية من بيانات الإدخال لاختبار سيناريوهات الأعمال المعنية. وسيكون لديك عدد قليل من اختبارات التكامل مع كمية محدودة من بيانات الإدخال الشائعة لإعادة إنتاج واختبار "السيناريوهات المشتركة". ستتطلب إضافة قواعد جديدة إلى اختبار التكامل تحديث إخراج الاختبار وسوف تعكس كيفية تأثير القواعد الجديدة على تدفق البيانات المشتركة.

انصح قاعدة اختبار جونيت يمنحك ذلك إمكانية تحميل الموارد بطريقة تصريفية وتأكيد القواعد التي يتم تشغيلها بالفعل. سيحافظ على فشل التأكيد الداخلي ويبلغ عن أي قواعد تؤدي إلى عدم تطابق يلمح لك بشأن الخطأ الذي حدث في لمحة. تسجيل تسجيل الضوء على العلاقات بين الأسباب بين الأحداث. يعمل مع SpringRunner.class لاختبارات تكامل الربيع.

مثال:

@DroolsSession(resources = {
        "classpath*:/org/droolsassert/rules.drl",
        "classpath*:/com/company/project/*/{regex:.*.(drl|dsl|xlsx|gdst)}",
        "classpath*:/com/company/project/*/ruleUnderTest.rdslr" },
        ignoreRules = { "before", "after" })
public class DroolsAssertTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    @AssertRules("atomic int rule")
    public void testInt() {
        drools.insertAndFire(new AtomicInteger());
        assertEquals(1, drools.getObject(AtomicInteger.class).get());
    }
}

نرى القواعد
أكثر: https://github.com/droolsassert/droolsassert

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top