Как повторно запустить неудачный тест в Espresso? – мозговой штурм

Я пытаюсь выяснить, как повторно запустить неудачные тесты с использованием Espresso. Я думаю, что это немного сложнее из обычного тестового примера JUnit, так как вам нужно восстановить статус в приложении до начала теста.

Мой подход заключается в создании моего собственного ActivityTestRule, поэтому я просто скопировал весь код из этого класса и назвал его MyActivityTestRule.

В случае применения контрольно-измерительных испытаний также потребуется информация о том, как мы хотим начать нашу деятельность. Я предпочитаю запускать его сам, а не среду, чтобы сделать это для меня. Так, например:

@Rule public MyActivityTestRule<ActivityToStartWith> activityRule = new MyActivityTestRule<>( ActivityToStartWith.class, true, false ); 

Поэтому я также запускаю свою деятельность в методе @Before annotation:

  @Before public void setUp() throws Exception { activityRule.launchActivity(new Intent()); } 

И сделайте очистку в @ После метода аннотации:

  @After public void tearDown() throws Exception { cleanUpDataBaseAfterTest(); returnToStartingActivity(activityRule); } 

Эти методы – setUp (), tearDown () необходимы для вызова до / после каждого тестового прогона – для обеспечения правильности состояния приложения во время запуска теста.


Внутри MyActivityTestRule я сделал несколько модификаций. Во-первых, это изменение метода применения:

  @Override public Statement apply(final Statement base, Description description) { return new ActivityStatement(super.apply(base, description)); } 

Для меня это неизвестная вещь, поскольку ActivityStatement, размещенный в ActivityTestRule, имеет метод super.apply, поэтому он также завершает тестовый оператор в UiThreadStatement:

 public class UiThreadStatement extends Statement { private final Statement mBase; private final boolean mRunOnUiThread; public UiThreadStatement(Statement base, boolean runOnUiThread) { mBase = base; mRunOnUiThread = runOnUiThread; } @Override public void evaluate() throws Throwable { if (mRunOnUiThread) { final AtomicReference<Throwable> exceptionRef = new AtomicReference<>(); getInstrumentation().runOnMainSync(new Runnable() { public void run() { try { mBase.evaluate(); } catch (Throwable throwable) { exceptionRef.set(throwable); } } }); Throwable throwable = exceptionRef.get(); if (throwable != null) { throw throwable; } } else { mBase.evaluate(); } } } 

Нет, не делайте то, что я делаю с моими испытаниями. Я никогда не могу создать случай, когда mRunOnUiThread логичен, чтобы быть правдой. Это будет верно, если в моих тестовых случаях будут присутствовать тесты с аннотацией @UiThreadTest – или это то, что я понял из кода. Это никогда не происходит, но я не использую ничего подобного, поэтому решил проигнорировать это UiThreadStatement и изменить MyActivityTestRule на:

  @Override public Statement apply(final Statement base, Description description) { return new ActivityStatement(base); } 

И мои тестовые примеры работают без проблем. Благодаря этому все, что у меня осталось – это обертывание вокруг mBase.evaluate ():

 private class ActivityStatement extends Statement { private final Statement mBase; public ActivityStatement(Statement base) { mBase = base; } @Override public void evaluate() throws Throwable { try { if (mLaunchActivity) { mActivity = launchActivity(getActivityIntent()); } mBase.evaluate(); } finally { finishActivity(); afterActivityFinished(); } } } 

В общем случае запускActivity будет вызываться только в том случае, если я задал в третьем параметре значение конструктора ActivityTestRule значение true. Но я запускаю тесты самостоятельно в setUp (), поэтому этого не происходит.

Из того, что я понял, mBase.evaluate () запускает мой код внутри метода аннотации @Test. Он также останавливает тестовый случай во время броска. Это означает, что я могу поймать его и перезапустить его – как предлагается там: как повторно запустить неудачные тесты JUnit?

И хорошо, я сделал что-то вроде этого:

  public class ActivityRetryStatement extends Statement { private final Statement mBase; private final int MAX_RUNS = 2; public ActivityRetryStatement(Statement base) { mBase = base; } @Override public void evaluate() throws Throwable { Throwable throwable = null; for (int i = 0; i < MAX_RUNS; i++) { try { mBase.evaluate(); // if you reach this lane that means evaluate passed // and you don't need to do the next run break; } catch (Throwable t) { // save first throwable if occurred if (throwable == null) { throwable = t; } // my try that didn't work launchActivity(testInitialIntent); // I've returned test to starting screen but // mBase.envaluate() didn't make it run again // it would be cool now to: // - invoke @After // - finish current activity // - invoke @Before again and start activity // - mBase.evaluate() should restart @Test on activity started again by @Before } } finishActivity(); afterActivityFinished(); // if 1st try fail but 2nd passes inform me still that there was error if (throwable != null) { throw throwable; } } } 

Таким образом, эти комментарии в блоке catch являются частями, которые я не знаю, как это сделать. Я попытался выполнить launchActivity по намерениям, которые я использовал в setUp (), чтобы запустить тест в первый раз. Но mBase.evaluate () не заставлял его реагировать (тестовый пример не повторился) – ничего не произошло +, это не спасло бы меня там, я думаю. Мне не хватало некоторых инициаций, которые я делаю в @SetUp, это не было вызвано снова. Я действительно хотел бы найти способ, как правильно перезапустить весь жизненный цикл тестирования @Before @Test @After снова. Возможно, некоторые вызовут Instrumentation или TestRunner из кода.

Любые мысли о том, как это можно сделать?

Ответ супер прост. Просто убедитесь, что вы обновили тесты эспрессо до 4 июня, а затем просмотрите этот ответ

Intereting Posts