如何在使用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中嵌入屏幕截图
以下是您的问题的答案:
-
让我们假设您的方法如下:
@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 }
-
您可以编写一个库来截取如下截图:
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()); } }
-
现在您可以在每个方法之后轻松调用库来截取屏幕截图,如下所示:
@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。
这可能不是你问的,但这也可以帮助别人! (虽然我没有使用过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);
现在,只要驱动程序找到该元素,它就会调用相应的注入方法。
如果它能解决您的问题,请告诉我