java 如何在使用 Cucumber 和 JUnit 时截取屏幕截图并将其附加到 Allure 报告?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43315248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How take screenshot and attach it to Allure report, while using Cucumber and JUnit?
提问by SanchelliosProg
I'm using Cucumber, Selenium, Java, Maven and JUnit stack in my automation-test-project.
我在我的自动化测试项目中使用 Cucumber、Selenium、Java、Maven 和 JUnit 堆栈。
The goal is to take screenshots on fails and broken tests. I have found the solution for Java/Maven/JUnit stack:
目标是对失败和损坏的测试进行截图。我找到了 Java/Maven/JUnit 堆栈的解决方案:
@Rule
public TestWatcher screenshotOnFailure = new TestWatcher() {
@Override
protected void failed(Throwable e, Description description) {
makeScreenshotOnFailure();
}
@Attachment("Screenshot on failure")
public byte[] makeScreenshotOnFailure() {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
};
But, of course it does not work in case of using Cucumber, because it does not use any @Test methods.
但是,当然它在使用 Cucumber 的情况下不起作用,因为它不使用任何 @Test 方法。
So, I've decided to change @Rule to @ClassRule, to make it listen to any fails, so here it is:
因此,我决定将@Rule 更改为@ClassRule,以使其侦听任何失败,因此这里是:
@ClassRule
public static TestWatcher screenshotOnFailure = new TestWatcher() {
@Override
protected void failed(Throwable e, Description description) {
makeScreenshotOnFailure();
}
@Attachment("Screenshot on failure")
public byte[] makeScreenshotOnFailure() {
logger.debug("Taking screenshot");
return ((TakesScreenshot) Application.getInstance().getWebDriver()).getScreenshotAs(OutputType.BYTES);
}
};
And this solution didn't help me.
而这个解决方案对我没有帮助。
So, the question is: "How to attach screenshots on fail, when I use Java/Selenium/Cucumber/JUnit/Maven in my test project?"
所以,问题是:“当我在测试项目中使用 Java/Selenium/Cucumber/JUnit/Maven 时,如何在失败时附加屏幕截图?”
回答by SanchelliosProg
The solution is just to add following code to your definition classes:
解决方案只是将以下代码添加到您的定义类中:
@After
public void embedScreenshot(Scenario scenario) {
if (scenario.isFailed()) {
try {
byte[] screenshot = ((TakesScreenshot) Application.getInstance().getWebDriver())
.getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
} catch (Exception e) {
e.printStackTrace();
}
}
}
回答by Amit Malik
In the GlobalGlue
在 GlobalGlue
public class GlobalGlue {
@Before
public void before(Scenario scenario) throws Exception {
CONTEXT.setScenario(scenario);
}
@After
public void after() {
WebDriverUtility.after(getDriver(), CONTEXT.getScenario());
}
}
Create another class WebDriverUtility and in that add method:
创建另一个类 WebDriverUtility 并在该添加方法中:
public static void after(WebDriver driver, Scenario scenario) {
getScreenshot(driver, scenario);
driver.close();
}
and
和
public static void getScreenshot(WebDriver driver, Scenario scenario) {
if (scenario.isFailed()) {
final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
log.info("Thread: " + Thread.currentThread().getId() + " :: "
+ "Screenshot taken and inserted in scenario report");
}
}
}
the main part is you need to embed the screen shot in scenario when scenario is failed:
主要部分是您需要在场景失败时将屏幕截图嵌入场景中:
final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
ExecutionContext.java
执行上下文.java
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import cucumber.api.Scenario;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.WebDriver;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
/**
* Maintains one webdriver per scenario and one scenario per thread.
* Can be used for parallel execution.
* Assumes that scenarios within one feature are not parallel.
* Can be rewritten using <code>ThreadLocal</code>.
*
* @author dkhvatov
*/
public enum ExecutionContext {
CONTEXT;
private static final Logger log = LogManager.getLogger(ExecutionContext.class);
private final LoadingCache<Scenario, WebDriver> webDrivers =
CacheBuilder.newBuilder()
.build(CacheLoader.from(scenario ->
WebDriverUtility.createDriver()));
private final Map<String, Scenario> scenarios = new ConcurrentHashMap<>();
/**
* Lazily gets a webdriver for the current scenario.
*
* @return webdriver
*/
public WebDriver getDriver() {
try {
Scenario scenario = getScenario();
if (scenario == null) {
throw new IllegalStateException("Scenario is not set for context. " +
"Please verify your glue settings. Either use GlobalGlue, or set " +
"scenario manually: CONTEXT.setScenario(scenario)");
}
return webDrivers.get(scenario);
} catch (ExecutionException e) {
log.error("Unable to start webdriver", e);
throw new RuntimeException(e);
}
}
/**
* Gets scenario for a current thread.
*
* @return scenario
*/
public Scenario getScenario() {
return scenarios.get(Thread.currentThread().getName());
}
/**
* Sets current scenario. Overwrites current scenario in a map.
*
* @param scenario scenario
*/
public void setScenario(Scenario scenario) {
scenarios.put(Thread.currentThread().getName(), scenario);
}
}
回答by Chinthaka Devinda
This way you can attach screens to your allure report. Also use the Latest allure version in your pom file
通过这种方式,您可以将屏幕附加到您的魅力报告中。还要在你的 pom 文件中使用最新的诱惑版本
import com.google.common.io.Files;
import io.qameta.allure.Attachment;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import java.io.File;
import java.io.IOException;
public class ScreenshotUtils {
@Attachment(type = "image/png")
public static byte[] screenshot(WebDriver driver)/* throws IOException */ {
try {
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
return Files.toByteArray(screen);
} catch (IOException e) {
return null;
}
}
}
Pom File :
Pom文件:
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-cucumber4-jvm</artifactId>
<version>${allure.version}</version>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit4</artifactId>
<version>${allure.version}</version>
<scope>test</scope>
</dependency>