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>
/**
* <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);
}
}
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();
}
}
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();
}
}