美文网首页
自动化测试AndroidJUnitRunner

自动化测试AndroidJUnitRunner

作者: JuneLeo | 来源:发表于2018-06-07 17:52 被阅读0次
背景
  • 自动化测试开发过程中,由于对注解执行顺序不了解,可能发生时序异常,也会造成代码质量低
  • 各种注解所运行的线程不了解
目的
  • 掌握各种注解的执行时机
  • 提高代码开发质量
执行顺序图
image
收益
  • 发现度假在@Before中进行了mock,mock不生效
  • 打开了思维,对每个注解有了了解,可以在不同的注解中进行不同的事务
源码分析
public T launchActivity(@Nullable Intent startIntent) {
  ...
  if (null == startIntent) {

    startIntent = getActivityIntent();

    if (null == startIntent) {

        ...

      startIntent = new Intent(Intent.ACTION_MAIN);

    }

  }
    ...
  beforeActivityLaunched();  //子线程

  mActivity = mActivityClass.cast(mInstrumentation.startActivitySync(startIntent));//异步启动activity

  mInstrumentation.waitForIdleSync();  //子线程阻塞

  if (mActivity != null) {

    afterActivityLaunched();  //子线程

  } else {

    ...

  }

  return mActivity;

}

public void waitForIdleSync() {

    validateNotAppThread();  //判断不是UI线程

    Idler idler = new Idler(null);

    mMessageQueue.addIdleHandler(idler); //添加IdlerHandler

    mThread.getHandler().post(new EmptyRunnable());

    idler.waitForIdle(); //阻塞

}

private static final class Idler implements MessageQueue.IdleHandler {

    private final Runnable mCallback;

    private boolean mIdle;

    public Idler(Runnable callback) {

        mCallback = callback;

        mIdle = false;

    }

    public final boolean queueIdle() {

        if (mCallback != null) {

            mCallback.run();

        }

        synchronized (this) {

            mIdle = true;

            notifyAll();  //解除阻塞

        }

        return false;

    }

    public void waitForIdle() {

        synchronized (this) {

            while (!mIdle) {

                try {

                    wait(); //阻塞

                } catch (InterruptedException e) {

                }

            }

        }

    }

}
源码相关类
  • AndroidJUnitRunner 自动化测试入口 Runner
  • TestRequestBuilder 测试前请求构建类helper
  • LenientFilterRequest Request包装类
  • AndroidJUnit4ClassRunner test方法的Runner类 ,继承ParentRunner
  • ExtendedSuite(Runner)class的Runner类 继承ParentRunner ;保存着AndroidJUnit4ClassRunner(test方法Runner)
  • TestExecutor 测试执行类 运行ExtendedSuite中的run()开始执行Statement,启动入口;
  • Statement 执行各种注解对应的方法执行顺序
    • ExtendedSuite中的方法执行顺序为:
      RunRules(@ClassRule) ->RunAfters(@AfterClass) ->RunBefores(@BeforeClass);
    • AndroidJUnit4ClassRunner中的方法执行顺序为:
      RunRules(@Rule MethodRule和TestRule) ->RunAfters(@After) ->RunBefores(@Before) ->FailOnTimeout(@Test) ->ExpectException(@Test) ->InvokeMethod(@Test)
    • 注解执行顺序
      ExtendedSuite @ClassRule-> @BeforeClass -> {AndroidJUnit4ClassRunner} -> @AfterClass
      AndroidJUnit4ClassRunner @Rule-> @Before-> @Test-> @After
  • Statement链式调用
//ParentRunner
protected Statement classBlock(final RunNotifier notifier) {
    Statement statement = childrenInvoker(notifier);
    if (!areAllChildrenIgnored()) {
        statement = withBeforeClasses(statement);
        statement = withAfterClasses(statement);
        statement = withClassRules(statement);
    }
    return statement;
}
//BlockJUnit4ClassRunner 
protected Statement methodBlock(FrameworkMethod method) {
    Object test;
    try {
        test = new ReflectiveCallable() {
            @Override
            protected Object runReflectiveCall() throws Throwable {
                return createTest();
            }
        }.run();
    } catch (Throwable e) {
        return new Fail(e);
    }

    Statement statement = methodInvoker(method, test);
    statement = possiblyExpectingExceptions(method, test, statement);
    statement = withPotentialTimeout(method, test, statement);
    statement = withBefores(method, test, statement); //@before
    statement = withAfters(method, test, statement); 参数statement对应@Before
    statement = withRules(method, test, statement);
    return statement;
}
//@After
public class RunAfters extends Statement {
    private final Statement next;

    private final Object target;

    private final List<FrameworkMethod> afters;

    public RunAfters(Statement next, List<FrameworkMethod> afters, Object target) {
        this.next = next;
        this.afters = afters;
        this.target = target;
    }

    @Override
    public void evaluate() throws Throwable {
        List<Throwable> errors = new ArrayList<Throwable>();
        try {
            next.evaluate();   //这个statement对应@Before
        } catch (Throwable e) {
            errors.add(e);
        } finally {
            for (FrameworkMethod each : afters) {
                try {
                    each.invokeExplosively(target);
                } catch (Throwable e) {
                    errors.add(e);
                }
            }
        }
        MultipleFailureException.assertEmpty(errors);
    }
}

相关文章

网友评论

      本文标题:自动化测试AndroidJUnitRunner

      本文链接:https://www.haomeiwen.com/subject/sdxnsftx.html