我正在使用TestNG 6.8 + Selenium WebDriver 2.32来测试Web应用程序的GUI。在测试失败的情况下,我想截取应用程序GUI的屏幕截图。
我有什么:
IInvokedMethodListener
我需要什么:
这是我的代码的骨架:
import org.testng.annotations.Listeners;
...
@Listeners(GuiTestListener.class)
public abstract class AbstractGuiTest {
protected WebDriver driver; //Used by all tests
...
}
这是我的测试监听器类,它对失败的测试作出反应:
public class GuiTestListener implements IInvokedMethodListener {
@Override
public void afterInvocation(IInvokedMethod method, ITestResult itr) {
if (method.isTestMethod() && !itr.isSuccess()) {
//Take a screenshot here. But how do I get at the intance of WebDriver declared in the AbstractGuiTest?
}
}
}
您能否建议如何获取在AbstractGuitTest中声明的WebDriver实例,以便我可以使用它在GuiTestListener类中截取屏幕截图?
答案 0 :(得分:2)
你可以从ITestResult获得它:
Object x = itr.getInstance();
AbstractGuiTest currentCase = (AbstractGuiTest)x;
WebDriver driver = currentCase.getDriver();
答案 1 :(得分:1)
您可能的解决方案很好地捕获了这个想法 - 应该有一些地方在测试和监听器之间共享WebDriver
实例。我想到了另外两个解决方案,这些解决方案用于我参与的项目或我在互联网上阅读过。
通过Singleton“holder”类共享它,就像在这个blogpost中一样。它是关于Groovy和Geb的,但它提出了这个想法。
使用依赖注入(例如guiceberry)在需要它的所有地方注入WebDriver
。 guiceberry tutorial中有一个例子。
答案 2 :(得分:0)
我有一些类似的东西,我需要在测试失败时使用selenium截取屏幕截图。我的所有测试类扩展AbstractTestNGSpringContextTests实现TestWithSeleniumDriver,它们有注释@Listeners(ScreenshotForFailedTestListener.class)
public interface TestWithSeleniumDriver {
public RemoteWebDriver getDriver();
}
public class ScreenshotForFailedTestListener implements IInvokedMethodListener {
@Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
// nothing
}
@Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod() && ITestResult.FAILURE == testResult.getStatus()) {
if (method.getTestResult().getInstance() instanceof TestWithSeleniumDriver) {
TestWithSeleniumDriver instance = (TestWithSeleniumDriver) method.getTestResult().getInstance();
RemoteWebDriver driver = instance.getDriver();
if (driver != null) {
TestingUtils.captureScreen(driver, method);
}
}
}
}
}
public class TestingUtils {
private static final Logger logger = LogManager.getLogger(TestingUtils.class);
public static String captureScreen(RemoteWebDriver driver, IInvokedMethod method) {
String path;
try {
Throwable throwable = method.getTestResult().getThrowable();
String testClass = method.getTestMethod().getRealClass().getName();
String packageName = method.getTestMethod().getRealClass().getPackage().getName();
String shortClassName = method.getTestMethod().getRealClass().getSimpleName();
String testMethod = method.getTestMethod().getMethodName();
StackTraceElement stackTraceElement = null;
for (StackTraceElement traceElement : throwable.getStackTrace()) {
if (traceElement.getClassName().equals(testClass) && traceElement.getMethodName().equals(testMethod)) {
stackTraceElement = traceElement;
break;
}
}
WebDriver augmentedDriver = new Augmenter().augment(driver);
File source = ((TakesScreenshot) augmentedDriver).getScreenshotAs(OutputType.FILE);
String drvName = "unknown";
if (driver instanceof FirefoxDriver)
drvName = "firefox";
else if (driver instanceof ChromeDriver)
drvName = "chrome";
else if (driver instanceof OperaDriver)
drvName = "opera";
// else if ( driver instanceof AndroidDriver )
// drvName = "android";
else if (driver instanceof RemoteWebDriver)
if (driver.getCapabilities().getBrowserName() != null)
drvName = driver.getCapabilities().getBrowserName();
String day = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String hour = new SimpleDateFormat("HH-mm-ss").format(new Date());
if (stackTraceElement == null) {
path = ("./target/screenshots/" + drvName + "/" + "failed" + "/" + //
day + "/" + //
packageName + "/" + shortClassName + "/" + testMethod + "_noLineInfo_" + //
driver.getCurrentUrl().replaceAll("https://", "").replaceAll("/", "_") + "_" + //
hour + ".png").replaceAll("__", "_");//
} else {
path = ("./target/screenshots/" + drvName + "/" + "failed" + "/" + //
day + "/" + //
packageName + "/" + shortClassName + "/" + testMethod + "_line-" + stackTraceElement.getLineNumber() + "_" + //
driver.getCurrentUrl().replaceAll("https://", "").replaceAll("/", "_") + "_" + //
hour + ".png").replaceAll("__", "_");//
}
FileUtils.copyFile(source, new File(path));
String stackTrace = ExceptionUtils.getStackTrace(throwable);
logger.error("===========================");
logger.error("screnshot captured to : " + path);
logger.error("===========================");
} catch (IOException e) {
path = "Failed to capture screenshot: " + e.getMessage();
}
return path;
}
}
代码必须根据您的需求进行调整