如何在使用JAVA和Cucumber的测试中的每个步骤后捕获屏幕截图?

在运行集成测试时, 在每个步骤之后捕获屏幕截图的最佳方法是什么?

测试使用Selenium(3.0.1)和Cucumber(1.2.4)用Java编写。

测试后截取屏幕截图的代码如下,但我需要在每个使用@Given,@ When,@Then注释的方法后截屏。

@After public void after(Scenario scenario){ final byte[] screenshot = driver.getScreenshotAs(OutputType.BYTES); scenario.embed(screenshot, "image/png"); } 

谢谢你的任何提示。

这篇文章可以帮到你吗?

在Cucumber JVM中嵌入屏幕截图

以下是您的问题的答案:

  1. 让我们假设您的方法如下:

     @Given("^Open$") public void Open() throws Throwable { //your code } @When("^I$") public void I(String uname, String pass) throws Throwable { //your code } @Then("^User$") public void User() throws Throwable { //your code } 
  2. 您可以编写一个库来截取如下截图:

     public static void screenshot(WebDriver driver, long ms) { try { TakesScreenshot ts = (TakesScreenshot) driver; File source = ts.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(source, new File("./ScreenShots/"+ms+"Facebook.png")); System.out.println("ScreenShot Taken"); } catch (Exception e) { System.out.println("Exception while taking ScreenShot "+e.getMessage()); } } 
  3. 现在您可以在每个方法之后轻松调用库来截取屏幕截图,如下所示:

     @Given("^Open$") public void Open() throws Throwable { //your code Utility.screenshot(driver, System.currentTimeMillis()); } @When("^I$") public void I(String uname, String pass) throws Throwable { //your code Utility.screenshot(driver, System.currentTimeMillis()); } @Then("^User$") public void User() throws Throwable { //your code Utility.screenshot(driver, System.currentTimeMillis()); } 

如果这回答你的问题,请告诉我。

使用Aspects解决了这个问题。 非常棘手,请注意注释:

 @After("call(public * cucumber.runtime.StepDefinitionMatch.runStep(..)) && within(cucumber.runtime.Runtime)") 

以下是Viviana Cattenazzi撰写的完整代码。

的pom.xml

    org.aspectj aspectjweaver 1.8.9   org.aspectj aspectjrt 1.8.9   org.aspectj aspectjtools 1.8.9   info.cukes cucumber-core 1.2.4   ......  org.codehaus.mojo aspectj-maven-plugin 1.10    info.cukes cucumber-core   true 1.8 1.8 1.8    process-test-classes  compile test-compile     

…….

StepsInterceptor.java

 @Aspect public class StepsInterceptor { @After("call(public * cucumber.runtime.StepDefinitionMatch.runStep(..)) && within(cucumber.runtime.Runtime)") public void beforeRunningStep(JoinPoint thisJoinPoint) throws Exception { try { StepDefinitionMatch stepDefinitionMatch = (StepDefinitionMatch) thisJoinPoint.getTarget(); Step step = (Step) retrievePrivateField(stepDefinitionMatch, "step"); String stepName = step.getKeyword().trim(); if ("Given".equals(stepName) || "When".equals(stepName)) { Object theRealStepDef = extractJavaStepDefinition(stepDefinitionMatch); // take screen shot here } } catch (ClassCastException exc) { .... } } } 

我不认为在接受并合并后续合并请求之前是可能的。 如果您真的感兴趣,可以在本地合并,并拥有自己的自定义Jar。

https://github.com/cucumber/cucumber-jvm/pull/838

这可能不是你问的,但这也可以帮助别人! (虽然我没有使用过Cucumber)

这是我拍摄屏幕截图并将其添加到PDF文件的代码(如果你想用它做其他事情)。

您只需要随时调用screenshotPDF(webDriver, testName)方法!

 package com.helper; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.openqa.selenium.Capabilities; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.server.handler.WebDriverHandler; import org.testng.annotations.Test; public class ScreenshotPDF { @SuppressWarnings("deprecation") @Test //public static void screenshotPDF() { public static void screenshotPDF(WebDriver webDriver, String testName){ { PDDocument doc = null; boolean isNewFile = false; Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy h:mm:ss a"); String timeStemp = sdf.format(date); try { try { doc = PDDocument.load(new File( "C:/Users/Documents/sample.pdf")); } catch (FileNotFoundException f) { doc = new PDDocument(); PDPage p = new PDPage(); doc.addPage(p); isNewFile = true; } File screenshot = ((TakesScreenshot) webDriver) .getScreenshotAs(OutputType.FILE); Integer numberP = doc.getNumberOfPages(); PDPage blankPage = new PDPage(); PDPage page; if (!isNewFile) { doc.addPage(blankPage); page = doc.getPage(numberP); } else { page = doc.getPage(numberP - 1); } PDImageXObject pdImage = PDImageXObject .createFromFileByContent(screenshot, doc); PDPageContentStream contentStream = new PDPageContentStream( doc, page, AppendMode.APPEND, true); PDFont font = PDType1Font.HELVETICA_BOLD; contentStream.beginText(); contentStream.setFont(font, 12); contentStream.moveTextPositionByAmount(100, 600); contentStream.drawString(testName+" "+timeStemp); contentStream.endText(); float scale = 0.4f; Capabilities cap = ((RemoteWebDriver) webDriver).getCapabilities(); String browserName = cap.getBrowserName().toLowerCase(); if (browserName.contains("explorer")) scale = 0.4f; contentStream.drawImage(pdImage, 50, 210, pdImage.getWidth() * scale, pdImage.getHeight() * scale); contentStream.close(); contentStream.close(); doc.save("C:/Users/Documents/sample.pdf"); } catch (Exception e) { e.printStackTrace(); } finally { if (doc != null) { try { doc.close(); } catch (IOException e) { e.printStackTrace(); } } } } } } 

黄瓜java中没有afterStep注释。 所以你不能直接做到这一点。 你可以用@DebanjanB答案中提到的另一种方式来做。

但这可以通过逐步注释在黄瓜ruby中实现。

Selenium公开了一个名为WebDriverEventListener的接口,你可以实现自己的代码,一般这个接口有像afterFindBy这样的方法,beforeFindBy只需要实现那个方法来拍摄屏幕截图。

实现此方法后,您需要将此实现的类注入到驱动程序对象,如下所示

 EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(driver); MyWebDriverListerner handler = new MyWebDriverListerner(); eventFiringWebDriver.register(handler); 

现在,只要驱动程序找到该元素,它就会调用相应的注入方法。

如果它能解决您的问题,请告诉我