هل يمكنني تحديد مجموعة واسعة النطاق في حالة اختبار TestNG؟

StackOverflow https://stackoverflow.com/questions/9044

  •  08-06-2019
  •  | 
  •  

سؤال

لدي فئة أساسية تمثل اختبار قاعدة بيانات في TestNG، وأريد تحديد أن جميع الفئات الممتدة من هذه الفئة تنتمي إلى مجموعة "db-test"، لكنني وجدت أن هذا لا يبدو ممكنًا.لقد جربت التعليق التوضيحيTest:

@Test(groups = { "db-test" })
public class DBTestBase {
}

ومع ذلك، هذا لا يعمل لأن التعليق التوضيحيTest سيحاول إدخال مجموعة من الأساليب في الاختبارات، وستظهر التحذيرات/الأخطاء في الكسوف عند تشغيل الاختبارات.

لذا حاولت تعطيل الاختبار، بحيث يتم تعيين المجموعات على الأقل:

@Test(enabled = false, groups = { "db-test" })
public class DBTestBase {
}

ولكن بعد ذلك يتم أيضًا تعطيل أي @BeforeTest (والتعليقات التوضيحية المشابهة الأخرى) ...وهذا بالطبع ليس ما أريد.

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

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

المحلول

الجواب من خلال العرف org.testng.IMethodSelector:

إنه تضمين الطريقة () يمكننا استبعاد أي طريقة نريدها، مثل الطريقة العامة غير المشروحة.

ومع ذلك، لتسجيل العرف جافا MethodSelector، يجب عليك إضافته إلى ملف XMLTest مثيل تتم إدارته بواسطة أي TestRunner، مما يعني أنك بحاجة إلى مثيل خاص بك اختبار عداء مخصص.

ولكن، لإنشاء TestRunner مخصص، تحتاج إلى تسجيل ملف TestRunnerFactory, ، عبر ال -testrunfactory خيار.

ولكن هذا -testrunfactory لم يؤخذ بعين الاعتبار أبدًا اختبار فصل...لذلك تحتاج أيضًا إلى تحديد فئة TestNG مخصصة:

  • من أجل تجاوز طريقة التكوين (الخريطة)،
  • حتى تتمكن بالفعل من ضبط TestRunnerFactory
  • TestRunnerFactory الذي سيبني لك TestRunner مخصصًا،
  • TestRunner الذي سيقوم بتعيين XMLMethodSelector مخصص لمثيل XMLTest
  • XMLMethodSelector الذي سيقوم بإنشاء IMethodSelector مخصص
  • IMethodSelector الذي سيستبعد أي طرق TestNG من اختيارك!

نعم...انه كابوس.ولكنه أيضًا يمثل تحديًا برمجيًا، لذا يجب أن يكون صعبًا بعض الشيء ;)

كل الكود متاح في مقتطفات من منطقة DZone.

كالعادة بالنسبة لتحدي الكود:

  • فئة جافا واحدة (وعدد لا بأس به من الفئات الداخلية)
  • انسخ الفصل والصقه في دليل "المصدر/الاختبار" (نظرًا لأن الحزمة هي "اختبار")
  • تشغيله (لا حاجة للوسائط)

تحديث من مايك ستون:

سأقبل هذا لأنه يبدو قريبًا جدًا مما انتهيت من القيام به، لكنني اعتقدت أنني سأضيف ما فعلته أيضًا.

في الأساس، قمت بإنشاء تعليق توضيحي للمجموعات يتصرف مثل خاصية المجموعات الخاصة بالتعليقات التوضيحية الاختبارية (وغيرها).

بعد ذلك، قمت بإنشاء GroupsAnnotationTransformer، الذي يستخدم IAnnotationTransformer للنظر في جميع الاختبارات وفئات الاختبار التي تم تعريفها، ثم قام بتعديل الاختبار لإضافة المجموعات، والذي يعمل بشكل مثالي مع استبعاد المجموعة وإدراجها.

قم بتعديل البنية لاستخدام محول التعليقات التوضيحية الجديد، وكل شيء يعمل بشكل مثالي!

حسنًا...التحذير الوحيد هو أنه لا يضيف المجموعات إلى طرق غير اختبارية ...لأنه في الوقت الذي قمت فيه بذلك، كان هناك محول تعليق توضيحي آخر يتيح لك تحويل أي شيء، ولكن بطريقة ما لم يتم تضمينه في TestNG الذي كنت أستخدمه لسبب ما ...لذلك من الجيد أن تجعل الطرق المشروحة قبل/بعد AlwaysRun=true...وهو ما يكفي بالنسبة لي.

والنتيجة النهائية هي أنني أستطيع أن أفعل:

@Groups({ "myGroup1", "myGroup2"})
public class MyTestCase {
    @Test
    @Groups("aMethodLevelGroup")
    public void myTest() {
    }
}

ولقد جعلت المحول يعمل مع الفئات الفرعية وكل شيء.

نصائح أخرى

سيقوم TestNG بتشغيل كافة الأساليب العامة من فصل دراسي يحتوي على تعليق توضيحيTest.ربما يمكنك تغيير الطرق التي لا تريد أن يعمل بها TestNG لتكون غير عامة

يبدو لي على النحو التالي تحدي الكود (منشور ويكي المجتمع):

كيف تكون قادرًا على تنفيذ جميع طرق اختبار الفئة الممتدة من المجموعة "aGlobalGroup" بدون:

  • تحديد مجموعة "aGlobalGroup" في الفئة الموسعة نفسها؟
  • اختبار الأساليب العامة غير المشروحة للفئة الموسعة؟

الجواب الأول سهل:
إضافة فئة TestNG(groups = { "aGlobalGroup" }) على مستوى الفئة الأساسية

سيتم تطبيق هذه المجموعة على كافة الأساليب العامة لكل من الفئة الأساسية والفئة الموسعة.

لكن:حتى الطرق العامة غير التجريبية (بدون تعليق توضيحي لـ TestNG) سيتم تضمينها في تلك المجموعة.

تحدي:تجنب تضمين تلك الأساليب التي لا تتعلق بـ TestNG.

@Test(groups = { "aGlobalGroup" })
public class Base {

    /**
     * 
     */
    @BeforeClass
     public final void setUp() {
           System.out.println("Base class: @BeforeClass");
     }


    /**
     * Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
     * Will be executed even if the TestNG class tested is a sub-class.
     */
    @Test(groups = { "aLocalGroup" })
     public final void aFastTest() {
       System.out.println("Base class: Fast test");
     }

    /**
     * Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
     * Will be executed even if the TestNG class tested is a sub-class.
     */
    @Test(groups = { "aLocalGroup" })
     public final void aSlowTest() {
        System.out.println("Base class: Slow test");
        //throw new IllegalArgumentException("oups");
     }

     /**
      * Should not be executed. <br />
      * Yet the global annotation Test on the class would include it in the TestNG methods...
     */
    public final void notATest() {
       System.out.println("Base class: NOT a test");
     }

    /**
     * SubClass of a TestNG class. Some of its methods are TestNG methods, other are not. <br />
     * The goal is to check if a group specify in the super-class will include methods of this class. <br />
     * And to avoid including too much methods, such as public methods not intended to be TestNG methods.
     * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a>
     */
    public static class Extended extends Base
    {
        /**
         * Test not part a 'aGlobalGroup', but still included in that group due to the super-class annotation. <br />
         * Will be executed even if the TestNG class tested is a sub-class.
         */
        @Test
        public final void anExtendedTest() {
           System.out.println("Extended class: An Extended test");
        }

        /**
         * Should not be executed. <br />
         * Yet the global annotation Test on the class would include it in the TestNG methods...
         */ 
        public final void notAnExtendedTest() {
            System.out.println("Extended class: NOT an Extended test");
        }
    }

لست متأكدًا من كيفية عمل وراثة التعليقات التوضيحية لـ TestNG ولكن هذا شرط قد تكون ذات فائدة.

في الواقع، قد يكون هذا مساعدة أفضل, ، انظر إلى inheritGroups.

يمكنك تحديد التعليق التوضيحيTest على مستوى الطريقة الذي يسمح بأقصى قدر من المرونة.

public class DBTestBase {

    @BeforeTest(groups = "db-test")
    public void beforeTest() {
        System.out.println("Running before test");
    }

    public void method1() {
        Assert.fail(); // this does not run. It does not belong to 'db-test' group.
    }

    @Test(groups = "db-test")
    public void testMethod1() {
        Assert.assertTrue(true);
    }
}

هل هذا يناسبك أم أني أفتقد شيئًا من سؤالك.

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