Selenide // Как продолжить выполнение теста если один из его степов упал на shouldHave(CollectionCondition.size()) ?

Привет.

Есть простой тест:

@Test
    public void knowMyIp() throws IOException
    {
        knowMyIpTest();
        scrollDown();
        oneMoreStep();
    }

В scrollDown() происходит проверка типа:

$(byText("Mon IP")).parent().findAll("a").shouldHave(CollectionCondition.size(15));

Она падает и тест на этом дальше не идёт, а хотелось бы.

Причём configfailurepolicy=“continue” в xml сьюта не помогает решить проблему.

Подскажите пожалуйста, есть ли возможность продолжения выполнения теста, если один из его степов сфейлился ? SoftAssert не предлагать, т.к. тут чисто селенидовский метод shouldHave.

Спасибо.

Вообще-то у селенида тоже есть свои soft asserts.

А вообще, если вы пропустите падение и пойдёте дальше, то как вы потом узнаете, что проверка упала? Будете глазами все отчёты просматривать?

Вообще-то у селенида тоже есть свои soft asserts.

Как это выглядит в коде, не подскажите ?

А вообще, если вы пропустите падение и пойдёте дальше, то как вы потом узнаете, что проверка упала? Будете глазами все отчёты просматривать?

Ну, иначе тест падает на втором шаге на той странице, где он был в момент падения и далее ничего не происходит. То есть следующий за ним тест вообще может оказаться не в том состоянии, где он должен быть в момент начала проверки. => второй тест может вообще не с того места пойти проверять и т.д.

Смысл не в том, чтобы пропускать падение, а в том, чтобы пометить что в этом шаге случился фейл и дальше пойти по флоу теста и делать другие проверки. Fail тесты же в отчёте красным маркируются - ничего страшного нет в том, чтобы зайти в отчет и увидеть что там во втором шаге случилась какая-то ошибка.

То есть еще раз, мне нужно накапливать ошибки по мере прохождения теста, не затрагивая его флоу, как в этом случае(в этом случае все другие проверки обрываются).
SoftAsserts для этого прекрасно подходит, но как это сделать средствами Selenide я не знаю.

Легко же гуглится: SoftAssertions · selenide/selenide Wiki · GitHub

1 лайк

Спасибо большое !

А тогда еще вопрос возник в продолжении - есть ли возможность где-то в одном только месте указывать листенеры по типу @Listeners({ SoftAsserts.class}), а не над каждым классом ?

А то для каждого нового класса прописывать как-то накладно и неудобно.


Попробовал указать в пределах сьюта в .xml :

<suite>
 
  <listeners>
    <listener class-name="com.example.MyListener" />
    <listener class-name="com.example.MyMethodInterceptor" />
  </listeners>

но получил:

Listener org.testng.asserts.SoftAssert@25e2a451 must be one of ITestListener, ISuiteListener, IReporter,  IAnnotationTransformer, IMethodInterceptor or IInvokedMethodListener

Кто-нибудь обходил такое ранее ?

Насколько я знаю, TestNG как раз именно так и устроен: достаточно повесить аннотацию @Listeners на один класс - и она начинает влиять на все тесты.

Насчёт второй ошибки странно: SoftAssert наследует класс ExitCodeListener, который наследуется от org.testng.ITestListener.

То есть следующий за ним тест вообще может оказаться не в том состоянии, где он должен быть в момент начала проверки. => второй тест может вообще не с того места пойти проверять и т.д.

Оу, это называется “зависимые тесты”. Крайне плохо. Мой совет: если тестов ещё не критически много - перепишите.
Каждый тест должен начинаться со старта браузера и логина пользователя (если оный есть, конечно). Для того, чтобы тесты бежали быстрее - используйте многопоточный запуск.

1 лайк

предлагать многопоток - это хорошо, а вот старт браузера каждый раз и логин пользователя (самые дорогие операции с точки зрения не тестов, а входа в тест кейс) - не очень хорошо

тот же самый селенид же умеет чистить браузер от предыдущей сессии + можно попросить у разработчиков ручку на бэке для сброса, ну и положить куку или токен в хранилище, чтоб не проходить логин - это база

1 лайк

Насколько я знаю, TestNG как раз именно так и устроен: достаточно повесить аннотацию @Listeners на один класс - и она начинает влиять на все тесты.

Не слышал такого. Кто-то из форумчан может это подтвердить ?

Насчёт второй ошибки странно: SoftAssert наследует класс ExitCodeListener , который наследуется от org.testng.ITestListener .

Упс, виноват, не тот SoftAssert заимпортил.
Но !
Это всё равно не решило проблемы. Теперь я получаю:

Starting ChromeDriver 114.0.5735.90 (386bc09e8f4f2e025eddae123f36f6263096ae49-refs/branch-heads/5735@{#1052}) on port 24001
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
июн 04, 2023 2:33:08 PM org.openqa.selenium.devtools.CdpVersionFinder findNearestMatch
WARNING: Unable to find an exact match for CDP version 114, so returning the closest version found: 113

java.lang.IllegalStateException: You must configure you classes using JUnit4/JUnit5/TestNG mechanism as documented in https://github.com/selenide/selenide/wiki/SoftAssertions

То есть что-то ему не нравится в:

<suite name = "Suite #1" configfailurepolicy="continue">
    <listeners>
        <listener class-name="com.codeborne.selenide.testng.SoftAsserts"/>
    </listeners>
...

Не находит он глобально объявленного листенера в *.xml

На багу смахивает :thinking:

Использую последнюю версию:

<dependency>
            <groupId>com.codeborne</groupId>
            <artifactId>selenide-testng</artifactId>
            <version>6.15.0</version>
            <scope>compile</scope>
        </dependency>

Если и багу, то багу TestNG, а не Селенида. :slight_smile:
А если положить болт на XML и добавить старую добрую аннотацию @Listeners(com.codeborne.selenide.testng.SoftAsserts.class)?

А если над классом листенер вешать - то всё ок.

Вы уверены, что это проблема TestNG ?

Ну если листенер над классом работает, значит, проблема не в листенере. Он - работает.
А где тогда проблема - вам лучше знать. Я точно не фанат TestNG.
Может, этот ваш xml не считывается, не попадает в classpath?

1 лайк

Если бы он не считывался, тогда тесты бы не запускались :man_shrugging:

Я точно не фанат [TestNG]

А почему, позвольте полюбопытствовать ? :slight_smile:

Тут рассказывал: Десять причин моей ненависти - Андрей Солнцев. QA Fest 2019 - YouTube

@asolntsev

Андрей, я спросил в TestNG группе по поддержке по этому вопросу, вот что сказали:


I have tried fetching your changes and then running the test code.
I can see that TestNG is invoking the listeners. There’s not much that can be done from the TestNG side.

The documentation of Selenide+TestNG states that the “SoftAsserts” listener is supposed to be added at the class level, but in your example code on github, I don’t see the annotation on the test class but instead I see that being added in the suite file.

When I added the “@Listeners(SoftAsserts.class)” to your test class and then ran the suite file, the testcase ran to completion without any issues.

I looked at the implementation and I see that you have to add the listener as a class level annotation and it will NOT work if you add it as a listener on your suite file.

So please fix your code according to the Selenide + TestNG documentation to get the sample working.

I can confirm that there’s no issues with TestNG in terms of listener invocation. If you still feel that there’s a problem, I would request you to please help share a test sample that uses only TestNG as a reproducible sample (using TestNG 7.8.0 with JDK11) so that we can further look into it.


То есть он говорит что листенер вызывается.
Выходит, всё же проблема Селенида это.

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

А, да, вспомнил.
Внутри самого SoftAsserts есть проверка, что он срабатывает только для тех классов, на которых висит аннотация @Listeners(SoftAsserts).

Изначально это было сделано как раз для того, чтобы не включать софт ассерты автоматически на все тесты (тот неожиданный эффект TestNG, который я уже упоминал выше).

И да, получается, это не очень удобно, если вы хотите глобально включить софт ассерты сразу для всех тестов. :frowning:

Но это легко решить, если ваши тестовые классы наследуются от общего родителя. Тогда аннотацию @Listeners(SoftAsserts) можно повесить на родительский класс.

Ага, можно и так.
Спасибо.