使用cucumber集成webdriver进行ui测试

未来已来2018-09-10 09:05

作者:卢策


1.业务背景:

页面搭建系统作为运营活动配置后台,需要支持各种商品、优惠券、品牌、专辑、图片、文章、视频、宝贝计划等模块配置,需要快速测试及回归上线。
2.ui框架设计
采用cucumber+testng+webdriver+java方式实现
1)使用testng 支持多浏览器并发
2)使用cucumber按照行为驱动理念,完成测试场景用例及测试数据
3)使用java+webdriver完成测试步骤实现
4)使用jenkins集成,并输入相关测试报告等
3.关键代码细节分析
1).tesng并发配置
2)testng 监听
public class RemoteWebDriverListener implements IInvokedMethodListener {

static Logger log = Logger.getLogger(RemoteWebDriverListener.class.getName());
private String browserName;
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
log.info("【BEGINNING】");
if (method.isTestMethod()) {
browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
URL hubURL = null;
try {
hubURL = new URL(
(method.getTestMethod().getXmlTest().getSuite().getParameter("hubURL") != "")
? method.getTestMethod().getXmlTest().getSuite().getParameter("hubURL")
: "http://localhost:4444/wd/hub");
} catch (MalformedURLException e) {
log.error("ex:\n" + e.getMessage() + "");
log.error(e.getStackTrace());
}
log.info("HUB URL: " + hubURL);
WebDriver driver = RemoteDriverFactory.createInstance(hubURL, browserName);
RemoteDriverManager.setDriver(driver);;
log.info("Done! Created "+ browserName + " driver!" );
} else {
log.warn("Provided method is NOT a TestNG testMethod!!!");
}
log.debug("【END】");
}
}


3)WebDriverEventListener事件监听

package cucumber.examples.java.testNG;

import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.WebDriverEventListener;

public class MyEventListener implements WebDriverEventListener {
private static Logger log = Logger.getLogger(MyEventListener.class.getName());

public void beforeAlertAccept(WebDriver driver) {
log.info("【点击接受警告框前】:警告框文案=" + driver.switchTo().alert().getText());
}

public void afterAlertAccept(WebDriver driver) {
log.info("【点击接受警告框后】成功");

}

public void afterAlertDismiss(WebDriver driver) {
log.info("【点击取消警告框后】成功");

}

public void beforeAlertDismiss(WebDriver driver) {
log.info("【点击取消警告框前】:警告框文案" + driver.switchTo().alert().getText());

}

public void beforeNavigateTo(String url, WebDriver driver) {
log.info("【导航切换前】当前url: " + driver.getCurrentUrl());
log.info("【导航切换前】切换的url: " + url);

}

public void afterNavigateTo(String url, WebDriver driver) {
log.info("【导航切换后】切换的url: " + url);
log.info("【导航切换后】当前url: " + driver.getCurrentUrl());

}

public void beforeNavigateBack(WebDriver driver) {
log.info("【导航后退前】当前url:" + driver.getCurrentUrl());

}

public void afterNavigateBack(WebDriver driver) {
log.info("【导航后退后】当前url:" + driver.getCurrentUrl());

}

public void beforeNavigateForward(WebDriver driver) {
log.info("【导航前进前】当前url:" + driver.getCurrentUrl());

}

public void afterNavigateForward(WebDriver driver) {
log.info("【导航前进后】当前url:" + driver.getCurrentUrl());

}

public void beforeNavigateRefresh(WebDriver driver) {
log.info("【页面刷新前】当前url:" + driver.getCurrentUrl());

}

public void afterNavigateRefresh(WebDriver driver) {
log.info("【页面刷新后】当前url:" + driver.getCurrentUrl());

}

public void beforeFindBy(By by, WebElement element, WebDriver driver) {
log.info("【查找元素前】查找条件: " + by);

}

public void afterFindBy(By by, WebElement element, WebDriver driver) {
log.info("【查找元素后】查找条件: " + by);

}

public void beforeClickOn(WebElement element, WebDriver driver) {
log.info("【点击元素前】文案:" + element.getText());

}

public void afterClickOn(WebElement element, WebDriver driver) {
log.info("【点击元素后】文案:" + element.getText());

}

public void beforeChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {
log.info("【元素变化前】文案:" + element.getText() + ". keysToSend:" + keysToSend.toString());

}

public void afterChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {
log.info("【元素变化后】文案:" + element.getText() + ". keysToSend:" + keysToSend.toString());

}

public void beforeScript(String script, WebDriver driver) {
log.info("【执行脚本前】script:" + script);

}

public void afterScript(String script, WebDriver driver) {
log.info("【执行脚本后】");

}

public void beforeSwitchToWindow(String s, WebDriver webDriver) {
log.info("【切换窗口前】handle" + webDriver.getWindowHandle());
log.info("【切换窗口前】参数s=" + s);
}

public void afterSwitchToWindow(String s, WebDriver webDriver) {
log.info("【切换窗口后】handle" + webDriver.getWindowHandle());
log.info("【切换窗口后】参数s=" + s);
}

public void onException(Throwable throwable, WebDriver driver) {
log.error("【发生异常】onException:" + throwable.getStackTrace());
log.error("【发生异常】原因是: " + throwable.getMessage());
RemoteDriverManager.quitDriver();
}
}


4)webdriver linsten 注册

WebDriverEventListener eventListener = new MyEventListener();
EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(remoteWebDriver).register(eventListener);


5)webdriver启动

static WebDriver createInstance(URL hubUrl, String browserName) {
browserName = (browserName != null) ? browserName : "chrome";
System.setProperty("webdriver.chrome.driver", "src\\test\\resources\\selenium\\chromedriver.exe");
RemoteWebDriver remoteWebDriver = null;

if (browserName.equalsIgnoreCase("firefox")) {
DesiredCapabilities capability = DesiredCapabilities.firefox();
remoteWebDriver = new RemoteWebDriver(hubUrl, capability);
} else if (browserName.equalsIgnoreCase("chrome")) {
DesiredCapabilities capability = DesiredCapabilities.chrome();
remoteWebDriver = new RemoteWebDriver(hubUrl, capability);
}


6)cucumber 测试用例 searchpage.feature
@lego
功能:搜索页面

  场景大纲: 使用页面id搜索已存在的页面
    假设 登录乐高
    当 搜索页面"<pageId>"
    那么 返回列表包含"<pageId2>"
    例子:
      | pageId | pageId2 |
      | 2546   | 2546    |

  场景: 使用页面id精准搜索页面-页面id存在,可以搜索到结果
    假设 登录乐高
    当 页面搜索框输入2768
    那么 返回列表页面名称字段为2768 / QATEST_搜索页面

  场景大纲: 使用页面id精准搜索页面-页面id存在,可以搜索到结果
    假设 登录乐高
    当 页面搜索框输入<pageID>
    那么 返回列表页面名称字段为<pageName>

    例子:

      | pageID | pageName           |
      | 2768   | 2768 / QATEST_搜索页面 |

  场景: 使用页面id精准搜索页面-页面id不存在
    假设 登录乐高
    当 页面搜索框输入<pageID>
    那么 返回空搜索结果<errMsg>
      | pageID | errMsg           |
      | 1      | 搜索结果为空,请重新输入搜索内容 |
      | 2      | 搜索结果为空,请重新输入搜索内容 |
7) 测试步骤tesp实现
// 页面搜索输入框
private By searchInput = By.cssSelector ("input[placeholder='请输入页面名称/页面ID/页面URL']");

// 搜索按钮
private By searchBtn = By.cssSelector ("#box > div.m-list-page.f-pr > div.m-search > div > button");

//搜索列表
private By searchResult = By.cssSelector ("#box > div.m-list-page.f-pr > div.m-tabs-ex > div.tabs-bd > div:nth-child(2) > div > table > tbody > tr > td:nth-child(2)");

@当("^搜索页面\"([^\"]*)\"$")
public void 搜索页面 ( String text ) {
click ( searchInput);
sendKeys ( text , searchInput );
click ( searchBtn );

}

@那么("^返回列表包含\"([^\"]*)\"$")
public void 返回列表包含 ( String pageid ) {
textContainsToBe(searchResult,pageid);
}

@当("^页面搜索框输入(.*?)$")
public void 页面搜索框输入 ( String text ) {
clickElement ( searchInput );
sendKeys ( text , searchInput );
clickElement ( searchBtn );
}


8)测试执行 LegoRunner.java

@CucumberOptions(strict = true, monochrome = true,
features = "target/test-classes/features",
glue = "cucumber.examples.java.testNG.stepDefinitions",
format = {"pretty",
"html:target/lego/cucumber-html-report;",
"json:target/lego/cucumber.json",
"junit:target/cucumber-report/lego/cucumber.xml"},
tags = {"@lego"})
public class LegoRunner extends AbstractTestNGCucumberTests {

}


8.jenkins 配置
使用插件cucumber-report


网易云大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者卢策授权发布