最近要在框架中添加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(); } }