هل يتم تنفيذ أساليب TestNG BEBOFFORESUITE قبل أساليب BEForetest؟

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

  •  25-09-2019
  •  | 
  •  

سؤال

الخلفية: هدفي هو ترميز نظام Testng-Selenium الذي يعمل بذاته (لا توجد سلاسل إلى Maven أو Ant Plugins ؛ Just Java). يجب أن تسمح لحالات الاختبار لقبول المعلمات بما في ذلك المتصفح وعنوان URL المجال. عندما يقوم Testrunner بتركيب حالات الاختبار هذه ، يتم استخدام المتصفح والمجال للحصول على كائن سيلينيوم لإجراء اختباره.

المشكلة: تنجح فئة اختبار واحدة فقط لكل جناح في الحصول على معلمة المجال (في طريقة beboforesuite) قبل محاولة الحصول على كائن سيلينيوم (في beforetest). فئات الاختبار التي لا تتلقى المجال لها كائن سيلينيوم فارغ ب/ج لا يمكن إنشاءه.

رمز: يتم احتواء كل منها XMLClasses داخل XMLTest الخاص بها ، وكل الثلاثة في XMLSUITE واحد. يحتوي الجناح على ترتيب TestClass1 ، TestClass2 ، ثم testClass3. فئات الاختبار نفسها هي فئات فرعية من طبقتين من فئتي القاعدة التجريدية تتضمن وظائف لتهيئة المتغيرات المحقونة وبالتالي الحصول على مثيل للسيلينيوم. والغرض من ذلك هو اختبار تطبيق واحد أو عدة تطبيقات (على مجالات متعددة) مع أقل قدر ممكن من الكود المتكرر (أي: إن تثبيت السيلينيوم في فئة القاعدة الجذرية لأنه شائع في جميع الاختبارات). انظر الأساليب أدناه للحصول على التفاصيل.

// Top-most custom base class
abstract public class WebAppTestBase extends SeleneseTestBase
{
        private static Logger logger = Logger.getLogger(WebAppTestBase.class);
        protected static Selenium selenium = null;
        protected String domain = null;
        protected String browser = null;

        @BeforeTest(alwaysRun = true)
        @Parameters({ "selenium.browser" })
        public void setupTest(String browser)
        {
                this.browser = browser;
                logger.debug(this.getClass().getName()
                                + " acquiring Selenium instance ('" + this.browser + " : " + domain + "').");
                selenium = new DefaultSelenium("localhost", 4444, browser, domain);
                selenium.start();
        }

}

// Second level base class.
public abstract class App1TestBase extends WebAppTestBase
{

        @BeforeSuite(alwaysRun = true)
        @Parameters({"app1.domain" })
        public void setupSelenium(String domain)
        {
                // This should execute for each test case prior to instantiating any Selenium objects in @BeforeTest
                logger.debug(this.getClass().getName() + " starting selenium on domain '" + domain+ "'.");
                this.domain = domain;
        }
}

// Leaf level test class
public class TestClass1 extends App1TestBase
{
        @Test
        public void validateFunctionality() throws Exception
        {
                // Code for tests go here...
        }
}

// Leaf level test class
public class TestClass2 extends App1TestBase
{
        @Test
        public void validateFunctionality() throws Exception
        {
                selenium.isElementPresent( ...
                // Rest of code for tests go here...
                // ....
        }
}


// Leaf level test class
public class TestClass3 extends App1TestBase
{
        @Test
        public void validateFunctionality() throws Exception
        {
                // Code for tests go here...
        }
}

الإخراج: TestCase3 يعمل بشكل صحيح. TestCase1 و TestCase2 فشل. يتم إنشاء تتبع المكدس ...

 10:08:23 [DEBUG RunTestCommand.java:63] - Running Tests.
 10:08:23 [Parser] Running:
  Command line suite
  Command line suite

[DEBUG App1TestBase.java:49] - TestClass3 starting selenium on domain 'http://localhost:8080'.
 10:08:24 [DEBUG WebAppTestBase.java:46] - TestClass2 acquiring Selenium instance ('*firefox : null').
 10:08:24 [ERROR SeleniumCoreCommand.java:40] - Exception running 'isElementPresent 'command on session null
 10:08:24 java.lang.NullPointerException: sessionId should not be null; has this session been started yet?
        at org.openqa.selenium.server.FrameGroupCommandQueueSet.getQueueSet(FrameGroupCommandQueueSet.java:216)
        at org.openqa.selenium.server.commands.SeleniumCoreCommand.execute(SeleniumCoreCommand.java:34)
        at org.openqa.selenium.server.SeleniumDriverResourceHandler.doCommand(SeleniumDriverResourceHandler.java:562)
        at org.openqa.selenium.server.SeleniumDriverResourceHandler.handleCommandRequest(SeleniumDriverResourceHandler.java:370)
        at org.openqa.selenium.server.SeleniumDriverResourceHandler.handle(SeleniumDriverResourceHandler.java:129)
        at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1530)
        at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1482)
        at org.openqa.jetty.http.HttpServer.service(HttpServer.java:909)
        at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820)
        at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
        at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837)
        at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:245)
        at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:357)
        at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:534)

أنا أقدر أي معلومات قد تكون لديك حول هذه المسألة.

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

المحلول

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

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

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

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