文章部分转自:http://www.cnblogs.com/sdet/p/3648993.html 感谢原作者
监听所有操作有什么用?
1,我可以用log记录我的driver的所有事件。注意,我只要对每种事件写一行代码,一共撑死了10来行代码。以后就可以自动监听,自动执行这些代码,不用再写一大堆log.info,也不用面对一个没log的测试用例。开发人员转的自动化测试人员们请不要再对selenium提供的每个操作做二次封装,仅仅为了往里面塞一段log了。webdriver提供的操作数量远远多余事件数量。等你封装好,你累都累死了,读你程序的人也累死了。
2,我可以对事件截图。不仅能在出错时截图,我还可以回溯到错误前一个步骤时截图。甚至对每个步骤截图。而不必在测试用例里写一大堆screenshot的调用。
3,我可以隐式等待。对五六个主要事件进行隐式等待。五六行的代码量换取你在测试用例里一次一次的调用等待。你也不需要再因为为了加个等待而对selenium提供的每个方法都做二次封装。(开发转的自动化测试人员特别爱干这事。)
4,其他,你可以发挥想象力挖掘更多用法。
最大优点:代码量非常小。
具体实现:
普通我们创建一个WebDriver是:
WebDriver driver = new FirefoxDriver();
现在只需要改成这样创建一个EventFiringWebDriver并注册的方法:
WebDriver driver = new EventFiringWebDriver(new FirefoxDriver()).register(new LogEventListener());
其中LogEventListener()是自定义的监听器,名字可以随意取,监听器需要继承WebEventListener接口,并实现接口中的方法,具体如下:
public class LogEventListener implements WebEventListener{
public void beforeNavigateBack(WebDriver selenium){}
public void beforeNavigateForward(WebDriver selenium){}
public void beforeClickOn(WebElement element, WebDriver selenium){}
public void beforeScript(String script, WebDriver selenium){}
public void afterClickOn(WebElement element, WebDriver selenium){}
public void afterFindBy(By by, WebElement element, WebDriver selenium){}
public void afterNavigateBack(WebDriver selenium){}
public void afterNavigateForward(WebDriver selenium){}
public void afterNavigateTo(String url, WebDriver selenium){}
public void afterScript(String script, WebDriver selenium){}
public void beforeNavigateTo(String url, WebDriver selenium){}
public void beforeChangeValueOf(WebElement element, WebDriver selenium){}
public void afterChangeValueOf(WebElement element, WebDriver selenium){}
public void beforeFindBy(By by, WebElement element, WebDriver selenium){}
public void onException(Throwable error, WebDriver selenium){}
}
例如当我需要在selenium出错的时候进行截屏操作,只需要在onException(Throwable error, WebDriver selenium){}方法体中加入截屏操作,所有遇到Exception的地方自动执行截屏操作,不需要手动添加截屏调用,非常省时省力,维护起来也方便。
关于使用监听器后的Assert使用
通常在测试用例编写的最后阶段都会使用Assert来断言测试结果,我们希望如果Assert断言测试失败就进行截图操作,而前面的监听器之坚挺webdriver的时间,assert抛出的是AssertionError,不是Exception,因此不能被监听器捕获,而无法进行对应操作,如果我们想在assert失败的时候进行截屏操作,就需要重写Assert类并进行,设置成Static类型,可随时调用,具体如下:
package util; import org.testng.Assert; public class AssertRewrite { //重写assertEquals方法,断言失败就截图,然后再抛出error,以便系统能捕获该error public static void assertEquals(Object actual,Object expected ){ try{ Assert.assertEquals(actual, expected); }catch(Error e){ //这里写截图操作 throw e;//这里故意抛出error } } //重写assertNotEquals方法 public static void assertNotEquals(Object actual,Object expected){ } //重写assertNull方法 public static void assertNull(Object object){ } //后续可继续添加assert方法的重写,以实现更多断言功能 }