Espresso, Beyond the basics @ 360AnDev

Espresso, Beyond the basics @ 360AnDev

32018c62accb6edf57251e04308d4216?s=128

Iñaki Villar

July 14, 2017
Tweet

Transcript

  1. 2.
  2. 23.

    boolean isIdleNow() { if (!pool.getQueue().isEmpty()) { return false; } else

    { int activeCount = pool.getActiveCount(); if (0 != activeCount) { if (monitor.get() == null) { activeCount = activeCount - activeBarrierChecks.get(); } } return 0 == activeCount; } } AsyncTaskPoolMonitor
  3. 32.

    UiController boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException; boolean injectKeyEvent(KeyEvent event) throws

    InjectEventSecurityException; boolean injectString(String str) throws InjectEventSecurityException;
  4. 33.

    UiController boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException; boolean injectKeyEvent(KeyEvent event) throws

    InjectEventSecurityException; boolean injectString(String str) throws InjectEventSecurityException; EventInjector AsyncTaskMonitor IdlingResourceRegistry
  5. 34.

    UiController boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException; boolean injectKeyEvent(KeyEvent event) throws

    InjectEventSecurityException; boolean injectString(String str) throws InjectEventSecurityException; EventInjector AsyncTaskMonitor IdlingResourceRegistry boolean allResourcesAreIdle()
  6. 38.

    ViewInteractionModule Matcher<Root> ViewFinder Matcher<View> View ViewInteractionComponent public static ViewInteraction onView(final

    Matcher<View> viewMatcher) { return BASE.plus(new ViewInteractionModule(viewMatcher)).viewInteraction(); }
  7. 45.

    
 perform(click());
 new GeneralClickAction(Tap.SINGLE, VISIBLE_CENTER, Press.FINGER)); 
 MotionEvents.sendDown(uiController, coordinates, precision);


    
 uiController.injectMotionEvent(motionEvent);
 
 MainActivityTest
 
 ViewActions
 
 Tapper
 
 MotionEvents

  8. 49.

    @Override
 public void loopMainThreadUntilIdle() {
 do {
 if (!asyncTaskMonitor.isIdleNow()) {


    asyncTaskMonitor.notifyWhenIdle(…);
 condChecks.add(IdleCondition.ASYNC_TASKS_HAVE_IDLED);
 }
 
 if (!compatTaskMonitor.isIdleNow()) {
 compatTaskMonitor.notifyWhenIdle(…);
 condChecks.add(IdleCondition.COMPAT_TASKS_HAVE_IDLED);
 }
 
 if (!idlingResourceRegistry.allResourcesAreIdle()) {
 idlingResourceRegistry.notifyWhenAllResourcesAreIdle(…);
 condChecks.add(IdleCondition.DYNAMIC_TASKS_HAVE_IDLED);
 }
 
 loopUntil(condChecks);
 } while (!sIdleNow()); }
  9. 50.

    @Override
 public void loopMainThreadUntilIdle() {
 do {
 if (!asyncTaskMonitor.isIdleNow()) {


    asyncTaskMonitor.notifyWhenIdle(…);
 condChecks.add(IdleCondition.ASYNC_TASKS_HAVE_IDLED);
 }
 
 if (!compatTaskMonitor.isIdleNow()) {
 compatTaskMonitor.notifyWhenIdle(…);
 condChecks.add(IdleCondition.COMPAT_TASKS_HAVE_IDLED);
 }
 
 if (!idlingResourceRegistry.allResourcesAreIdle()) {
 idlingResourceRegistry.notifyWhenAllResourcesAreIdle(…);
 condChecks.add(IdleCondition.DYNAMIC_TASKS_HAVE_IDLED);
 }
 
 loopUntil(condChecks); } while (!sIdleNow()); }
  10. 51.
  11. 52.
  12. 53.
  13. 54.
  14. 55.
  15. 56.

    abstract class WrappingES(delegate: ExecutorService) : ExecutorService { val delegate: ExecutorService

    = checkNotNull(delegate) abstract fun <T> wrapTask(callable: Callable<T>): Callable<T> fun wrapTask(command: Runnable): Runnable { val wrapped = wrapTask(Executors.callable<Any>(command, null)) return Runnable { try { wrapped.call() } catch (e: Exception) { throw RuntimeException(e) } } }
  16. 57.

    abstract class WrappingES(delegate: ExecutorService) : ExecutorService { val delegate: ExecutorService

    = checkNotNull(delegate) abstract fun <T> wrapTask(callable: Callable<T>): Callable<T> fun wrapTask(command: Runnable): Runnable { val wrapped = wrapTask(Executors.callable<Any>(command, null)) return Runnable { try { wrapped.call() } catch (e: Exception) { throw RuntimeException(e) } } }
  17. 58.

    abstract class WrappingES(delegate: ExecutorService) : ExecutorService { val delegate: ExecutorService

    = checkNotNull(delegate) abstract fun <T> wrapTask(callable: Callable<T>): Callable<T> fun wrapTask(command: Runnable): Runnable { val wrapped = wrapTask(Executors.callable<Any>(command, null)) return Runnable { try { wrapped.call() } catch (e: Exception) { throw RuntimeException(e) } } }
  18. 59.

    override fun execute(command: Runnable) { delegate.execute(wrapTask(command)) } override fun <T>

    submit(task: Callable<T>): Future<T> { return delegate.submit(wrapTask(checkNotNull(task))) } override fun submit(task: Runnable): Future<*> { return delegate.submit(wrapTask(task)) } override fun <T> submit(task: Runnable, result: T): Future<T> { return delegate.submit(wrapTask(task), result) }
  19. 60.

    class IdlingResourceExecutorService(delegate: ExecutorService, val mIdlingResource: CountingIdlingResource) : GuavaWrappingExecutorService(delegate) { override

    fun <T> wrapTask(callable: Callable<T>): Callable<T> { return WrappedCallable(callable) } private inner class WrappedCallable<T>(private val delegate: Callable<T>) : Callable<T> { @Throws(Exception::class) override fun call(): T { mIdlingResource.increment() val call: T try { call = delegate.call() } finally { mIdlingResource.decrement() } return call } } } 
 }
  20. 61.

    class IdlingResourceExecutorService(delegate: ExecutorService, val mIdlingResource: CountingIdlingResource) : GuavaWrappingExecutorService(delegate) { override

    fun <T> wrapTask(callable: Callable<T>): Callable<T> { return WrappedCallable(callable) } private inner class WrappedCallable<T>(private val delegate: Callable<T>) : Callable<T> { @Throws(Exception::class) override fun call(): T { mIdlingResource.increment() val call: T try { call = delegate.call() } finally { mIdlingResource.decrement() } return call } } } 
 }
  21. 62.

    class IdlingResourceExecutorService(delegate: ExecutorService, val mIdlingResource: CountingIdlingResource) : GuavaWrappingExecutorService(delegate) { override

    fun <T> wrapTask(callable: Callable<T>): Callable<T> { return WrappedCallable(callable) } inner class WrappedCallable<T>(val delegate: Callable<T>) : Callable<T> { @Throws(Exception::class) override fun call(): T { mIdlingResource.increment() val call: T try { call = delegate.call() } finally { mIdlingResource.decrement() } return call } } } 
 }
  22. 63.
  23. 64.

    public class RxSchedulerHook extends RxJavaSchedulersHook {
 
 private Scheduler customScheduler;


    private CountingIdlingResource idling;
 private static RxSchedulerHook sInstance;
 public RxSchedulerHook(CountingIdlingResource countingIdlingResource) {
 FailedTest watcher = new FailedTest();
 idling = countingIdlingResource;
 customScheduler = new Scheduler() {
 @Override public Scheduler.Worker createWorker() {
 return new CustomWorker();
 }
 };
 }

  24. 65.

    @Override public Subscription schedule(final Action0 action, final long delayTime, TimeUnit

    unit) {
 return super.schedule(new Action0() {
 @Override public void call() {
 
 action.call();
 }
 }, delayTime, unit);
 }
 
 @Override public Subscription schedule(final Action0 action) {
 return super.schedule(new Action0() {
 @Override public void call() {
 idling.increment();
 try {
 action.call();
 } finally {
 idling.decrement();
 }
 }
 });
 }
  25. 67.
  26. 69.
  27. 70.

    @Rule public ActivityTestRule<Main> activityTestRule = new ActivityTestRule<>(Main){
 @Override
 protected void

    beforeActivityLaunched() {
 super.beforeActivityLaunched();
 }
 
 @Override
 protected void afterActivityLaunched() {
 super.afterActivityLaunched();
 }
 
 @Override
 protected void afterActivityFinished() {
 super.afterActivityFinished();
 }
 };
  28. 71.

    @Rule public ActivityTestRule<Main> activityTestRule = new ActivityTestRule<>(Main){
 @Override
 protected void

    beforeActivityLaunched() {
 super.beforeActivityLaunched();
 }
 
 @Override
 protected void afterActivityLaunched() {
 super.afterActivityLaunched();
 }
 
 @Override
 protected void afterActivityFinished() {
 super.afterActivityFinished();
 }
 };
  29. 73.

    @Rule public IntentTestRule<Main> activityTestRule = new IntentTestRule<>(Main) 
 
 public

    IntentsTestRule(Class<T> activityClass, boolean initialTouchMode,
 boolean launchActivity) {
 super(activityClass, initialTouchMode, launchActivity);
 }
 
 @Override
 protected void afterActivityLaunched() {
 Intents.init();
 super.afterActivityLaunched();
 }
 
 @Override
 protected void afterActivityFinished() {
 super.afterActivityFinished();
 Intents.release();
 }
 
 

  30. 75.

    public interface TestRule {
 Statement apply(Statement base, Description description);
 }

    public class UiThreadTestRule implements TestRule {
 private static final String LOG_TAG = "UiThreadTestRule";
 
 @Override
 public Statement apply(final Statement base, Description description) {
 return new UiThreadStatement(base, shouldRunOnUiThread(description));
 }
 
 protected boolean shouldRunOnUiThread(Description description) {
 return description.getAnnotation(UiThreadTest.class) != null;
 } }
  31. 76.

    private class ActivityStatement extends Statement {
 
 private final Statement

    mBase;
 
 public ActivityStatement(Statement base) {
 mBase = base;
 }
 
 @Override
 public void evaluate() throws Throwable {
 try {
 if (mLaunchActivity) {
 act = launchActivity(getActivityIntent());
 }
 mBase.evaluate();
 } finally {
 finishActivity();
 }
 }
 }
  32. 77.

    public class TraceTestRule implements TestRule {
 
 private Trace trace;


    
 @Override
 public Statement apply(final Statement base, Description description) {
 return new Statement() {
 @Override
 public void evaluate() throws Throwable {
 try {
 trace.start();
 base.evaluate();
 } finally {
 trace.end();
 }
 }
 };
 }
 }
  33. 78.

    public class TraceTestRule implements TestRule {
 
 private Trace trace;


    
 @Override
 public Statement apply(final Statement base, Description description) {
 return new Statement() {
 @Override
 public void evaluate() throws Throwable {
 try {
 trace.start();
 base.evaluate();
 } finally {
 trace.end();
 }
 }
 };
 }
 } @Rule
 public TraceTestRule traceTestRule = new TraceTestRule(getTargetContext());

  34. 80.

    return new Statement() {
 @Override
 public void evaluate() throws Throwable

    {
 List<Throwable> errors = new ArrayList<Throwable>();
 
 startingQuietly(description, errors);
 try {
 base.evaluate();
 succeededQuietly(description, errors);
 } catch (AssumptionViolatedException e) {
 errors.add(e);
 skippedQuietly(e, description, errors);
 } catch (Throwable e) {
 errors.add(e);
 failedQuietly(e, description, errors);
 } finally {
 finishedQuietly(description, errors);
 }
 
 MultipleFailureException.assertEmpty(errors);
 }
 }; public abstract class TestWatcher implements TestRule
  35. 81.

    return new Statement() {
 @Override
 public void evaluate() throws Throwable

    {
 List<Throwable> errors = new ArrayList<Throwable>();
 
 startingQuietly(description, errors);
 try {
 base.evaluate();
 succeededQuietly(description, errors);
 } catch (AssumptionViolatedException e) {
 errors.add(e);
 skippedQuietly(e, description, errors);
 } catch (Throwable e) {
 errors.add(e);
 failedQuietly(e, description, errors);
 } finally {
 finishedQuietly(description, errors);
 }
 
 MultipleFailureException.assertEmpty(errors);
 }
 }; public abstract class TestWatcher implements TestRule
  36. 82.

    public class FailedTest extends TestWatcher {
 
 public FailedTest() {


    uiAutomation = UiDevice.getInstance();
 }
 
 
 @Override
 protected void failed(Throwable e, Description description) {
 super.failed(e, description);
 String fileNameBase = getFileNameWithoutExtension(description);
 saveScreenshot(fileNameBase);
 saveInfo(fileNameBase);
 }
 
 @Override
 protected void succeeded(Description description) {
 super.succeeded(description);
 }
 
 @Override
 protected void skipped(AssumptionViolatedException e, Description description) {
 super.skipped(e, description);
 }

  37. 83.

    public class FailedTest extends TestWatcher {
 
 public FailedTest() {


    uiAutomation = UiDevice.getInstance();
 }
 
 
 @Override
 protected void failed(Throwable e, Description description) {
 super.failed(e, description);
 String fileNameBase = getFileNameWithoutExtension(description);
 saveScreenshot(fileNameBase);
 saveInfo(fileNameBase);
 }
 
 @Override
 protected void succeeded(Description description) {
 super.succeeded(description);
 }
 
 @Override
 protected void skipped(AssumptionViolatedException e, Description description) {
 super.skipped(e, description);
 }

  38. 84.

    public class FailedTest extends TestWatcher {
 
 public FailedTest() {


    uiAutomation = UiDevice.getInstance();
 }
 
 
 @Override
 protected void failed(Throwable e, Description description) {
 super.failed(e, description);
 String fileNameBase = getFileNameWithoutExtension(description);
 saveScreenshot(fileNameBase);
 saveInfo(fileNameBase);
 }
 
 @Override
 protected void succeeded(Description description) {
 super.succeeded(description);
 }
 
 @Override
 protected void skipped(AssumptionViolatedException e, Description description) {
 super.skipped(e, description);
 }

  39. 86.

    public class RuleChain implements TestRule
 public RuleChain ruleChain = RuleChain.outerRule(new

    LogRule("outer rule")
 .around(new LogRule("middle around rule")
 .around(new LogRule("inner around rule”))));
  40. 87.

    public class RuleChain implements TestRule
 public RuleChain ruleChain = RuleChain.outerRule(new

    LogRule("outer rule")
 .around(new LogRule("middle around rule")
 .around(new LogRule("inner around rule”)))); Starting outer Starting middle Starting inner Finishing inner Finishing middle Finishing outer
  41. 89.

    public NewActivityTestRule<Main> activityRule = new NewActivityTestRule<>(Main.class);
 
 
 @Rule
 public

    RuleChain chain = RuleChain.outerRule(new FailedTest() .around(activityRule);

  42. 90.

    public NewActivityTestRule<Main> activityRule = new NewActivityTestRule<>(Main.class);
 
 
 @Rule
 public

    RuleChain chain = RuleChain.outerRule(new FailedTest() .around(activityRule);
 
 @Rule
 public RuleChain chain = RuleChain.outerRule(new FailedTest()) .around(new TraceTestRule()) .around(activityRule);

  43. 91.
  44. 102.
  45. 103.