WebDriver 之测试失败自动截图.docx

上传人:b****7 文档编号:25036777 上传时间:2023-06-04 格式:DOCX 页数:9 大小:17.59KB
下载 相关 举报
WebDriver 之测试失败自动截图.docx_第1页
第1页 / 共9页
WebDriver 之测试失败自动截图.docx_第2页
第2页 / 共9页
WebDriver 之测试失败自动截图.docx_第3页
第3页 / 共9页
WebDriver 之测试失败自动截图.docx_第4页
第4页 / 共9页
WebDriver 之测试失败自动截图.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

WebDriver 之测试失败自动截图.docx

《WebDriver 之测试失败自动截图.docx》由会员分享,可在线阅读,更多相关《WebDriver 之测试失败自动截图.docx(9页珍藏版)》请在冰豆网上搜索。

WebDriver 之测试失败自动截图.docx

WebDriver之测试失败自动截图

WebDriver之测试失败自动截图

 webDriver 测试的时候最头疼的就是调试。

但也远不及运行的时候出错,再回头调试来的痛苦。

总所周知, web 自动化的代码都非常脆弱,一份代码一会运行失败,一会运行成功也是很正常的事情。

总的来说造成案例运行失败的原因大抵有两点:

  环境问题:

比如网络不稳定啊

  代码变动:

比如某个元素不在

  遇到 bug :

这就是真的发现 bug 了

  无论哪一种,遇到了都需要花一番时间去debug。

那如果这个时候有一张运行时候出错的截图,那就一目了然了。

(即便不一目了然,也有很多帮助)

  在运行出错的时候,捕获错误并截图有两种思路:

  自定义一个WeDdriver的监听器,在出异常的时候截图。

  利用Juint的TestRule,自定义一个Rule在运行失败的时候截图。

  自定义监听器

  截图的原理

  截图需要用到RemoteWebDriver。

在 Selenium 官方我们可以找到:

  Onenicefeatureoftheremote

  webdriveristhatexceptionsoften

  haveanattachedscreenshot,encoded

  asaBase64PNG.Inordertogetthis

  screenshot,youneedtowritecode

  similarto:

  publicStringextractScreenShot(WebDriverExceptione){

  Throwablecause=e.getCause();

  if(causeinstanceofScreenshotException){

  return((ScreenshotException)cause).getBase64EncodedScreenshot();

  }

  returnnull;

  }

  意思就是说,每个异常都是ScreenshotException的对象,转码一下就可以用了。

这是截图的本质。

  import java.io.File;

  importjava.io.FileOutputStream;

  importjava.io.IOException;

  importjava.text.SimpleDateFormat;

  importjava.util.Date;

  importorg.openqa.selenium.WebDriver;

  importorg.openqa.selenium.internal.Base64Encoder;

  importorg.openqa.selenium.remote.ScreenshotException;

  importorg.openqa.selenium.support.events.AbstractWebDriverEventListener;

  /**

  *Thisisancustomizedwebdrivereventlistener.

  *NowitimplementsonExceptionmethod:

webdriverwilltakeascreenshot

  *whenitmeetsanexception.It'sgoodbutnotsousable.Andwhenweuse

  *WebDriverWaittowaitforanelementappearing,thewebdriverwillthrow

  *exceptionalwaysandtheonExceptionwillbeexcutedagainandagain,which

  *generatesalotofscreenshots.

  *Puthereforstudy

  *Usage:

  *WebDriverdriver=newFirefoxDriver();

  *WebDriverEventListenerlistener=newCustomWebDriverEventListener();

  *returnnewEventFiringWebDriver(driver).register(listener);

  *

  *@authorqa

  *

  */

  publicclassCustomWebDriverEventListenerextends

  AbstractWebDriverEventListener{

  @Override

  publicvoidonException(Throwablethrowable,WebDriverdriver){

  Throwablecause=throwable.getCause();

  if(causeinstanceofScreenshotException){

  SimpleDateFormatformatter=newSimpleDateFormat(

  "yyyy-MM-dd-hh-mm-ss");

  StringdateString=formatter.format(newDate());

  Fileof=newFile(dateString+"-exception.png");

  FileOutputStreamout=null;

  try{

  out=newFileOutputStream(of);

  out.write(newBase64Encoder()

  .decode(((ScreenshotException)cause)

  .getBase64EncodedScreenshot()));

  }

  catch(Exceptione){

  e.printStackTrace();

  }

  finally{

  try{

  out.close();

  }

  catch(IOExceptione){

  e.printStackTrace();

  }

  }

  }

  }

  }

  主要看onException这个方法的实现,很明显,我们捕获了这个异常,然后通过强制转换将图片提取出来,写入硬盘。

  然后就是使用这个监听器,通常会在setup方法里面将这个监听器注册到WebDriver中去,看代码:

  @Test

  publicvoidsetup(){

  Stringremote_driver_url="http:

//localhost:

4444/wd/hub";

  DesiredCapabilitiescapability=null;

  capability=DesiredCapabilities.firefox();

  WebDriverEventListenereventListener=newCustomWebDriverEventListener();

  WebDriverdriver=newEventFiringWebDriver(newRemoteWebDriver(newURL(

  remote_driver_url),capability)).register(eventListener);

  }

  在这之后,如果运行出错,WebDriver抛出异常就会在相应的classpath下面生成png的截图。

  自定义TestRule

  和自定义WebDriver监听器不同,自定义TestRule只有在这个Rule被执行的时候,才去做一些我们预设的CallBack。

所以这个截图动作,对于WebDriver而言,是主动的。

那么,我们就需要自定义一个RemoteWebDriver来实现截图功能。

WebDriver自身提供了TakesScreenshot这个接口,我们只要实现它就可以了,看代码:

  import.URL;

  importorg.openqa.selenium.OutputType;

  importorg.openqa.selenium.TakesScreenshot;

  importorg.openqa.selenium.WebDriverException;

  importorg.openqa.selenium.remote.CapabilityType;

  importorg.openqa.selenium.remote.DesiredCapabilities;

  importorg.openqa.selenium.remote.DriverCommand;

  importorg.openqa.selenium.remote.RemoteWebDriver;

  publicclassCustomRemoteWebDriverextendsRemoteWebDriverimplements

  TakesScreenshot{

  publicCustomRemoteWebDriver(URLurl,DesiredCapabilitiesdc){

  super(url,dc);

  }

  @Override

  publicXgetScreenshotAs(OutputTypetarget)

  throwsWebDriverException{

  if((Boolean)getCapabilities().getCapability(

  CapabilityType.TAKES_SCREENSHOT)){

  returntarget

  .convertFromBase64Png(execute(DriverCommand.SCREENSHOT)

  .getValue().toString());

  }

  returnnull;

  }

  }

  然后,我们在加一个封装类,将截图方法放进去。

  WebDriverWrapper.screenShot:

  /**

  *Functiontotakethescreenshotandsaveittotheclasspathdir.

  *Usually,youwillfindthepngfileundertheprojectroot.

  *

  *@paramdriver

  *Webdriverinstance

  *@paramdesc

  *Thedescriptionofthepng

  */

  publicstaticvoidscreenShot(WebDriverdriver,Stringdesc){

  DatecurrentTime=newDate();

  SimpleDateFormatformatter=newSimpleDateFormat("yyyy-MM-dd-hh-mm-ss");

  StringdateString=formatter.format(currentTime);

  FilescrFile=((TakesScreenshot)driver)

  .getScreenshotAs(OutputType.FILE);

  try{

  desc=desc.trim().equals("")?

"":

"-"+desc.trim();

  Filescreenshot=newFile("screenshot"+File.separator

  +dateString+desc+".png");

  FileUtils.copyFile(scrFile,screenshot);

  }catch(IOExceptione){

  e.printStackTrace();

  }

  }

  下面,就是添加Junit的TestRule:

  importorg.junit.rules.TestRule;

  importorg.junit.runner.Description;

  importorg.junit.runners.model.Statement;

  importorg.openqa.selenium.WebDriver;

  publicclassTakeScreenshotOnFailureRuleimplementsTestRule{

  privatefinalWebDriverdriver;

  publicTakeScreenshotOnFailureRule(WebDriverdriver){

  this.driver=driver;

  }

  @Override

  publicStatementapply(finalStatementbase,Descriptiondescription){

  returnnewStatement(){

  @Override

  publicvoidevaluate()throwsThrowable{

  try{

  base.evaluate();

  }

  catch(Throwablethrowable){

  WebDriverWrapper.screenShot(driver,"assert-fail");

  throwthrowable;

  }

  }

  };

  }

  }

  代码很简单,在抛出evalate方法的错误之前,截图。

  然后就是使用这个TestRule,很简单,只要在你的 测试用例里面加入:

  publicclassMyTest{

  ...

  @Rule

  publicTestRulemyScreenshot=newTakeScreenshotOnFailureRule(driver);

  ...

  @Test

  publicvoidtest1(){}

  @Test

  publicvoidtest2(){}

  ...

  }

  即可。

关于Junit的Rule请自行google!

  两则的比较

  总得来说,两种方法都很方便,也很有效果,基本都能截图成功。

  不同之处在于,

  RemoteWebDriver监听器是在RemoteWebDriver抛出异常的时候截图。

  TestRule是在assert失败的时候截图。

  我在项目中最早是用第一种方法,后来改用第二种,主要是因为,在自定义的监听器里,它遇到所有的异常都会截图,这个时候,如果你用了conditionwait一个Ajax的元素,那就会很悲剧,你会发现在你的目录下面有无数的截图。

当初我没有找到解决方法,期待有人提出。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1