相信用過Selenium WebDriver 的朋友都應該知道如何使用WebDriver API實現Take Screenshot的功能。html
在這篇文章裏,我主要來介紹對failed tests實現 take screenshot的功能, 而且咱們也高大上一回,作成註解的形式。java
效果以下:web
目錄 前提 Maven 配置 Example
簡單類圖
TakeScreenshotOnFailure
CustomTestListener
WebDriverHost
TestBase
DemoListenerTest
TestNG.xml
Run as TestNG
<dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.9.5</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.46.0</version> </dependency>
簡單類圖apache
首先建立一個類 以下 TakeScreenshotOnFailure.javaide
package test.demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Annotation informs CustomTestListener to take screenshot if test method fails. File name is method name + png suffix. * Test class must implement WebDriverHost in order for the screenshot to work. * * @author wadexu */ @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD}) public @interface TakeScreenshotOnFailure { }
##轉載註明出處: http://www.cnblogs.com/wade-xu/p/4861024.html 單元測試
而後建立一個本身的CustomTestListener 繼承TestNG 的 TestListenerAdapter 重寫onTestFailure()方法, 加入take screenshot的功能學習
代碼以下測試
package test.demo; import java.io.File; import java.lang.reflect.Method; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.testng.ITestResult; import org.testng.TestListenerAdapter; /** * * @Description: A custom test listener extends TestListenerAdapter for take screen shot on failed test case. * @author wadexu * * @updateUser * @updateDate */ public class CustomTestListener extends TestListenerAdapter { private static String fileSeperator = System.getProperty("file.separator"); protected static final Logger logger = Logger.getLogger(CustomTestListener.class); @Override public void onTestFailure(ITestResult result) { super.onTestFailure(result); Object o = result.getInstance(); WebDriver driver = ((WebDriverHost) o).getWebDriver(); Method method = result.getMethod().getConstructorOrMethod().getMethod(); TakeScreenshotOnFailure tsc = method.getAnnotation(TakeScreenshotOnFailure.class); if (tsc != null) { String testClassName = getTestClassName(result.getInstance().toString()).trim(); String testMethodName = result.getName().toString().trim(); String screenShotName = testMethodName + ".png"; if (driver != null) { String imagePath = ".." + fileSeperator + "Screenshots" + fileSeperator + "Results" + fileSeperator + testClassName + fileSeperator + takeScreenShot(driver, screenShotName, testClassName); logger.info("Screenshot can be found : " + imagePath); } } } /** * Get screen shot as a file and copy to a new target file * * @Title: takeScreenShot * @param driver * @param screenShotName * @param testClassName * @return screenShotName */ public static String takeScreenShot(WebDriver driver, String screenShotName, String testClassName) { try { File file = new File("Screenshots" + fileSeperator + "Results"); if (!file.exists()) { logger.info("File created " + file); file.mkdir(); } File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); File targetFile = new File("Screenshots" + fileSeperator + "Results" + fileSeperator + testClassName, screenShotName); FileUtils.copyFile(screenshotFile, targetFile); return screenShotName; } catch (Exception e) { logger.error("An exception occured while taking screenshot " + e.getCause()); return null; } } /** * Get a test class name * * @Title: getTestClassName * @param testName * @return testClassName */ public String getTestClassName(String testName) { String[] reqTestClassname = testName.split("\\."); int i = reqTestClassname.length - 1; String testClassName = reqTestClassname[i].substring(0, reqTestClassname[i].indexOf("@")); logger.info("Required Test Name : " + testClassName); return testClassName; } }
接口類 WebDriverHost ui
package test.demo; import org.openqa.selenium.WebDriver; /** * Class implementing that interface is expected to return instance of web driver used in last test method. * * @author wadexu */ public interface WebDriverHost { /** * Returns instance of web driver used in last test method. * * @return WebDriver */ public WebDriver getWebDriver(); }
##轉載註明出處: http://www.cnblogs.com/wade-xu/p/4861024.html this
測試基類TestBase
package test.demo; import java.io.File; import java.io.IOException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxProfile; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; /** * @Description: Abstract test base class, Test class must extends this class. * Initialize a firefox webDriver for tutorial purpose only. * @author wadexu * * @updateUser * @updateDate */ public abstract class TestBase implements WebDriverHost{ protected WebDriver webDriver = null; @Override public WebDriver getWebDriver() { return webDriver; } @BeforeClass public void setUp() throws IOException { FirefoxProfile firefoxProfile = new FirefoxProfile(); // use proxy firefoxProfile.setPreference("network.proxy.type", 1); firefoxProfile.setPreference("network.proxy.http", "10.51.1.000"); firefoxProfile.setPreference("network.proxy.http_port", "8080"); //get rid of google analytics, otherwise it's too slow to access to cnblogs website firefoxProfile.addExtension(new File(getClass().getClassLoader().getResource("no_google_analytics-0.6-an+fx.xpi").getFile())); webDriver = new FirefoxDriver(firefoxProfile); } @AfterClass public void tearDown() { webDriver.close(); } }
DemoListenerTest 測試類
package test.demo; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; /** * @Description: Demo a Test using custom Test Listener with an annotation TakeScreenshotOnFailure * @author wadexu * * @updateUser * @updateDate */ public class DemoListenerTest extends TestBase{ @Test @TakeScreenshotOnFailure public void testFail() { webDriver.get("http://www.cnblogs.com/"); //Fail this test method for tutorial purpose only assertTrue(false); } }
TestNG 的 xml 文件 配置以下,加入listener監聽
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <!--<suite name="DMP_Test_Suite" --> <suite name="Demo_Test_Suite" parallel="false"> <listeners> <listener class-name="test.demo.CustomTestListener" /> </listeners> <test name="Demo_Test"> <classes> <class name="test.demo.DemoListenerTest" /> </classes> </test> </suite>
##轉載註明出處: http://www.cnblogs.com/wade-xu/p/4861024.html
Run as TestNG
斷言故意錯誤 讓test fail
控制檯輸出
2015-10-08 15:04:29,896 INFO [test.demo.CustomTestListener] - Required Test Name : DemoListenerTest
2015-10-08 15:04:31,985 INFO [test.demo.CustomTestListener] - Screenshot can be found : ..\Screenshots\Results\DemoListenerTest\testFail.png
圖片以測試方法命名, 存在含類名的路徑下
測試方法Pass 或者 fail但沒加Annotation 都不會截屏。
感謝閱讀,若是您以爲本文的內容對您的學習有所幫助,您能夠點擊右下方的推薦按鈕,您的鼓勵是我創做的動力。