请查看testng.xml并提出建议
我想运行2个类(如下所述),但由于在下面提到的2个方案下显示出一些不稳定的行为,因此面临一些挑战。
设置和说明:
有2个测试类:1. HomepageTest和SignIntest
这些测试类下的方法具有组和优先级
**目标是使用
场景1::当我使用Threadcount = 1时;
[test name =“ AutoPracticee” parallel =“ classes” thread-count =“ 1”]
以下是行为:
1.1。执行时,它会启动Homepage [在window1上]>执行Homepagetest的[Priority1]>
,然后启动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
答案 0 :(得分:0)
在决定使用并行执行时,请确保所使用的资源没有在多个线程之间共享。并确保它们是不变的,以提高安全性。 driverObj
是静态的,并且所有测试类都可以同时访问它,这是问题的根本原因。您可以通过在测试方法内部创建和初始化驱动程序并将其安全传递来简化操作。另一种稍微复杂的方法是使用ThreadLocal
对于优先级,这是当前行为,即先运行高优先级测试,然后再运行低优先级测试和iirc,即使没有优先级,也不能保证执行顺序。