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

时间:2017-06-01 04:02:13

标签: java selenium cucumber integration-testing

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

使用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");
}

感谢您的任何提示。

8 个答案:

答案 0 :(得分:1)

这篇文章可以帮到你吗?

Embedding screenshots in Cucumber JVM

答案 1 :(得分:1)

以下是您的问题的答案:

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

    $now = Carbon::now();
    $schedule = Schedule::where('start_date', '<=', $now)
        ->where('end_date', '>=', $now)
        ->get();
    
  2. 您可以编写一个库来截取如下截图:

    @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
    }
    
  3. 现在您可以在每个方法之后轻松调用库来截取屏幕截图,如下所示:

    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());
    }
    
    
    }
    
  4. 如果这回答你的问题,请告诉我。

答案 2 :(得分:1)

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

slf4j-simple

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

<强>的pom.xml

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

.......

<强> StepsInterceptor.java

 <dependencies>
         <dependency>
             <groupId>org.aspectj</groupId>
             <artifactId>aspectjweaver</artifactId>
             <version>1.8.9</version>
         </dependency>
         <dependency>
             <groupId>org.aspectj</groupId>
             <artifactId>aspectjrt</artifactId>
             <version>1.8.9</version>
         </dependency>
         <dependency>
             <groupId>org.aspectj</groupId>
             <artifactId>aspectjtools</artifactId>
             <version>1.8.9</version>
         </dependency>
         <dependency>
             <groupId>info.cukes</groupId>
             <artifactId>cucumber-core</artifactId>
             <version>1.2.4</version>
         </dependency>
     </dependencies>

......

         <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>aspectj-maven-plugin</artifactId>
             <version>1.10</version>
             <configuration>
                 <weaveDependencies>
                     <weaveDependency>
                         <groupId>info.cukes</groupId>
                         <artifactId>cucumber-core</artifactId>
                     </weaveDependency>
                 </weaveDependencies>
                 <showWeaveInfo>true</showWeaveInfo>
                 <source>1.8</source>
                 <target>1.8</target>
                 <complianceLevel>1.8</complianceLevel>
             </configuration>
             <executions>
                 <execution>
                     <phase>process-test-classes</phase>
                     <goals>
                         <goal>compile</goal>
                         <goal>test-compile</goal>
                     </goals>
                 </execution>
             </executions>
         </plugin>

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

这可能不是你问的,但这也可以帮助别人! (虽然我没有使用过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();
                    }
                }
            }
        }

    }

}

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

这时,OP可能已经找到了备选方案。但是,这可能会帮助其他人。 io.cucumber的最新版本同时具有@BeforeStep和@AfterStep,因此您可以将捕获的屏幕截图嵌入到@AfterStep函数中,这可以解决您的问题。

https://stackoverflow.com/a/53135127/5885718

答案 7 :(得分:-1)

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

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

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="DatePicker">
        ...
        <!-- The text color for the selected date header text, ex. "2014" or
             "Tue, Mar 18". This should be a color state list where the
             activated state will be used when the year picker or day picker is
             active.-->
        <attr name="headerTextColor" format="color" />
    </declare-styleable>
</resources>

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

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