最近要在框架中添加case失败时,要自动截图,主要又两种方式,思想都是在抛异常的时候,捕获到异常,并作页面截图处理。今天坐下总结。
一、第一种方式,重写onException方法
只针对webdriver的异常截图,该方法由于只针对webdriver抛的异常时才能截图,有一定的限制
a.继承AbstractWebDriverEventListener类,重写onException方法,
public void onException(java.lang.Throwable throwable, WebDriver driver){ Throwable cause = throwable.getCause();
/*
String cause = throwable.getClass().getName();
ScreenshotException ec = new ScreenshotException(cause);
*/ System.out.println(throwable.getClass().getName()); System.out.println("onException=" + cause); Date currentTime = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss"); String dateString = formatter.format(currentTime); File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); try { File screenshot = new File("D:/ddd/" + dateString + ".png"); FileUtils.copyFile(scrFile,screenshot); } catch (IOException e) { e.printStackTrace(); } }
b.测试类,要用EventFiringWebDriver ,并注册MyListen
public static void main(String args[]) { String key = "webdriver.chrome.driver"; String value = "D:/BaiduYunDownload/selenium/chromedriver.exe"; System.setProperty(key, value); WebDriver dr = new ChromeDriver(); EventFiringWebDriver event = new EventFiringWebDriver(dr); MyListen ml = new MyListen(); event.register(ml); dr = event; dr.get("http://www.baidu.com"); dr.findElement(By.id("kw1")).sendKeys("test"); //System.out.println(5/0); Assert.assertEquals("haha", event.findElement(By.id("su")).getAttribute("value")); event.quit(); }
二、第二种方式:使用testNG的TestListenerAdapter
a.先建一个类继承TestListenerAdapter,并重写onTestFailure方法
package com.screenshot.exception; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.io.FileUtils; import org.apache.velocity.runtime.log.LogManager; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.testng.ITestResult; import org.testng.TestListenerAdapter; import com.screenshot.singleton.TestBase; /** * @author QiaoJiaofei * @version 创建时间:2015年8月24日 下午6:33:44 * 类说明 */ public class UseTestNg extends TestListenerAdapter{ @Override public synchronized void onTestFailure(ITestResult result) { Object currentClass = result.getInstance(); WebDriver webDriver = ((TestUsNg) currentClass).getDriver(); if (webDriver != null) { Date currentTime = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss"); String dateString = formatter.format(currentTime); File scrFile = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE); try { File screenshot = new File("D:/ddd/" + dateString + ".png"); FileUtils.copyFile(scrFile,screenshot); } catch (IOException e) { e.printStackTrace(); } } } }
b.创建测试类,注意需要在测试类中写getDriver()方法
package com.screenshot.exception; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; /** * @author QiaoJiaofei * @version 创建时间:2015年8月24日 下午6:43:44 * 类说明 */ public class TestUsNg { private WebDriver dr; public WebDriver getDriver() { return dr; } @Test public void f() { String key = "webdriver.chrome.driver"; String value = "D:/BaiduYunDownload/selenium/chromedriver.exe"; System.setProperty(key, value); dr = new ChromeDriver(); System.out.println(5/0); } }
C.在testng的xml文件中添加监听
<listeners>
<listener class-name="com.screenshot.exception.UseTestNg" />
</listeners>
D.测试类继承该类,每个子类前面要加:@Listeners({com.gm.base.MyListener.class})
三、如何将生成的图片连接到reportNG中,将下面的代码放入上面相应重写的方法中,图片路径与上述代码中生成的图片结合一起。
String imgName = "";//图片路径 Reporter.log("<a href=./img/" + imgName + " target=_blank>Failed Screen Shot</a>", true);
题外:使用Robot主动截图,这种可以在自己想截图的时候调用该方法即可截当前界面
package com.screenshot.book; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import org.testng.annotations.Test; /** * @author QiaoJiaofei * @version 创建时间:2015年8月26日 下午7:40:34 * 类说明 */ public class TestRobot { @Test public void takeScreenShotMethod(){ try{ Thread.sleep(3000); BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); ImageIO.write(image, "jpg", new File("D:/ddd/screenshot.jpg")); } catch(Exception e){ e.printStackTrace(); } } }
备注:
使用junit自动截图,可以使用Rule,由于我用的是testNG,所以没有调试junit的方法。详细参考:http://stackoverflow.com/questions/20995722/when-does-onexception-get-triggered-in-webdrivereventlistener
@Rule public TestRule testWatcher = new TestWatcher() { @Override public void succeeded(Description test){ for (LogEntry log : driver.manage().logs().get(LogType.DRIVER).getAll()) { System.out.println("Level:" + log.getLevel().getName()); System.out.println("Message:" + log.getMessage()); System.out.println("Time:" + log.getTimestamp()); System.out.println("-----------------------------------------------"); } System.out.println(); @Override public void failed(Throwable t, Description test) { String testName = test.getClassName(); String subTestName = test.getMethodName(); String screenShotName = String.format("%s\%s", testName, screenShotName); if (driver instanceof TakesScreenshot) { File tempFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); try { System.out.println(">>>>>>>>>>LOGS: " + yourDirForImages + "\" + screenShotName + ".png"); FileUtils.copyFile(tempFile, new File(String.format("%s.png", screenShotName))); } catch (IOException e) { e.printStackTrace(); } }