当前位置: 首页 > 知识库问答 >
问题:

并行执行多个类的testNg中的不稳定行为:SeleniumWebdriver+testNg

乜安志
2023-03-14

请查看testng.xml并建议
我想运行2个类(下面提到),但面临一些挑战,因为它在下面提到的2个场景下显示了一些不稳定的行为。

这些测试类下的方法具有组和优先级
**目标是使用组运行这些测试

Scenario1:当我使用Threadcount=1时;
[test name=“autopracticee”parallel=“classes”thread-count=“1”]

以下是行为:

1.1.在执行时,它启动主页[在window1]>执行Homepagetest的[Priority1]>
然后启动SignInPage[在Window2(这里窗口1也是打开的)]>>并执行SignIntest的[Priority1]
==>>之后,它执行Homepagetest的[priority2]和SignIntest的
[priority2]等等。
[即执行时根据优先级在主页和SignInTage之间切换]
[参考问题1]

1.2.执行完成后,它将关闭1个窗口(主页)
但无法关闭另一个浏览器(SigninPage)
[此处所有打开的窗口都应关闭,但1关闭且1保持打开][参考问题2]

****场景O2:**当我使用threadcount=2:
**
行为:
2.1。在chrome上同时打开两个窗口--在一个窗口中启动URL(为URL等待10秒)
但在第二个窗口中不启动任何URL(在整个测试过程中保持为空)

2.2:执行与上述1.1相同。
所有执行都发生在1个窗口上,
另一个窗口(空白窗口)在整个测试过程中保持空闲状态。甚至没有为其分配URL

2.3执行完成后,它只关闭一个正在执行的窗口
,即它无法关闭未启动URL的窗口

问题1:[两种情况]为什么执行不是以集团为基础的。
它是在1.1中提到的优先级基础上运行的,这看起来不正确。

理想情况下,它应该执行testClass1的Group1和2
然后关闭该窗口,然后启动第二个窗口并运行Group1和2测试,然后关闭该窗口

问题2:[对于两种情况]为什么无法关闭1浏览器。我使用
窗口句柄对活动窗口进行了计数,
计数返回1,而它应该是2,因为webdriver已经打开了2个窗口

//testNG.xml

    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="AutoPracticee" > <!--   -->
        <parameter name="Browser" value="CH"></parameter>
        <parameter name="URL" 
value="http://automationpractice.com/index.php"></parameter>
        <!-- <parameter name="OSName" value="Windows"></parameter>-->       
<test name="AutoPracticee" parallel = "classes" thread-count = "1"> 
            <!-- For scenario2, execute with -- thread-count = "2" -- -->
            <groups>
                <run>                       
                    <include name="smoke"/>
                    <include name="txt"/>

                <!-- OR 
                     <include name="Homepage_func"/>
                    <include name="SignInpage_func"/>
                Try this set of group also(Both together as a set)
                -->


                </run>
            </groups>
            <classes>
                 <class name= 

"com.automationpracticee.framework.test.createaccountandlogin.SignInTest"/>

                 <class name= 
"com.automationpracticee.framework.test.homepage.HomepageTest"/>   


            </classes>
        </test>    
    </suite>
public class HomepageTest extends UI_GenericMethods{
    Homepage homeObj;
    SignInPage SignInPageObj;

    @BeforeClass(alwaysRun = true)`enter code here`
    @Parameters({ "Browser", "URL" })
    public void getBrowser(String Browser, String URL) throws IOException, 
     InterruptedException {
        System.out.println("getBrowser Method ");
        System.out.println("Launch " + URL + " on " + Browser);
        try {
            homeObj = gm_OpenApp(Browser, URL);

        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    @AfterClass(alwaysRun = true)
    public void tearDown_HP() throws InterruptedException, IOException {
        System.out.println("In tear Down method_HP");
        System.out.println("closing now_HP");
        driverObj.quit();
    }

    // "********Validation of SignIn Link********");
    @Test(priority = 0, groups = { "Homepage_func", "smoke"})
    public void validateHeaderSignInLink_HP() throws Exception {

        System.out.println("In validateHeaderSignInLink Method_HP");
        System.out.println("Out  of validateHeaderSignInLink method_HP");
    }

    // "********Validation of GetSavingNow Button********");
    @Test(priority = 1, groups = { "Homepage_func", "smoke" })
    public void validateGetSavingNowButton_HP() throws Exception {

        System.out.println("In validateGetSavingNowButton Method_HP");
        System.out.println("Out  of validateGetSavingNowButton method_HP");
    }

    @Test(priority = 2, groups = { "Homepage_func", "smoke"})
    // "********Validation of SearchBox********");
    public void validateSearchField_HP() throws Exception {
        System.out.println("In validateSearchField Method_HP");
        System.out.println("Out  of validateSearchField method_HP");
    }

    @Test(priority = 3, groups = { "Homepage_func", "smoke" })
    // "********Validation of Logo********");
    public void validateLogoIcon_HP() throws Exception {
        System.out.println("In validateLogoIcon Method_HP");
        System.out.println("Out  of validateLogoIcon method_HP");
    }

    @Test(priority = 4, groups = { "Homepage_func", "smoke"})
    // "********Validation of Slider1********");
    public void validateHomepageSlider1_HP() throws Exception {
        System.out.println("In validateHomepageSlider1 Method_HP");
        System.out.println("Out  of validateHomepageSlider1 method_HP");

    }

    @Test(priority = 5, groups = { "Homepage_func", "func"})
    // "********Validation of Slider2********");
    public void validateHomepageSlider2_HP() throws Exception {
        System.out.println("In validateHomepageSlider2 Method_HP");
        System.out.println("Out  of Validation of Slider2 method_HP");
    }

    @Test(priority = 6, enabled = false, groups = {"Homepage_func", "func"})
    // "********Validation of Slider3********");
    public void validateHomepageSlider3_HP() throws Exception {
        System.out.println("In validateHomepageSlider3 Method_HP");
        System.out.println("Out  of Validation of Slider3 method_HP");
    }

    // "********Validation of CarouselBlocks********");
    @Test(priority = 7, groups = { "Homepage_func", "func"})
    public void validateHomepageCarouselBlocks_HP() throws Exception {
        System.out.println("In validateHomepageCarouselBlocks Method_HP");
        System.out.println("Out of validateHomepageCarouselBlocks 
     Method_HP");
    }

    // "********Validation of TopPromoBlocks********");
    @Test(priority = 8, groups = { "Homepage_func", "func"})
    public void validateHomepageTopPromoBlocks_HP() throws Exception {
        System.out.println("In validateHomepageTopPromoBlocks Method_HP");
        System.out.println("Out of validateHomepageTopPromoBlocks 
      Method_HP");

    }


    @Test(priority = 9, groups = { "Homepage_txt", "txt"})
    public void validateproductBlock_productName_HP() throws Exception {
        System.out.println("In validateproductBlock_productName_HP Method_HP 
        ");
        System.out.println("Out of validateproductBlock_productName_HP 
         Method_HP ");

    }

    @Test(priority = 10, groups = { "Homepage_txt", "txt"})
    public void validateproductBlock_FooterLinkName_HP() throws Exception {
        System.out.println("In validateproductBlock_FooterLinkName_HP 
        Method_HP ");
        System.out.println("Out of validateproductBlock_FooterLinkName_HP 
        Method_HP ");

     }
 }

//签名:

 public class SignInTest extends UI_GenericMethods{
    Homepage homeObj;
    SignInPage lognObj; 
    @BeforeClass (alwaysRun = true)
    @Parameters({ "Browser", "URL" })
    public void setup_SIP(String Browser, String URL) throwsIOException{
        System.out.println("setup_SIP");
        System.out.println("Launch "+URL+" on "+Browser);
        try {
                homeObj = gm_OpenApp(Browser, URL);
                System.out.println("*Now navigate to login  page*");                                             
                lognObj = homeObj.navigateToSignInPage();
                parentWindow = driverObj.getWindowHandle();
                System.out.println("***Login page is in display***");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    @AfterClass (alwaysRun = true)
    public void tearDown_SIP() throws InterruptedException, IOException{
        System.out.println("In tear Down method_SIP ");
        System.out.println("closing now_SIPP");
        driverObj.quit();       
    }     
    @Test (priority = 1, groups = {"SignInpage_txt", "txt"})
    public  void validateSignInPage_PageHeading_SIP() throws Exception{
        System.out.println("In validateSignInPage_PageHeading Method_SIP");
        System.out.println("Out  of validateSignInPageHeading method_SIP");
    }   
        @Test (priority = 2, groups = {"SignInpage_txt", "txt"})
        public  void validateSignInPage_SignInSectionHeading_SIP() throws 
         Exception{
         System.out.println("In validateSignInPage_SignInSectionHeading 
         Method_SIP");
        System.out.println("Out  of 
    validateSignInPage_SignInSectionHeading method_SIP");
        }   
   @Test (priority = 3, groups = {"SignInpage_txt", "txt"})
   public  void validateSignInPageBreadcrumbText_SIP() throws Exception{
            System.out.println("In validateSignInPageBreadcrumbText 
            Method_SIP");
            System.out.println("Out  of validateSignInPageBreadcrumbText 
             method_SIP");
        }   
         @Test (priority = 4, groups = {"SignInpage_txt", "txt"})
        public  void validateRegistrationSectionHeading_SignInPage_SIP() 
        throws Exception{
            System.out.println("In 
            validateRegistrationSectionHeading_SignInPage Method_SIP");
            System.out.println("Out  of 
            validateRegistrationSectionHeading_SignInPage method_SIP");
        }   
        @Test (priority = 5, groups = {"SignInpage_func", "smoke"})
        public void validateLoginProcess_SIP() throws Exception {
            System.out.println("In validateLoginProcess Method_SIP");
            System.out.println("Out  of validateLoginProcess method_SIP");
        }           
        @Test (priority = 6, groups = {"SignInpage_func", "func"})
        public void validateForgotPasswordLink_SIP() throws IOException, 
        InterruptedException, InvalidFormatException{
            System.out.println("In validateForgotPasswordLink Method_SIP");
            System.out.println("Out  of validateForgotPasswordLink 
           method_SIP");        
        }
    } 

可重用方法库

public class UI_GenericMethods{

    protected static WebDriver driverObj;
    protected Homepage homeObj;


    /****************************************
     * Launch Browser & URL
     ****************************************************/

    /******************** Launch Browser **************************/

    public void gm_LaunchBrowser(String browserName){

        if (browserName.equalsIgnoreCase("CH") == true) {
        System.getProperty("webdriver.chrome.driver", "Please put Path 
         here");
        driverObj = new ChromeDriver();

        // Launch Firefox browser
    } else if (browserName.equalsIgnoreCase("FF") == true) {
        System.getProperty("webdriver.gecko.driver", "Please put Path 
        here");
        driverObj = new FirefoxDriver();        
    } else {
        System.out.println("Please enter correct browser name");
    }   
       driverObj.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
       driverObj.manage().timeouts().pageLoadTimeout(200, TimeUnit.SECONDS);
       driverObj.manage().window().maximize();

  }

    /******************** Open Site **************************/
    public static void gm_OpenURL(String URL) {
        driverObj.get(URL);
    }

   public Homepage gm_OpenApp(String BrowserName, String URL){
       System.out.println("In gm_OpenAp Method");
       gm_LaunchBrowser(BrowserName);
       try { //Just to wait for few seconds before and after URL launch
           Thread.sleep(10000);
       } catch (InterruptedException e) {       
          e.printStackTrace();
       }
       gm_OpenURL(URL);  //URL Launched
       try {
          Thread.sleep(10000);
       } catch (InterruptedException e) {       
            e.printStackTrace();
       }
        System.out.println("URL done");
       System.out.println("Now Homepage is in display");
       homeObj = PageFactory.initElements(driverObj, Homepage.class);
       return homeObj;
     }
  }

共有1个答案

解飞语
2023-03-14

当决定使用并行执行时,请确保您使用的资源不是跨多个线程共享的。并确保它们是不可变的,以增加安全性。driverobj是静态的,所有测试类都可以同时访问它,它是问题的根本原因。您可以通过在测试方法内部创建和初始化驱动程序来保持它的简单,并安全地传递它。另一种稍微复杂的方法是使用threadlocal

对于优先级,当前的行为是优先级较高的测试首先运行,然后是优先级较低的测试,iirc即使没有优先级,执行顺序也无法保证。

 类似资料:
  • 我试图使用Selenium和TestNG进行测试设计,我将每个@test放在一个单独的类中,并对所有类使用once@beforeSuite&@afterSuite,原因是: 代码易于维护 数据驱动,以便能够选择通过文件运行的类。 案例1类: 注意:如果上面的代码在套件中使用单个运行,它就可以正常工作。 问题是它是否像下面的配置那样并行运行。

  • 我有4个@Test方法,希望每个方法都运行3次。我想在12个线程中同时执行所有这些。 我创建了一个testng。像这样的xml文件 如果我设置并行="方法",TestNG在Test1的4个线程中执行4个测试方法,之后对Test2执行相同的操作,然后对Test3执行相同的操作。但是我不想在运行Test2之前等待Test1完成。TestNG能够运行Test1、Test2 有没有办法告诉TestNG不要

  • 问题内容: 下面的代码(几乎相同)在Linux下可以计算页面浏览量,但在Windows下可以将页面浏览量提高一倍。 有人能弄清楚为什么吗? 在Mingw下: 这可能是错误吗? 跟进: 实际上,如果我为另一个页面定义了其他处理程序,例如: Wich没有闭包,也没有增加任何东西,计数器无论如何都会增加,但是只有+1: 因此,仍然在Mingw的领导下: 在Linux下,输出如下所示: 问题答案: 我怀疑

  • 我试图用Cucumber,用不同的参数并行运行多个testng套件。对于每个tesng套件,我试图传递不同的浏览器、testinfo等等。我想通过maven命令行选项来实现这一点。我关注了https://rationaleemotions.wordpress.com/2016/03/29/parallel-execution-of-multiple-testng-suites/#comment-1

  • 问题内容: 我有一个测试,可以从数据提供者那里接收数据。我希望此测试与数据提供者的不同值并行运行。 我尝试了类似的方法: } 我收到的输出是: 你好:10 你好:12 你好:17 你好:11 你好:16 你好:14 你好:13 你好:15 产生10个线程,而我在线程池大小中指定5个。您能否告诉我们必须在上述代码段中添加哪些内容来控制数据提供程序线程池的大小。 问题答案: 您需要使用。在和不需要的值

  • TestNG Runner类执行多个功能文件? 我知道我们可以创建一个可以针对多个TestNG测试类的TestNG xml,但是我们可以创建一个可以针对多个Cucumber/ Junit特性文件的TestNG.xml吗?