您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 > junit
Junit使用及其原理分析
作者:alighters 發(fā)布時(shí)間:[ 2016/9/13 10:53:28 ] 推薦標(biāo)簽:單元測試 Junit

  其會(huì)調(diào)到一個(gè) run(Runner runner) 的方法,而 Runner 是一個(gè)抽象類,其實(shí)現(xiàn)針對(duì)不同的平臺(tái)又有好多個(gè)。這里主要提及兩個(gè),一個(gè)是 Junit4ClassRunner,它是 4.4 版本及之前的采用的,之后被廢棄掉了,而采用了繼承實(shí)現(xiàn)抽象類 ParentRunner 的 BlockJUnit4ClassRunner 類,它在 4.5 之后被采用。這里主要查看后者,先看 ParentRunner 對(duì)其接口 Runner 中方法 run 的實(shí)現(xiàn):
@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來進(jìn)行調(diào)用,先看它是怎么生成的:
  protected Statement classBlock(final RunNotifier notifier) {
  Statement statement = childrenInvoker(notifier);
  if (!areAllChildrenIgnored()) {
  statement = withBeforeClasses(statement);
  statement = withAfterClasses(statement);
  statement = withClassRules(statement);
  }
  return statement;
  }
  這里主要的方法 childrenInvoker 會(huì)調(diào)用一個(gè)抽象的方法 protected abstract void runChild(T child, RunNotifier notifier);,它則是由子類來實(shí)現(xiàn)。另外看到的是,當(dāng)測試類中的測試方法都沒有被忽略的時(shí)候,則會(huì)使用 with對(duì)應(yīng)的三個(gè)方法來添加其獲取注解 BeforeClass,AfterClass,ClassRule對(duì)應(yīng)的信息,并添加至其調(diào)用的 statement中。
  接下來查看 BlockJUnit4ClassRunner 的 runChild的實(shí)現(xiàn):
  @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的注解,則不會(huì)得到調(diào)用。看看 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;
}
  在這個(gè) statement 的獲取中,通過使用組合的方式,會(huì)這個(gè) statement 添加 Before,After 及其它 Rule 的鏈?zhǔn)秸{(diào)用,后生成一個(gè) statement 來返回。
  總結(jié)
  可以看出 Junit 是一個(gè)簡單而又強(qiáng)大的庫,不然不會(huì)經(jīng)久不衰。其簡單的實(shí)現(xiàn)但又強(qiáng)大的功能已經(jīng)基本滿足我們絕大多數(shù)的需求。但在這里還有一個(gè)疑問是不知道 Junit 是如何繼承到 Android Studio 的 IDE 中,并是如何直接調(diào)用我們的測試方法或者測試類的?

上一頁12下一頁
軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd