您的位置:软件测试 > 开源软件测试 > 开源单元测试工具 > junit
Junit使用及其原理分析
作者:alighters 发布时间:[ 2016/9/13 10:53:28 ] 推荐标签:单元测试 Junit

  其会调到一个 run(Runner runner) 的方法,而 Runner 是一个抽象类,其实现针对不同的平台又有好多个。这里主要提及两个,一个是 Junit4ClassRunner,它是 4.4 版本及之前的采用的,之后被废弃掉了,而采用了继承实现抽象类 ParentRunner 的 BlockJUnit4ClassRunner 类,它在 4.5 之后被采用。这里主要查看后者,先看 ParentRunner 对其接口 Runner 中方法 run 的实现:
@Override
public void run(final RunNotifier notifier) {
EachTestNotifier testNotifier = new EachTestNotifier(notifier,
getDescription());
try {
Statement statement = classBlock(notifier);
statement.evaluate();
} catch (AssumptionViolatedException e) {
testNotifier.addFailedAssumption(e);
} catch (StoppedByUserException e) {
throw e;
} catch (Throwable e) {
testNotifier.addFailure(e);
}
}
  其中,主要通过 classBlock 方法生成的 Statement 的 evaluate来进行调用,先看它是怎么生成的:
  protected Statement classBlock(final RunNotifier notifier) {
  Statement statement = childrenInvoker(notifier);
  if (!areAllChildrenIgnored()) {
  statement = withBeforeClasses(statement);
  statement = withAfterClasses(statement);
  statement = withClassRules(statement);
  }
  return statement;
  }
  这里主要的方法 childrenInvoker 会调用一个抽象的方法 protected abstract void runChild(T child, RunNotifier notifier);,它则是由子类来实现。另外看到的是,当测试类中的测试方法都没有被忽略的时候,则会使用 with对应的三个方法来添加其获取注解 BeforeClass,AfterClass,ClassRule对应的信息,并添加至其调用的 statement中。
  接下来查看 BlockJUnit4ClassRunner 的 runChild的实现:
  @Override
  protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
  Description description = describeChild(method);
  if (isIgnored(method)) {
  notifier.fireTestIgnored(description);
  } else {
  runLeaf(methodBlock(method), description, notifier);
  }
  }
  其中,若是添加了 @ignore的注解,则不会得到调用。看看 methodBlock方法都干了什么:
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);
statement = withAfters(method, test, statement);
statement = withRules(method, test, statement);
return statement;
}
  在这个 statement 的获取中,通过使用组合的方式,会这个 statement 添加 Before,After 及其它 Rule 的链式调用,后生成一个 statement 来返回。
  总结
  可以看出 Junit 是一个简单而又强大的库,不然不会经久不衰。其简单的实现但又强大的功能已经基本满足我们绝大多数的需求。但在这里还有一个疑问是不知道 Junit 是如何继承到 Android Studio 的 IDE 中,并是如何直接调用我们的测试方法或者测试类的?

上一页12下一页
软件测试工具 | 联系我们 | 投诉建议 | 诚聘英才 | 申请使用列表 | 网站地图
沪ICP备07036474 2003-2017 版权所有 上海泽众软件科技有限公司 Shanghai ZeZhong Software Co.,Ltd