参考了: http://blog.youkuaiyun.com/sunnyyou2011/article/details/45894089
http://www.seleniumeasy.com/testng-tutorials/how-to-take-screenshot-for-only-failed-tests-using-webdriver
大致分三步走: 一、先写个java类继承TestListenerAdapter。二、重写onTestFailure, onTestSkipped等方法,在这些方法中加入截图操作。三、把这个listener添加到testng.xml文件上。
一二、写个java类继承TestListenerAdapter & 重写onTestFailure, onTestSkipped等方法,在这些方法中加入截图操作。
public class ScreenshotListener extends TestListenerAdapter {
private static Logger logger = Logger.getLogger(TestngListener.class);
public static final String CONFIG = "config.properties";
@Override
public void onTestFailure(ITestResult tr) {
super.onTestFailure(tr);
logger.info(tr.getName() + " Failure");
takeScreenShot(tr);
}
@Override
public void onTestSkipped(ITestResult tr) {
super.onTestSkipped(tr);
logger.info(tr.getName() + " Skipped");
takeScreenShot(tr);
}
@Override
public void onTestSuccess(ITestResult tr) {
super.onTestSuccess(tr);
logger.info(tr.getName() + " Success");
}
@Override
public void onTestStart(ITestResult tr) {
super.onTestStart(tr);
logger.info(tr.getName() + " Start");
}
@Override
public void onFinish(ITestContext testContext) {
super.onFinish(testContext);
}
/**
* 自动截图,保存图片到本地以及html结果文件中
*
* @param tr
*/
private void takeScreenShot(ITestResult tr) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
String mDateTime = formatter.format(new Date());
String fileName = mDateTime + "_" + tr.getName();
String filePath = OrangeiOS.driver.getScreenshotAs(fileName);
Reporter.setCurrentTestResult(tr);
Reporter.log(filePath);
//这里实现把图片链接直接输出到结果文件中,通过邮件发送结果则可以直接显示图片
Reporter.log("<img src=\"../" + filePath + "\"/>");
}
另外一个例子,当要截图的网页很长的时候:
public class ScreenshotListener2 extends TestListenerAdapter {
private Log log = LogFactory.getLog(this.getClass());
@Override
public void onTestFailure(ITestResult tr) {
try {
log.info("The scripts is failed, about to take the screenshot. The method name of this scripts is " + tr.getName());
// New File with desired Name
String fileFolderName = "Screenshots";
// Get current time mills and convert to desired Format
SimpleDateFormat dateFormatType = new SimpleDateFormat("MM-dd-yyyy");
Date resultdate = new Date(System.currentTimeMillis());
// Verify the isre scroll bar exist or not by height of scroll.
String execScript2 = "return document.documentElement.scrollHeight";
JavascriptExecutor scrollBarPresent = (TestCaseBase.driver);//driver is instance of EventFiringWebDriver class
Long heightOfScrollBar = (Long) (scrollBarPresent.executeScript(execScript2));
// Decide how many screenshots need to captured depends on height of the scroll bar
double ScrollCountBefore = Math.round(heightOfScrollBar.doubleValue() / 450);
int ScrollCount = (int) ScrollCountBefore;
// At least capture one screenshot
File[] screenshotArray = new File[ScrollCount + 1];
screenshotArray[0] = new File(fileFolderName + File.separator + dateFormatType.format(resultdate) + "_" + tr.getName() + "Pic" + 0 + ".png");
// Put other screenshots in the array if need
for (int i = 1; i < (screenshotArray.length) - 1; i++) {
screenshotArray[i] = new File(fileFolderName + File.separator + dateFormatType.format(resultdate) + "_" + tr.getName() + "Pic" + i + ".png");
}
// Delete captured screenshots before on current script
if (screenshotArray[0].getParentFile().isDirectory()) {
for (File subFile : screenshotArray[0].getParentFile().listFiles()) {
Path pathForSubFile = Paths.get(subFile.getAbsolutePath().toString());
String subFileName = pathForSubFile.getFileName().toString();
if (subFileName.contains(tr.getName())) {
subFile.delete();
}
}
}
// New folder for certain environment if it doesn't exist
if (!screenshotArray[0].exists()) {
new File(screenshotArray[0].getParent()).mkdirs();
}
// Create other screenshots except the first one
for (int j = 0; j < (screenshotArray.length) - 1; j++) {
try {
screenshotArray[j].createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
// Capture the screenshot and scroll down before if need
for (int i = 0; i < (screenshotArray.length) - 1; i++) {
try {
if (i > 0) {
JavascriptExecutor jsx = (TestCaseBase.driver);
jsx.executeScript("window.scrollBy(0,400)", "");
}
new FileOutputStream(screenshotArray[i]).write(((TakesScreenshot) TestCaseBase.driver).getScreenshotAs(OutputType.BYTES));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (UnreachableBrowserException e) {
log.info("No screenshot be taken for browser was closed.");
}
}
}
三、把上面的ScreenshotListener加到testng.xml文件中。
<listeners>
<listener class-name="***.ScreenshotListener" />
</listeners>