Помогите подключить Allure к проекту Java + TestNG + Maven

Есть проект Java + Selenium + TestNG + Maven
Помогите с настройкой Allure.
И настроить что б в отчете Allure были скриншоты.

А можно чуть конкретнее в чем проблема?

Вот тут довольно полное описание как подключить allure к maven

А вот тут довольно неплохие примеры.

Скриншоты вообще надо прикреплять через attach и там уже такой же вопрос - что именно не получается?

1 лайк

Спасибо. Получилось.
Осталось 2 вопроса:

  1. Можно ли сохранять Allurereport в html?

  2. Как добавить скрин в репорт? Сейчас скрины, при падение теста, просто сохраняются на диске.
    Код по сохранению скрина:

    @AfterMethod
    public void setScreenshot(ITestResult result) {
    if (!result.isSuccess()) {
    try {
    WebDriver returned = new Augmenter().augment(DRIVER);
    if (returned != null) {
    File f = ((TakesScreenshot) returned)
    .getScreenshotAs(OutputType.FILE);
    try {
    FileUtils.copyFile(f, new File(“E:\Test_results\”
    + result.getName() + " " + getFileName() + “.jpg”));
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    } catch (ScreenshotException se) {
    se.printStackTrace();
    }
    }
    }

И хранится он в AbstractTest, который наследуют все тестовые классы.
Подскажите, как и куда добавить @Attachment

Я подозреваю после mvn test не запустили mvn site.

После запуска mvn site появится:

target/site/allure-maven-plugin/index.html

То есть отчет в Html

По Аттачу:

1 лайк

Нашел, пардон. До этого смотрел в другой папке.
Запускал mvn clean test site jetty:run
Спасибо за ссылку.
Помогли!

Не совсем понимаю куда (в какой класс) записать эти методы:

@Attachment
public String performedActions(ActionSequence actionSequence) {
    return actionSequence.toString();
}

@Attachment(value = "Page screenshot", type = "image/png")
public byte[] saveScreenshot(byte[] screenShot) {
    return screenShot;
}

К сожалению, не могу сказать конкретно - так как не вижу Ваш тестовый фреймворк.

Сделайте куда вам будет удобнее, потом можно перенести :smile:

Сделал куда мне удобно (AbstractTest от него наследуются все тестовые классы), скриншоты не появляются

Давайте полный код, тут уже надо смотреть

AbstractTest.class:

public abstract class AbstractTest {
    public static WebDriver DRIVER;

    private String getFileName() throws IOException {
        DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy_hh.mm.ss");
        Date date = new Date();
        return dateFormat.format(date);
    }

    @BeforeMethod
    public static void before(){
        DRIVER =  new InternetExplorerDriver();
        DRIVER.manage().deleteAllCookies();
    }

    /*@AfterMethod(alwaysRun=true)
    public void setScreenshot(ITestResult result) {
        if (!result.isSuccess()) {
            try {
                WebDriver returned = new Augmenter().augment(DRIVER);
                if (returned != null) {
                    File f = ((TakesScreenshot) returned)
                            .getScreenshotAs(OutputType.FILE);
                    try {
                        FileUtils.copyFile(f, new File("E:\\Test_results\\"
                                + result.getName() + " " + getFileName() + ".jpg"));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } catch (ScreenshotException se) {
                se.printStackTrace();
            }
        }
    }*/
    
    @AfterMethod(alwaysRun=true)
    public static void after() {
        DRIVER.close();
        DRIVER.quit();
    }
}

Пример тестового класса:

public class TestServicePayments extends AbstractTest {
@Features("Платежы")
@Stories("МТС Украина")
@Test
public void createMTCProvider() throws Exception{
    LoginPage loginPage = new LoginPage(DRIVER);
    loginPage.navigateTo();
    MainPage mainPage = loginPage.loginToMainPage();

класс page-а LoginPage:

public class LoginPage extends AbstractPage {

public static final String LOGIN = "...";
public static final String PASSWORD = "....";
public static final int TIMEOUT_SECONDS = 20;
private final String URL = BASE_URL;

@FindBy(id = "Login_tbUserName")
WebElement inputLogin;

@FindBy(id = "Login_tbPassword")
WebElement inputPassword;

@FindBy(id = "Login_btnEnter")
WebElement enterBtn;

public LoginPage(WebDriver driver) {
    super(driver);
    PageFactory.initElements(driver, this);
}


@Override
public String getUrl() {
    return null;
}

@Override
public void navigateTo() {
    driver.get(URL);
    waitForPage();
}

@Override
public void waitForPage() {
    waitForElement(driver, inputLogin, TIMEOUT_SECONDS);
}

@Step
public MainPage loginToMainPage(){
    waitForPage();
    driver.manage().deleteAllCookies();
    inputLogin.clear();
    inputLogin.sendKeys(LOGIN);
    inputPassword.clear();
    inputPassword.sendKeys(PASSWORD);
    enterBtn.click();
    MainPage mainPage = new MainPage(driver);
    mainPage.waitForPage();
    mainPage.isElement();
    return mainPage;
}}

Класс от которого наследуются все Pages:

abstract public class AbstractPage extends WebDriverHelper implements Page {
protected WebDriver driver;
public static final String BASE_URL="http://....";
public static final String BASE_URL_MC="http://....";

public AbstractPage(WebDriver driver) {
    this.driver = driver;
}

public abstract void waitForPage();}

А где аннотация @Attachment?

Я вижу как делается скриншот в setScreenshot, но не вижу где он прикрепляется к отчету

Так вот я ж и спрашиваю, куда его вставить?
Я вставлял просто в конце класса

 @Attachment
public String performedActions(ActionSequence actionSequence) {
    return actionSequence.toString();
}

@Attachment(value = "Page screenshot", type = "image/png")
public byte[] saveScreenshot(byte[] screenShot) {
    return screenShot;
}

ничего не получается

Вставлять можно куда угодно, сделайте вспомогательный класс ScreenShotUtils, например.
ну и вызывайте метод взятия скриншота из вашего setScreenshot.

1 лайк

На практике используем такое.
Есть кастомный лисенер.

public class CustomTestListener extends TestListenerAdapter {

    private Logger log = LoggerFactory.getLogger(CustomTestListener.class);

    @Override
    public void onTestStart(ITestResult result) {
        log.info("Test class started: " + result.getTestClass().getName());
        log.info("Test started: " + result.getName());
    }

    @Override
    public void onTestSuccess(ITestResult result) {
        log.info("Test SUCCESS: " + result.getName());
    }

    @Override
    public void onTestFailure(ITestResult result) {
        makeScreenshot();
        log.info("Test FAILED: " + result.getName());
        if (result.getThrowable()!=null) {
            result.getThrowable().printStackTrace();
        }
    }

    @Attachment(value = "Page screenshot", type = "image/png")
    private byte[] makeScreenshot() {
        return ((TakesScreenshot) WebDriverRunner.getWebDriver()).getScreenshotAs(OutputType.BYTES);
    }
}

В нем есть метод makeScreenshot(), который вызывается при падении теста.
Этот логер можно навесть на базовый тестовый класс:

@Listeners({CustomTestListener.class})
public abstract class TestBase {
    // You code here
}

И теперь Аллюр делает скриншоты и добавляет их в репорты при падении тестов.

1 лайк

Ага, спасибо. Уже разобрался.
Сделал вот так:

public class ScreenshotListener extends TestListenerAdapter {

@Override
public void onTestFailure(ITestResult result){
    Object currentClass = result.getInstance();
    WebDriver driver = ((AbstractTest) currentClass).getDriver();
    byte[] srcFile =  ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
    saveScreenshot(srcFile);
}

@Override
public void onTestSuccess(ITestResult result){
    Object currentClass = result.getInstance();
    WebDriver driver = ((AbstractTest) currentClass).getDriver();
    byte[] srcFile =  ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
    saveScreenshot(srcFile);
}

@Override
public void onTestSkipped(ITestResult result){
    Object currentClass = result.getInstance();
    WebDriver driver = ((AbstractTest) currentClass).getDriver();
    byte[] srcFile =  ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
    saveScreenshot(srcFile);
}

@Attachment(value = "Page screenshot", type = "image/png")
private byte[] saveScreenshot(byte[] screenshot){
    return screenshot;
}}

И над классом который наследую все тесты:

@Listeners({ScreenshotListener.class})
public abstract class AbstractTest {

Делает скрин при любых условиях

2 лайка

Тоді вже так, щоб уникнути копіпасту.

public class ScreenshotListener extends TestListenerAdapter {

@Override
public void onTestFailure(ITestResult result){
saveScreenshot(result);
}

@Override
public void onTestSuccess(ITestResult result){
saveScreenshot(result);
}

@Override
public void onTestSkipped(ITestResult result){
saveScreenshot(result);
}

@Attachment(value = “Page screenshot”, type = “image/png”)
private byte[] saveScreenshot(ITestResult result){
Object currentClass = result.getInstance();
WebDriver driver = ((AbstractTest) currentClass).getDriver();
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
}

Але був хороший коментар про файл з утілітою, де цей скріншот атач є. Теж з практики ще використовуємо атач звичайного тексту, це можуть бути помилки з консолі для прикладу, чи JSON, чи HTML сторінки при падінні тесту.

@Attachment(value = "Console error", type = "text/plain") private byte[] addConsoleError(String errorText){ return errorText.getBytes(); }

Вся магія в заданні проавильного MIME типу в анотації @Attachment(type=<your_needed_type>) і тому що має витягнути метод чи що йому треба перадати і потім повернути як byte[].

2 лайка

подскажи пожалуйста, откуда у тя вот такое - WebDriverRunner.getWebDriver(), попробовал твой листенер, но что-то эта строка красная

Ну это видимо некое подобие синглтона для драйвера. Возвращает используемый в тестах инстанс драйвера.

 public void onTestFailure(ITestResult result) {
    makeScreenshot();
    log.info("Test FAILED: " + result.getName());

может сделать по наглядней в логе не INFO а ERROR ( log.error("Test FAILED: " + result.getName()):wink:

спасибо

Ребята, не подскажите в чем может быть проблема? Прикрутил скрины к отчетам, появляются и в папочках Target и в отчет попадают, но в отчет они попадает куда попало, есть если из 20-ти тестов один зафелин скриншот фейла попадет не в тест с фейлом, а в тест - “Past”, причем скрин фейла и как мне показалось всегда попадает в разный тест… Не приложу ума почему так…