Java Selenium Webdriver:如何在同一窗口中一个接一个地运行多个测试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27388940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:16:55  来源:igfitidea点击:

Selenium Webdriver: How do I run multiple tests, one after the other in the same window?

javaseleniumwebdrivertestng

提问by Jason Krept

My goal is to have a series of tests run one after the other. I would like to have a "login" script log the user in and then the following scripts kick off continuing in the same window/driver. I'm using TestNG so my test suite is setup in the testng.xml file if that helps.

我的目标是让一系列测试一个接一个地运行。我想要一个“登录”脚本让用户登录,然后下面的脚本开始在同一个窗口/驱动程序中继续。我正在使用 TestNG,所以如果有帮助的话,我的测试套件是在 testng.xml 文件中设置的。

public class LoginScript {
String username, password, siteid;
private WebDriver driver;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
static Logger log = Logger.getLogger(LoginScript.class);


@BeforeSuite (alwaysRun=true)
@Parameters({ "url","username","password","site" })

public void setUp(String env, String user, String pwd, String ste) throws Exception {
username=user;
password=pwd;
siteid=ste;

driver = new FirefoxDriver();
driver.get(env);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}

@Test
public void testLoginScript() throws Exception {
//Maximize window
driver.manage().window().maximize();

//Login
driver.findElement(By.id("TBSiteID")).clear();
driver.findElement(By.id("TBSiteID")).sendKeys(siteid);
driver.findElement(By.id("TBUserName")).clear();
driver.findElement(By.id("TBUserName")).sendKeys(username);
driver.findElement(By.name("TBPassword")).clear();
driver.findElement(By.name("TBPassword")).sendKeys(password);
driver.findElement(By.name("Login")).click();
Thread.sleep(2000);
log.info("Found requested site");

}

 @AfterSuite
 public void tearDown() throws Exception {
//driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
  fail(verificationErrorString);
 }
 }

private boolean isElementPresent(By by) {
try {
  driver.findElement(by);
  return true;
} catch (NoSuchElementException e) {
  return false;
 }
}

private boolean isAlertPresent() {
try {
  driver.switchTo().alert();
  return true;
} catch (NoAlertPresentException e) {
  return false;
  }
 }

 private String closeAlertAndGetItsText() {
  try {
  Alert alert = driver.switchTo().alert();
  String alertText = alert.getText();
  if (acceptNextAlert) {
    alert.accept();
  } else {
    alert.dismiss();
  }
  return alertText;
} finally {
  acceptNextAlert = true;
}
}
}

Next script that I would like to run:

我想运行的下一个脚本:

public class AddNormalEE {
String username, password, siteid;
private WebDriver driver;
private boolean acceptNextAlert = true;
 private StringBuffer verificationErrors = new StringBuffer();
static Logger log = Logger.getLogger(AddNormalEE.class);


@BeforeSuite (alwaysRun=true)
@Parameters({ "url","username","password","site" })

public void setUp(String env, String user, String pwd, String ste) throws Exception {
username=user;
 password=pwd;
siteid=ste;

    //driver = new FirefoxDriver();
  //driver.get(env);
  //driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}


@Test
public void testAddNormalEE() throws Exception {
//Maximize window
//driver.manage().window().maximize();



@AfterSuite
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
  fail(verificationErrorString);
}
}

private boolean isElementPresent(By by) {
try {
  driver.findElement(by);
  return true;
  } catch (NoSuchElementException e) {
    return false;
  }
}

private boolean isAlertPresent() {
try {
  driver.switchTo().alert();
  return true;
} catch (NoAlertPresentException e) {
  return false;
}
}

private String closeAlertAndGetItsText() {
try {
  Alert alert = driver.switchTo().alert();
  String alertText = alert.getText();
  if (acceptNextAlert) {
    alert.accept();
  } else {
    alert.dismiss();
  }
  return alertText;
} finally {
  acceptNextAlert = true;
}
 }
}  

采纳答案by niharika_neo

If your tests are dependent, you can put them in the same class with dependsOnMethod={method1} defined on method2 so that the order is gauranteed. If it is between different classes, you might consider extending your AddNormalEE class from the LoginScript class.

如果您的测试是相关的,您可以将它们放在同一个类中,并在 method2 上定义dependsOnMethod={method1},以便保证顺序。如果它在不同的类之间,您可以考虑从 LoginScript 类扩展您的 AddNormalEE 类。

To run tests in the same browser, your driver instance needs to be shared between your classes or it has to be the same in all your @Tests. Either make it static or consider having a threadlocal webdriver variable in case you plan to run parallely some day. In the above case, you can also have a method getDriver() in your loginScript which returns the driver object to the AddNormalEE class if static needs to be avoided.

要在同一个浏览器中运行测试,您的驱动程序实例需要在您的类之间共享,或者它必须在所有 @Tests 中相同。要么让它是静态的,要么考虑使用一个 threadlocal webdriver 变量,以防你计划在某一天并行运行。在上述情况下,您还可以在 loginScript 中使用 getDriver() 方法,如果需要避免静态,它将驱动程序对象返回给 AddNormalEE 类。

As a general practice, it is good to have independent tests. You can make use of parallel runs to overcome the time issue with independent tests. Making login as a method and not a test since we are not asserting any behavior as per your code above. If I am testing login, I would have separate tests that test login functionality only.

作为一般做法,最好进行独立测试。您可以利用并行运行来克服独立测试的时间问题。将登录作为一种方法而不是测试,因为我们没有根据上面的代码断言任何行为。如果我正在测试登录,我将有单独的测试来测试登录功能。

回答by djangofan

The usual way that Selenium people write tests is to open a separate browser per test class, which is sorta how "Selenium Grid" is designed to operate. I usually put one test method per test class. If you want multiple test methods per class, and the app your testing does not care about the order you run those methods, then in theory you could run those multiple test methods on a single browser. I've done that before but, from my experience, it is not a good idea to design Selenium tests with that pattern, and so you can do it, but I recommend against it.

Selenium 人员编写测试的通常方式是为每个测试类打开一个单独的浏览器,这有点类似于“Selenium Grid”的设计运行方式。我通常为每个测试类放置一个测试方法。如果您希望每个类有多个测试方法,并且您的测试应用程序不关心您运行这些方法的顺序,那么理论上您可以在单个浏览器上运行这些多个测试方法。我以前这样做过,但根据我的经验,用这种模式设计 Selenium 测试并不是一个好主意,所以你可以这样做,但我建议不要这样做。

For example, with one test method per test class, in your @BeforeMethod you can instantiate the WebDriver browser instance and then in the @AfterMethod you can kill it. With multiple tests per class, you'd have to use @BeforeTest and @AfterTest, which can be done but your results may vary depending on how careful you are.

例如,每个测试类使用一个测试方法,在你的 @BeforeMethod 中你可以实例化 WebDriver 浏览器实例,然后在 @AfterMethod 中你可以杀死它。对于每个班级的多个测试,您必须使用@BeforeTest 和@AfterTest,这可以完成,但您的结果可能会因您的谨慎程度而有所不同。

回答by Shamik

I am not really clear on your question. If you want to use the same driver object across tests then create a static driver object and pass it on to the test methods and dont kill it. Or am i missing something .

你的问题我不是很清楚。如果您想在测试中使用相同的驱动程序对象,则创建一个静态驱动程序对象并将其传递给测试方法,不要杀死它。或者我错过了什么。

回答by vini007

Each test in a test class should perform the test using a new browser session, This can be easily done by putting the browser invoke and the kill process in a base Test class and extends this class in each test class.

测试类中的每个测试都应该使用新的浏览器会话执行测试,这可以通过将浏览器调用和终止进程放在基本 Test 类中并在每个测试类中扩展此类来轻松完成。