并行完成多个类的testNg执行中的异常行为:SeleniumWebdriver + TestNG

时间:2018-09-01 20:12:11

标签: selenium-webdriver testng

请查看testng.xml并提出建议
我想运行2个类(如下所述),但由于在下面提到的2个方案下显示出一些不稳定的行为,因此面临一些挑战。

设置和说明:

  1. 有2个测试类:1. HomepageTest和SignIntest

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

  3. 组运行这些测试

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

以下是行为:

1.1。执行时,它会启动Homepage [在window1上]>执行Homepagetest的[Pri​​ority1]>
,然后启动SignInPage [在Window2 (此处也打开了窗口1)] >>并执行[priority1]的SignIntest
== >>此后,它将执行HomepageTest的[priority2]和SigninTest的
[priority2]等。.
[即,执行将在优先级的Homepage和SignInpage之间切换]
[请参阅问题1]

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

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

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

2.3执行完成后,它仅关闭正在执行执行操作的1个窗口
也就是说,它无法关闭没有启动URL的窗口

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

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

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

问题3:[用于第二种情况] :当线程数= 2时,为什么它启动空白窗口
(如2.1中所述)

//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>

// HomepageTest:

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 ");

     }
 }

// SignInTest:

 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;
     }
  }

场景2的控制台输出         
setup_SIP         
getBrowser方法         
在CH上启动http://automationpractice.com/index.php     
在CH上启动http://automationpractice.com/index.php     
在gm_OpenAp方法中     
在gm_OpenAp方法中     
CH-http://automationpractice.com/index.php     
CH-http://automationpractice.com/index.php     
1 G:\ QA \ AutomationTools \ WorkspaceMars1 \ 1.2hp.com.automationprac \         ChromeDriver \ Chromedriver_win32_v2.38 \ chromedriver.exe     
1 G:\ QA \ AutomationTools \ WorkspaceMars1 \ 1.2hp.com.automationprac \         ChromeDriver \ Chromedriver_win32_v2.38 \ chromedriver.exe *     
2 G:\ QA \ AutomationTools \ WorkspaceMars1 \ 1.2hp.com.automationprac \         ChromeDriver \ Chromedriver_win32_v2.38 \ chromedriver.exe        
2G:\ QA \ AutomationTools \ WorkspaceMars1 \ 1.2hp.com.automationprac \         ChromeDriver \ Chromedriver_win32_v2.38 \ chromedriver.exe     
启动ChromeDriver 2.38.552522                                   (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb)     
端口17592     
仅允许本地连接。     
启动ChromeDriver          2.38.552522(437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb)     在端口11565上     
仅允许本地连接。     
Sep 02,2018 3:38:46 AM org.openqa.selenium.remote.ProtocolHandshake       createSession     
INFO:检测到的方言:OSS     
Sep 02,2018 3:38:46 AM org.openqa.selenium.remote.ProtocolHandshake     createSession     
INFO:检测到的方言:OSS     
浏览器名称已完成     
浏览器名称已完成     
网址已完成 [我的评论-此处为空白[用于方案2]]     
现在显示主页     
*******现在导航到登录页面*******     
在validateHeaderSignInLink方法_HP中     
超出validateHeaderSignInLink方法_HP     
网址已完成     
现在显示主页     
*******现在导航到登录页面*******     
1     
2     
*******显示登录页面*******     
在validateSignInPage_PageHeading方法_SIP中     
超出validateSignInPageHeading方法_SIP     
在validateSignInPage_SignInSectionHeading方法_SIP中     
在validateGetSavingNowButton方法中_HP     
超出validateSignInPage_SignInSectionHeading方法_SIP     
超出validateGetSavingNowButton方法_HP     
在validateSignInPageBreadcrumbText方法中_SIP     
超出validateSignInPageBreadcrumbText方法_SIP     
在validateSearchField Method_HP中     
超出validateSearchField方法_HP     
在validateRegistrationSectionHeading_SignInPage方法_SIP中     
超出validateRegistrationSectionHeading_SignInPage方法_SIP的范围
    
在validateLogoIcon方法中_HP
    
超出validateLogoIcon方法的范围_HP     
在validateLoginProcess方法中_SIP     
超出validateLoginProcess方法_SIP     
在拆解方法中_SIP     
立即关闭_SIPP ** [我的评论-无法关闭[针对方案1和2]
    
在validateHomepageSlider1方法中_HP     
超出validateHomepageSlider1方法范围_HP     
在validateproductBlock_productName_HP方法_HP中     
超出validateproductBlock_productName_HP方法_HP     
在validateproductBlock_FooterLinkName_HP Method_HP中     
超出validateproductBlock_FooterLinkName_HP方法_HP     
在拆解方法中_HP     
立即关闭_HP [我的评论-此处已关闭[针对方案1&2]
    
[INFO]测试运行:12,失败:0,错误:0,跳过:0,经过时间:      
44.759 s-在TestSuite中     
[INFO]     
[INFO]结果:     
[INFO]     
[INFO]测试运行:12,失败:0,错误:0,跳过:0     
[INFO]     
[INFO] ------------------------------------------- ----------------------      
[INFO]建立成功     
[INFO] ------------------------------------------- -------------------      
[INFO]总时间:50.490 s

1 个答案:

答案 0 :(得分:0)

在决定使用并行执行时,请确保所使用的资源没有在多个线程之间共享。并确保它们是不变的,以提高安全性。 driverObj是静态的,并且所有测试类都可以同时访问它,这是问题的根本原因。您可以通过在测试方法内部创建和初始化驱动程序并将其安全传递来简化操作。另一种稍微复杂的方法是使用ThreadLocal

对于优先级,这是当前行为,即先运行高优先级测试,然后再运行低优先级测试和iirc,即使没有优先级,也不能保证执行顺序。