0

我使用 Selenium IDE 创建了一个包含 2 个测试用例的测试套件。我将该套件导出为 Java/JUnit4/WebDriver。

第一个测试用例允许用户登录网站,找到匹配后进行会员搜索,访问会员的个人资料

第二个测试案例:在会员资料中,点击“捐赠”链接添加一个承诺。

测试套件在 Selenium IDE 中运行良好,但是当我执行该套件时它在 Eclipse 中挂起。在 Eclipse 中的行为,第一个测试用例运行良好,第二个用例打开一个新的浏览器,系统需要登录(输入用户名和密码)。

我想知道我该怎么做,所以测试用例 2 继续进行而不要求用户登录。感谢您的帮助和建议。

这是我的测试套件代码分为 3 个部分(我删除了 uid 和 pd,因为该站点是一个内部站点)

-test suite runner file: searchDonorAddPledge   
-test case1: searchDonorSuzy.class    
-test case2: DonorAddPledge.class

失败跟踪消息:

  1. org.openqa.selenium.StaleElementReferenceException:在缓存中找不到元素 - 页面可能在查找后已更改 命令持续时间或超时:30.12 秒

  2. 原因:org.openqa.selenium.remote.ErrorHandler$UnknownServerException:缓存中未找到元素 - 可能页面在查找后已更改构建信息:版本:'2.31.0',修订:'1bd294d',时间:'2013-02-27 20:53:56'

跑步者档案:

import org.junit.runners.Suite;
import org.junit.runner.RunWith;

      @RunWith(Suite.class)
      @Suite.SuiteClasses
      (
        {
            SearchDonorSuzy.class,
            DonorAddPledge.class      
        }
      )

      public class searchDonorAddPledge { }

测试用例 1 代码:

import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

public class SearchDonorSuzy 
{
    private WebDriver driver;
      private String baseUrl;
      private boolean acceptNextAlert = true;
      private StringBuffer verificationErrors = new StringBuffer();

      @Before
      public void setUp() throws Exception {
        driver = new FirefoxDriver();
        baseUrl = "https://jlaustin.tcheetah.com/";
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
      }

      @Test
      public void testSearchDonorSuzy() throws Exception {
        // set overall speed of the test case
        // ERROR: Caught exception [ERROR: Unsupported command [setSpeed | 4000 | ]]
        driver.get(baseUrl + "/?html=openid");
        driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
        driver.findElement(By.id("edit-name")).clear();
        driver.findElement(By.id("edit-name")).sendKeys("username");
        driver.findElement(By.id("edit-pass")).clear();
        driver.findElement(By.id("edit-pass")).sendKeys("password");
        driver.findElement(By.id("edit-submit")).click();
        driver.findElement(By.id("cmp_admin")).click();
        driver.findElement(By.id("quicksearch_anchor")).click();
        driver.findElement(By.cssSelector("img[alt=\"Member\"]")).click();
        driver.findElement(By.id("search_name")).clear();
        driver.findElement(By.id("search_name")).sendKeys("suzy");
        driver.findElement(By.cssSelector("input[type=\"image\"]")).click();
        driver.findElement(By.linkText("Balagia, Suzy")).click();
      }

      @After
      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 String closeAlertAndGetItsText() 
      {
        try 
        {
          Alert alert = driver.switchTo().alert();
          if (acceptNextAlert) 
          {
            alert.accept();
          } 
          else 
          {
            alert.dismiss();
          }
          return alert.getText();
        } 
        finally 
        {
          acceptNextAlert = true;
        }
      }

}

测试用例2代码:

import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

public class DonorAddPledge 
{
      private WebDriver driver;
      private String baseUrl;
      private boolean acceptNextAlert = true;
      private StringBuffer verificationErrors = new StringBuffer();

      @Before
      public void setUp() throws Exception 
      {
        driver = new FirefoxDriver();
        baseUrl = "https://jlaustin.tcheetah.com/";
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
      }

      @Test
      public void testDonorAddPledge() throws Exception 
      {
        driver.get(baseUrl + "/?nd=db_member&account_id=942&nowwritestate=i1110536420226242");

        driver.findElement(By.xpath("(//a[contains(text(),'Donor')])[2]")).click();
        driver.findElement(By.linkText("Campaign Manager")).click();
        new Select(driver.findElement(By.id("campaign_id"))).selectByVisibleText("A Christmas Affair 2012");
        driver.findElement(By.xpath("//a[contains(text(),'Add\n            pledge')]")).click();
        driver.findElement(By.id("pledge_amount")).clear();
        driver.findElement(By.id("pledge_amount")).sendKeys("100.00");
        driver.findElement(By.id("pledge_notes")).clear();
        driver.findElement(By.id("pledge_notes")).sendKeys("test pledge");
        driver.findElement(By.cssSelector("input[type=\"image\"]")).click();
      }

      @After
      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 String closeAlertAndGetItsText() 
      {
        try 
        {
          Alert alert = driver.switchTo().alert();
          if (acceptNextAlert) 
          {
            alert.accept();
          } 
          else 
          {
            alert.dismiss();
          }
          return alert.getText();
        }

        finally 
        {
          acceptNextAlert = true;
        }
      }

}
4

1 回答 1

1

两个测试用例都在它们的 @Before 方法中实例化了一个新的驱动程序;这将使用新会话启动一个新的浏览器实例,因此它会丢失任何先前测试用例的登录会话详细信息:

driver = new FirefoxDriver();

我建议研究两种替代策略:

  1. 每个类实例化一次驱动程序,并将测试用例放入依赖于使用同一会话的同一类中。
  2. 重组您的测试用例,使它们彼此独立。

1. 在多个测试用例中保持相同的会话

您可以通过每个类只实例化一次驱动程序来提高代码执行效率,而不是为每个测试用例单独实例化驱动程序。但是,您应该认为这主要是一种效率节省;例如,我不建议将其用作将测试用例链接在一起的一种方式,以便测试用例 2 依赖于测试用例 1 已成功运行。

2. 让你的测试用例独立

按顺序构建测试用例总是很诱人,这样您就可以执行测试用例 1(例如,包括登录),然后自然而然地引向测试用例 2(执行一些进一步的操作)。但是我警告说这会导致问题。它使你的整个测试套件更加脆弱——如果测试用例 1 中存在问题,那么之后所有的测试用例都会失败。它使您的测试不太灵活——您不能只运行测试用例 3 来单独重新测试,也不能从套件中挑选单个测试用例。

我强烈建议您研究第二种策略;例如,如果测试用例 1 只是测试登录例程,则让它测试登录例程,然后再次注销。如果测试用例 2 只是测试一些只能在登录后才能访问的功能 - 好吧,让它登录以便它可以访问它感兴趣的功能。测试用例 1 也确实登录的事实与测试用例 2 并不真正相关,这也不是问题 - 事实上,您可以将其视为开始重构测试用例以将重复代码提取到单独的方法调用中的机会。

于 2013-05-09T14:02:01.093 回答