سؤال

لدي فئة قاعدة مجردة ، والتي أستخدمها كقاعدة لاختبارات وحدتي (TestNG 5.10). في هذه الفئة ، أقوم بتهيئة البيئة بأكملها للاختبارات الخاصة بي ، وإعداد تعيينات قاعدة البيانات ، وما إلى ذلك. تحتوي هذه الفئة المجردة على طريقة مع أ @BeforeClass التعليق التوضيحي الذي يفعل التهيئة.

بعد ذلك ، أقدم هذا الفصل بفئات محددة لدي @Test الأساليب وأيضا @BeforeClass طُرق. تقوم هذه الطرق بتهيئة البيئة الخاصة بالفئة (على سبيل المثال ، وضع بعض السجلات في قاعدة البيانات).

كيف يمكنني فرض ترتيب محدد من @BeforeClass أساليب مشروحة؟ أحتاج إلى تنفيذ تلك من فئة القاعدة التجريدية قبل تلك الفئة الممتدة.

مثال:

abstract class A {
    @BeforeClass
    doInitialization() {...}
}

class B extends A {
    @BeforeClass
    doSpecificInitialization() {...}

    @Test
    doTests() {...}
}

الترتيب المتوقع:

A.doInitialization
B.doSpecificInitialization
B.doTests

الترتيب الفعلي:

B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization        // <---not executed
 B.doTests)                // <-/
هل كانت مفيدة؟

المحلول

لا تضع @BeforeClass على ال abstract صف دراسي. نسميها من كل فئة فرعية.

abstract class A {
    void doInitialization() {}
}

class B extends A {
    @BeforeClass
    void doSpecificInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}

يبدو أن Testng لديه @BeforeClass(dependsOnMethods={"doInitialization"}) - جربها.

نصائح أخرى

تعديل: الجواب أدناه هو جونيت, ، لكنني سأترك الأمر هنا على أي حال ، لأنه قد يكون مفيدًا.

بحسب ال JUNIT API: "سيتم تشغيل أساليب BeboReClass من الفئات الفائقة قبل تلك الفئة الحالية."

لقد اختبرت هذا ، ويبدو أنه يعمل بالنسبة لي.

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

أضفت public إلى الفئة التجريدية و testng (6.0.1) نفذت doinitialization () من قبل doTests. لا يتم تنفيذ testng doInitialization() إذا أزلت public من الفئة أ

public abstract class A {
 @BeforeClass
 doInitialization() {...}
}

class B extends A {    
 @Test
 doTests() {...}
}

لقد جربت مثالك فقط مع 5.11 وأحصل على @beforeclass من الفئة الأساسية التي تم استدعاؤها أولاً.

هل يمكنك نشر ملف testng.xml الخاص بك؟ ربما تحدد كل من A و B ، في حين أن B ضروري فقط.

لا تتردد في المتابعة على قائمة المراسلين للمستخدمين ، ويمكننا إلقاء نظرة فاحصة على مشكلتك.

- سيدريك

لقد مررت للتو ووجدت طريقة أخرى لتحقيق ذلك. فقط استخدم alwaysRun على @BeforeClass أو @BeforeMethod في الفصل التجريدي ، يعمل كما تتوقع.

public class AbstractTestClass {
    @BeforeClass(alwaysRun = true)
    public void generalBeforeClass() {
        // do stuff
        specificBeforeClass();
    }
}

عندما أركض من: junitcore.runclasses (testclass.class) ؛سوف ينفذ الوالد بشكل صحيح ، قبل الطفل (لا تحتاج super.setupbeforeClass () ؛) إذا قمت بتشغيله من Eclipse: لسبب ما فشل في تشغيل الفئة الأساسية. العمل حوله: اتصل بالفئة الأساسية بشكل واضح: ((BASETEST.SETUPBEFORECLASS () ؛) قد ترغب في الحصول على علامة في الفئة الأساسية في حالة تشغيله من التطبيق ، لتحديد ما إذا كان الإعداد بالفعل أم لا. لذلك يتم تشغيله مرة واحدة فقط إذا قمت بتشغيله عبر كلتا الأساليب الممكنة (مثل من Eclipse للاختبار الشخصي ، ومن خلال ANT لإصدار البناء).

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

ل Junit: كما ذكرت @"

لكن كن حريص عدم تسمية كلتا الطريقتين بنفس الاسم. لأنه في هذه الحالة سيتم إخفاء طريقة الوالدين من قبل والد الطفل. مصدر.

ماذا عن وجود طريقة beboReClass الخاصة بك ، استدعاء طريقة فارغة foreClass () التي قد تتم نسخها أو لا تتم نسخها بواسطة فئات فرعية مثل ذلك:

public class AbstractTestClass {
  @BeforeClass
  public void generalBeforeClass() {
    // do stuff
    specificBeforeClass();
  }

  protected void specificBeforeClass() {}
}

public class SpecificTest {
  @Override
  protected void specificBeforeClass() {
    // Do specific stuff
  }

  // Tests
}

dependsOnMethod من الممكن استخدامه.

على سبيل المثال في حالة الربيع (AbstractTestNGSpringContextTests)

@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")

تحقق من بيان الاستيراد الخاص بك. يجب أن يكون

import org.testng.annotations.BeforeClass;

ليس

import org.junit.BeforeClass;

لماذا لا تحاول إنشاء طريقة مجردة dospecialinit () في فئتك الفائقة ، والتي تسمى من طريقة BeforeClass المشروح في الفئة الفائقة.

لذا فإن تطوير المراوغة ويرث صفك يجبر على تنفيذ هذه الطريقة.

هناك حل سهل آخر هنا.

وضعي الخاص هو أنني بحاجة إلى ضخ الخدمات الوهمية من "Beforeclass" في الفئة الفرعية قبل تنفيذ "BeforeClass" في الفئة الفائقة.

للقيام بذلك - ببساطة استخدم أ @ClassRule في الفئة الفرعية.

فمثلا:

@ClassRule
public static ExternalResource mocksInjector = new ExternalResource() {
    @Override
    protected void before() {
        // inject my mock services here
        // Note: this is executed before the parent class @BeforeClass
    }
};

آمل أن يساعد هذا. هذا يمكن أن ينفذ بشكل فعال الإعداد الثابت في ترتيب "عكسي".

لقد واجهت مشكلة مماثلة اليوم ، كان الفرق الوحيد هو أن الطبقة الأساسية لم تكن مجردة

ها هي حالتي

public class A {
    @BeforeClass
    private void doInitialization() {...}
}

public class B extends A {
    @BeforeClass
    private void doSpecificInitialization() {...}

    @Test
    public void doTests() {...}
}

حدث ذلك أ @BeforeClass لم يتم تنفيذ الطريقة من الفئة A أبدًا.

  • A.Doinitialization () -> لم يتم تنفيذ هذا بصمت أبدًا
  • B.DospecificInitialization ()
  • B.Dotests ()

اللعب مع معدلات الخصوصية وجدت أن testng لن ينفذ أ @BeforeClass طريقة مشروحة من الطبقة الموروثة إذا كانت الطريقة غير مرئية من فئة من الدرجة

لذلك هذا سوف يعمل:

public class A {
    @BeforeClass
    private void doInitialization() {...}
}

public class B extends A {
    @BeforeClass
    //Here a privacy modifier matters -> please make sure your method is public or protected so it will be visible for ancestors
    protected void doSpecificInitialization() {...}

    @Test
    public void doTests() {...}
}

نتيجة لذلك يحدث: يحدث:

  • A.Doinitialization ()
  • B.DospecificInitialization ()
  • B.Dotests ()

هذا يعمل بالنسبة لي -

abstract class A {
    @BeforeClass
    doInitialization() {...}
}

class B extends A {
    @Override
    @BeforeClass
    doInitialization() { 

       //do class specific init

    }   

    @Test
    doTests() {...}
}

في حالتي (Junit) لدي نفس الأساليب التي تسمى الإعداد () في الفئة الأساسية والفئة المشتقة. في هذه الحالة فقط يتم استدعاء طريقة الفئة المشتقة ، وأنا أتصل بها طريقة الفئة الأساسية.

قد تكون طريقة أفضل وأنظف لتحقيق ذلك باستخدام الميراث على النحو التالي -

abstract class A {

    @BeforeClass
    void doInitialization() {}
}

class B extends A {

    @Override
    @BeforeClass
    void doInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top