Как я могу запустить JUnit 4.8 после неудачного теста, но перед любыми методами @After?
Я провожу серию тестов Selenium (на самом деле Sedenium с поддержкой WebDriver), используя JUnit 4.8.2. Я бы хотел, чтобы тесты автоматически снимали скриншот браузера, как только тест не подтвердил утверждение. Все тесты наследуют от SeleniumBaseTestCase
, а большинство затем наследует от SeleniumBastTestCaseWithCompany
(который использует методы @Before
и @After
для создания, а затем очистки общих тестовых данных через Selenium).
Я попытался добавить подкласс TestWatchman
в качестве @Rule
в SeleniumBaseTestCase
, переопределяя метод TestWatchman
failed
, чтобы сделать снимок экрана. Проблема в том, что методы @After
, очищающие тестовые данные, запускаются до того, как вызывается метод TestWatchman
failed
, поэтому скриншоты - это последний шаг очистки, а не те, которые не выполнялись.
В нем мало что кажется, что метод TestWatchman
apply
просто вызывает переданный метод оценки Statement
(единственный открытый метод), который вызывает методы @After
, оставляя TestWatchman
(или любой other Rule
) нет возможности вставить какой-либо код между выполнением теста и методами @After
, насколько я могу судить.
Я также видел подходы, которые создают пользовательский Runner
, чтобы изменить созданный Statement
так, чтобы методы, аннотированные с помощью пользовательского @AfterFailure
, выполнялись до методов @After
(так что скриншот можно взять в таком @AfterFailure
), но это зависит от переопределения метода BlockJUnit4ClassRunner
withAfters
, который устарел и из-за того, что стал закрытым, согласно documentation, который предлагает использовать Правила вместо этого.
Я нашел еще один ответ на SO о жизненном цикле @Rule, который заставляет его звучать так, как это может быть просто невозможно в JUnit 4.8, но может быть возможно в JUnit 4.10. Если бы это правильно, то справедливое, я бы просто хотел подтвердить это в первую очередь.
Любые мысли об элегантном и перспективном способе, в котором я могу достичь того, что я хочу, будут высоко оценены!
Ответы
Ответ 1
Вы правы в своем анализе, @Befores и @Afters добавляются в список заявлений перед любыми Правилами. @Before
выполняется после @Rule
, а @After
выполняется до @Rule
. Как вы это исправите, это зависит от того, насколько гибким может быть SeleniumBaseTestCaseWithCompany
.
Самый простой способ - удалить методы @Before/@After
и заменить их ExternalResource. Это может выглядеть примерно так:
public class BeforeAfterTest {
@Rule public TestRule rule = new ExternalResource() {
protected void before() throws Throwable { System.out.println("externalResource before"); }
protected void after() { System.out.println("externalResource after"); }
};
@Test public void testHere() { System.out.println("testHere"); }
}
это дает:
externalResource before
testHere
externalResource after
Это поле может быть помещено в ваш базовый класс, поэтому он наследуется/переопределяется. Ваша проблема с упорядочением между @After и вашими правилами затем уходит, потому что вы можете заказать свои правила, как вам нравится, используя @RuleChain (в 4.10, а не 4.8).
Если вы не можете изменить SeleniumBaseTestCaseWithCompany
, вы можете расширить BlockJUnit4ClassRunner
, но не переопределять withAfters, но переопределить BlockJUnit4ClassRunner # methodBlock(). Затем вы можете вызвать super.methodBlock и изменить порядок действий (*).
[*] Вы можете просто скопировать код и изменить порядок строк, но withRules является приватным и, следовательно, не может быть вызван из подкласса.