如何在 TestNG Index.html 报告中使用 reporter.log() 附加失败的测试用例屏幕截图
How to attach Failed Test Case screen shot using reporter.log() in the TestNG Index.html report
我正在使用静态方法拍摄屏幕截图并使用 reporter.log 函数将屏幕截图附加到 testNg 的 index.html 报告中。这是截屏的代码。
public class GenericHelper extends CNLogin {
public static String takeScreenShot(String methodName){
try {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// C:\Users9290\AppData\Local\Temp\screenshot7520341205731631960.png
String FilePath = "C:\Users\499290\Downloads\CNProject1\CNProject\test-output\";
new File(FilePath);
FileUtils.copyFile(scrFile, new File( FilePath +methodName +".jpg") );
System.out.println("***Placed screen shot in "+scrFile+" ***");
}
catch(IOException e) {
e.printStackTrace();
}
return methodName+".jpg";
}
}
我正在使用 index.html 报告中的以下代码附上屏幕截图
String TakescreenShot = GenericHelper.takeScreenShot("AddNewPr");
Reporter.log("<a href=\"" + TakescreenShot + "\"><p align=\"left\">Add New PR screenshot at " + new Date()+ "</p>");
我无法在测试用例失败时拍摄屏幕截图,屏幕截图也没有附加到报告中。
这是我的测试用例,如果它通过了,我的屏幕截图方法将拍摄屏幕截图并将屏幕截图附在报告中,但是当它失败时不确定如何拍摄屏幕截图。
public void MultipleServiceDelete() throws InterruptedException {
driver.findElement(By.id("page:frm:pageB:repeatUpper:0:repeat:0:chkIsDelete")).click();
Thread.sleep(5000);
driver.findElement(By.id("page:frm:pageB:btnDeleteMultipleServices")).click();
String DeleteService = ScreenShot.takeScreenShot("MultipleServiceDelete");
Reporter.log("<a href=\"" + DeleteService + "\"><p align=\"left\"> Delete Service screenshot at " + new Date()+ "</p>");
}
您需要添加一个 TestNG 侦听器,在测试失败时截取屏幕截图。这是从我的 Selenium Maven Template:
中获取的一些侦听器代码
package com.lazerycode.selenium.listeners;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.Augmenter;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import static com.lazerycode.selenium.DriverFactory.getDriver;
public class ScreenshotListener extends TestListenerAdapter {
private boolean createFile(File screenshot) {
boolean fileCreated = false;
if (screenshot.exists()) {
fileCreated = true;
} else {
File parentDirectory = new File(screenshot.getParent());
if (parentDirectory.exists() || parentDirectory.mkdirs()) {
try {
fileCreated = screenshot.createNewFile();
} catch (IOException errorCreatingScreenshot) {
errorCreatingScreenshot.printStackTrace();
}
}
}
return fileCreated;
}
private void writeScreenshotToFile(WebDriver driver, File screenshot) {
try {
FileOutputStream screenshotStream = new FileOutputStream(screenshot);
screenshotStream.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
screenshotStream.close();
} catch (IOException unableToWriteScreenshot) {
System.err.println("Unable to write " + screenshot.getAbsolutePath());
unableToWriteScreenshot.printStackTrace();
}
}
@Override
public void onTestFailure(ITestResult failingTest) {
try {
WebDriver driver = getDriver();
String screenshotDirectory = System.getProperty("screenshotDirectory");
String screenshotAbsolutePath = screenshotDirectory + File.separator + System.currentTimeMillis() + "_" + failingTest.getName() + ".png";
File screenshot = new File(screenshotAbsolutePath);
if (createFile(screenshot)) {
try {
writeScreenshotToFile(driver, screenshot);
} catch (ClassCastException weNeedToAugmentOurDriverObject) {
writeScreenshotToFile(new Augmenter().augment(driver), screenshot);
}
System.out.println("Written screenshot to " + screenshotAbsolutePath);
} else {
System.err.println("Unable to create " + screenshotAbsolutePath);
}
} catch (Exception ex) {
System.err.println("Unable to capture screenshot...");
ex.printStackTrace();
}
}
}
您可能最感兴趣的一点是名为 onTestFailure 的方法。这是当测试失败时将被触发的部分。我有一个驱动程序工厂,可以让我访问我的驱动程序对象,对 getDriver 的调用是从工厂获取我的驱动程序对象。如果您刚刚获得一个静态定义的驱动程序对象,您可以忽略该行:
WebDriver driver = getDriver();
其他方法只是创建文件并将屏幕截图写入其中的便捷方法。您显然需要稍微调整一下,以允许它获取屏幕截图已写入的位置并将其传递到您报告的日志中。
我建议让侦听器访问您的 Reporter 对象并更改:
System.out.println("Written screenshot to " + screenshotAbsolutePath);
至:
Reporter.log("<a href=\"" + screenshotAbsolutePath + "\"><p align=\"left\">Add New PR screenshot at " + new Date()+ "</p>");
在上面的代码中,屏幕截图保存到的目录是使用名为 "screenshotDirectory" 的系统 属性 设置的。您需要设置他的系统 属性,或者将以下行更改为您要保存屏幕截图的硬编码位置。为此,这一行:
String screenshotDirectory = System.getProperty("screenshotDirectory");
需要更改为:
String screenshotDirectory = "/tmp/screenshots";
或者,如果您使用 windows,类似于:
String screenshotDirectory = "C:\tmp\screenshots";
我正在使用静态方法拍摄屏幕截图并使用 reporter.log 函数将屏幕截图附加到 testNg 的 index.html 报告中。这是截屏的代码。
public class GenericHelper extends CNLogin {
public static String takeScreenShot(String methodName){
try {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// C:\Users9290\AppData\Local\Temp\screenshot7520341205731631960.png
String FilePath = "C:\Users\499290\Downloads\CNProject1\CNProject\test-output\";
new File(FilePath);
FileUtils.copyFile(scrFile, new File( FilePath +methodName +".jpg") );
System.out.println("***Placed screen shot in "+scrFile+" ***");
}
catch(IOException e) {
e.printStackTrace();
}
return methodName+".jpg";
}
}
我正在使用 index.html 报告中的以下代码附上屏幕截图
String TakescreenShot = GenericHelper.takeScreenShot("AddNewPr");
Reporter.log("<a href=\"" + TakescreenShot + "\"><p align=\"left\">Add New PR screenshot at " + new Date()+ "</p>");
我无法在测试用例失败时拍摄屏幕截图,屏幕截图也没有附加到报告中。
这是我的测试用例,如果它通过了,我的屏幕截图方法将拍摄屏幕截图并将屏幕截图附在报告中,但是当它失败时不确定如何拍摄屏幕截图。
public void MultipleServiceDelete() throws InterruptedException {
driver.findElement(By.id("page:frm:pageB:repeatUpper:0:repeat:0:chkIsDelete")).click();
Thread.sleep(5000);
driver.findElement(By.id("page:frm:pageB:btnDeleteMultipleServices")).click();
String DeleteService = ScreenShot.takeScreenShot("MultipleServiceDelete");
Reporter.log("<a href=\"" + DeleteService + "\"><p align=\"left\"> Delete Service screenshot at " + new Date()+ "</p>");
}
您需要添加一个 TestNG 侦听器,在测试失败时截取屏幕截图。这是从我的 Selenium Maven Template:
中获取的一些侦听器代码package com.lazerycode.selenium.listeners;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.Augmenter;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import static com.lazerycode.selenium.DriverFactory.getDriver;
public class ScreenshotListener extends TestListenerAdapter {
private boolean createFile(File screenshot) {
boolean fileCreated = false;
if (screenshot.exists()) {
fileCreated = true;
} else {
File parentDirectory = new File(screenshot.getParent());
if (parentDirectory.exists() || parentDirectory.mkdirs()) {
try {
fileCreated = screenshot.createNewFile();
} catch (IOException errorCreatingScreenshot) {
errorCreatingScreenshot.printStackTrace();
}
}
}
return fileCreated;
}
private void writeScreenshotToFile(WebDriver driver, File screenshot) {
try {
FileOutputStream screenshotStream = new FileOutputStream(screenshot);
screenshotStream.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
screenshotStream.close();
} catch (IOException unableToWriteScreenshot) {
System.err.println("Unable to write " + screenshot.getAbsolutePath());
unableToWriteScreenshot.printStackTrace();
}
}
@Override
public void onTestFailure(ITestResult failingTest) {
try {
WebDriver driver = getDriver();
String screenshotDirectory = System.getProperty("screenshotDirectory");
String screenshotAbsolutePath = screenshotDirectory + File.separator + System.currentTimeMillis() + "_" + failingTest.getName() + ".png";
File screenshot = new File(screenshotAbsolutePath);
if (createFile(screenshot)) {
try {
writeScreenshotToFile(driver, screenshot);
} catch (ClassCastException weNeedToAugmentOurDriverObject) {
writeScreenshotToFile(new Augmenter().augment(driver), screenshot);
}
System.out.println("Written screenshot to " + screenshotAbsolutePath);
} else {
System.err.println("Unable to create " + screenshotAbsolutePath);
}
} catch (Exception ex) {
System.err.println("Unable to capture screenshot...");
ex.printStackTrace();
}
}
}
您可能最感兴趣的一点是名为 onTestFailure 的方法。这是当测试失败时将被触发的部分。我有一个驱动程序工厂,可以让我访问我的驱动程序对象,对 getDriver 的调用是从工厂获取我的驱动程序对象。如果您刚刚获得一个静态定义的驱动程序对象,您可以忽略该行:
WebDriver driver = getDriver();
其他方法只是创建文件并将屏幕截图写入其中的便捷方法。您显然需要稍微调整一下,以允许它获取屏幕截图已写入的位置并将其传递到您报告的日志中。
我建议让侦听器访问您的 Reporter 对象并更改:
System.out.println("Written screenshot to " + screenshotAbsolutePath);
至:
Reporter.log("<a href=\"" + screenshotAbsolutePath + "\"><p align=\"left\">Add New PR screenshot at " + new Date()+ "</p>");
在上面的代码中,屏幕截图保存到的目录是使用名为 "screenshotDirectory" 的系统 属性 设置的。您需要设置他的系统 属性,或者将以下行更改为您要保存屏幕截图的硬编码位置。为此,这一行:
String screenshotDirectory = System.getProperty("screenshotDirectory");
需要更改为:
String screenshotDirectory = "/tmp/screenshots";
或者,如果您使用 windows,类似于:
String screenshotDirectory = "C:\tmp\screenshots";