请查看testng.xml,请提出建议 我想运行2个课程(如下所述),但面临一些挑战,因为它显示了2种情况下的一些不稳定的行为,如下所述。
设置和说明:
场景1:当我使用Threadcount = 1时; [test name =“AutoPracticee”parallel =“classes”thread-count =“1”] 以下是行为:
1.1。在执行时,它启动主页[在窗口1]>执行Homepagetest的[Priority1]> 然后启动SignInPage [On Window2(此处窗口1也打开)] >>并执行SignIntest的[priority1] == >>之后执行HomepageTest的[priority2]和 SigninTest的[priority2]等等.. [即执行优先在主页和SignInpage之间切换] [参考问题1]
1.2。执行完成后,关闭1个窗口(主页) 但无法关闭其他浏览器(SigninPage) [这里所有打开的窗户应该关闭但是1关闭,1仍然打开] [参考问题2] ****场景2:**当我使用threadcount = 2时: ** 行为: 2.1。它在chrome上同时打开2个窗口 - 在一个窗口中它启动URL(对于URL等待10秒) 但在第二个窗口中它不会启动任何URL(在整个测试过程中保持空白)
2.2:执行就像上面提到的1.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>
//首页测试:
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");
}
}
可重用的方法Lib
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;
}
}
Scenario2的控制台输出 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 仅允许本地连接。 在端口11565上启动ChromeDriver 2.38.552522(437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb) 仅允许本地连接。 2018年9月2日上午3:38:46 org.openqa.selenium.remote.ProtocolHandshake createSession 信息:检测到的方言:OSS 2018年9月2日上午3:38:46 org.openqa.selenium.remote.ProtocolHandshake createSession 信息:检测到的方言:OSS Browsrname完成了 Browsrname完成了 网址已完成[我的评论 - 这仍为空白[适用于Scenario2]] 现在主页正在展示中 *******现在导航到登录页面******* 在validateHeaderSignInLink Method_HP中 超出validateHeaderSignInLink方法_HP 网址已完成 现在主页正在展示中 *******现在导航到登录页面******* 1 2 *******登录页面显示******* 在validateSignInPage_PageHeading Method_SIP中 超出validateSignInPageHeading method_SIP 在validateSignInPage_SignInSectionHeading Method_SIP中 在validateGetSavingNowButton Method_HP中 超出validateSignInPage_SignInSectionHeading method_SIP 超出validateGetSavingNowButton方法_HP 在validateSignInPageBreadcrumbText Method_SIP中 超出validateSignInPageBreadcrumbText方法_SIP 在validateSearchField Method_HP中 超出validateSearchField method_HP 在validateRegistrationSectionHeading_SignInPage Method_SIP中 超出validateRegistrationSectionHeading_SignInPage method_SIP 在validateLogoIcon Method_HP中 超出validateLogoIcon method_HP 在validateLoginProcess Method_SIP中 超出validateLoginProcess method_SIP 在拆卸方法_SIP 关闭now_SIPP ** [我的评论 - 无法关闭[对于方案1和2] 在validateHomepageSlider1 Method_HP中 超出validateHomepageSlider1 method_HP 在validateproductBlock_productName_HP Method_HP中 超出validateproductBlock_productName_HP Method_HP 在validateproductBlock_FooterLinkName_HP Method_HP中 超出validateproductBlock_FooterLinkName_HP Method_HP 在拆卸方法_HP 关闭now_HP [我的评论 - 关闭[对于方案1和2] [INFO]测试运行:12,失败:0,错误:0,跳过:0,已过去时间: 44.759秒 - 在TestSuite中 [信息] [INFO]结果: [信息] [INFO]测试运行:12,失败:0,错误:0,跳过:0 [信息] [INFO] ----------------------------------------------- ------------------ [信息]建立成功 [INFO] ----------------------------------------------- --------------- [INFO]总时间:50.490秒
在决定使用并行执行时,请确保不使用多个线程共享您正在使用的资源。并且还要确保它们不可改变以增加安全性。 driverObj
是静态的,可以同时被所有测试类访问,并且是导致问题的根本原因。您可以通过在测试方法中创建和初始化驱动程序并安全地传递它来保持简单。另一个稍微复杂的方法是使用ThreadLocal
而对于优先级,这就是当前行为首先运行优先级较高的测试,然后是降低优先级的测试,即使没有优先级,也不会保证执行顺序。