selenium测试框架(java) 版本演化一

selenium的自动化测试代码应该如何组织?  如链接:https://code.google.com/p/selenium/wiki/PageObjects  这里提供了一种PageObject的设计思想,并且在百度内部给出了一个感觉比较实用的实现。其组织结构思想如下:

Page    封装页面元素,以及页面应提供的服务。
        尽量隐藏页面的细节,不要暴露出来。

widget  封装Page中的通用的组件。
        这里的理念是所有的WebElement都是控件。
        通用的页面样式,如导航栏,列表,组合查询框,可以封装成一个大控件。

Data    封装测试数据。

Test    封装测试驱动代码。推荐使用testng。

本文意图重新搭建一个简化的测试框架。

第一个版本,建立起可测的Selenium项目。  包含一个page基类,一个继承的实际待测页面BaiduMainPage,一个驱动的测试用例BaiduMainPageTest。

下面的需要改进点:  1,BaiduMainPageTest中使用的driver是在test中明确的声明为FireFox。应该用配置的方式来实现选用任意一个Driver。并且这里需要实现一个基类来完成这些事情。

2,可以将初始化元素,并将打开页面的过程封装成一个导航类。另外,经常会发生NoSuchElementException。添加等待后,基本解决。但是需要排查出现的原因,怀疑是没有及时加载。

框架代码

项目使用maven管理:

<dependencies>
    <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>2.41.0</version>
    </dependency>
    <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.5</version>
    </dependency>
    <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-simple</artifactId>
          <version>1.7.5</version>
    </dependency>
    <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8.8</version>
    </dependency>

BasePage

/**
 * <p>The <b>Page Object</b> pattern represents the screens of your web app as a series of
 * objects.</p>
 * 
 * <p>PageObjects can be thought of as facing in two directions simultaneously.
 * Facing towards the developer of a test, they represent the services offered
 * by a particular page. Facing away from the developer, they should be the only
 * thing that has a deep knowledge of the structure of the HTML of a page (or
 * part of a page) It‘s simplest to think of the methods on a Page Object as
 * offering the "services" that a page offers rather than exposing the details
 * and mechanics of the page.</p>
 * 
 * @see <a href="http://code.google.com/p/webdriver/wiki/PageObjects">Page Objects Wiki</a>
 * 
 * @author lizejun
 */
public abstract class Page implements SearchContext{

    protected Logger logger = LoggerFactory.getLogger(getClass());

    protected WebDriver driver = null;

    public Page(WebDriver driver) {
        if (null == driver) {
            throw new IllegalArgumentException("WebDriver cannot be null.");
        }
        this.driver = driver;
    }

    public WebDriver getWebDriver() {
        return driver;
    }

    /**
     * 获得当前的地址
     * @return
     */
    public String getCurrentUrl() {
        return driver.getCurrentUrl();
    }

    /**
     *  获取某个元素
     */
    public WebElement findElement(By by) {
        return driver.findElement(by);
    }

    /**
     * 获取符合
     */
    public List<WebElement> findElements(By by) {
        return driver.findElements(by);
    }

    /**
     * 用于硬性的等待
     * @param seconds
     */
    public void sleep(int seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 用于等待某个元素出现,软等待
     * @param by
     */
    public boolean wait(final By by){
        new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver arg0) {
                return arg0.findElement(by).isDisplayed();
            }
        });
        return true;
    }

    /**
     * 处理页面上弹出的Alert()
     * @param option
     */
    public Alert getAlert(){
        sleep(2);
        Alert alert = driver.switchTo().alert();
        return alert;
    }

    /**
     * 模拟键盘箭头向下,然后回车。即,模拟下拉选中
     */
    public void KeyDownAndEnter(){
        sleep(1);
        Actions actions = new Actions(driver);
        actions.sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ENTER).build().perform();
    }

    /**
     * 模拟键盘回车
     */
    public void KeyEnter(){
        sleep(1);
        Actions actions = new Actions(driver);
        actions.sendKeys(Keys.ENTER).build().perform();
    }

    /**
     * 关闭当前页面,并将焦点放到打开的新页面
     */
    public void switchToNewPage(){
        sleep(1);
        String handleNew="";
        for (String handle : driver.getWindowHandles()) {
            handleNew=handle;
        }
        driver.close();
        sleep(1);
        driver.switchTo().window(handleNew);
    }

}

DemoPage

public class BaiduMainPage extends Page{

    public BaiduMainPage(WebDriver driver) {
        super(driver);
    }

    /**
     * 输入文本input
     */
    @FindBy(how=How.ID,using="kw1")
    WebElement inputbox;

    /**
     * 查询按钮
     */
    @FindBy(how=How.ID, using="su1")
    WebElement submitbox;

    /**
     * 新闻链接
     */
    @FindBy(name="tj_news")
    WebElement newsIndex;

    /**
     * 输入待搜素文本
     * @param text
     */
    public void SearchText(String text) {
        inputbox.sendKeys(text);
        submitbox.click();
    }

    public void clickNewsIndex() {
        newsIndex.click();
    }
}

TestCase with testng

public class BaiduMainPageTest{

    protected WebDriver driver = null;

    protected BaiduMainPage page = null;

    @BeforeClass
    public void init() {
        driver = new FirefoxDriver();
    }

    @BeforeMethod
    public void initPage() {
        String path = "http://www.baidu.com/";
        driver.get(path);
        page = new BaiduMainPage(driver);
        PageFactory.initElements(driver, page);
    }

    @Test
    public void testSearch(){
        String text="apple";
        page.SearchText(text);
        Assert.assertTrue(driver.getTitle().contains(text));
        System.out.println(page.getCurrentUrl());
    }

    @Test
    public void testnews(){
        page.clickNewsIndex();
        page.sleep(2);
        System.out.println(page.getCurrentUrl());
        Assert.assertTrue(page.getCurrentUrl().contains("news.baidu.com"));
    }

    @AfterClass
    public void quit() {
        driver.quit();
    }
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。