unit4 下的所有的testcase都是在Runner下執行的, 可以將Runner理解為junit運行的容器, 默認情況下junit會使用JUnit4ClassRunner作為所有testcase的執行容器。
如果要定制自己的junit, 則可以實現自己的Runner,最簡單的辦法就是Junit4ClassRunner繼承, spring-test, unitils這些框架就是采用這樣的做法。
如在spring中是SpringJUnit4ClassRunner, 在unitils中是UnitilsJUnit4TestClassRunner, 一般我們的testcase都是在通過eclipse插件來執行的, eclipse的junit插件會在執行的時候會初始化指定的Runner。初始化的過程可以在ClassRequest中找到。
package org.junit.internal.runners;import java.lang.annotation.Annotation;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Collections;import java.util.Comparator;import java.util.Iterator;import java.util.List;import org.junit.runner.Description;import org.junit.runner.Runner;import org.junit.runner.manipulation.Filter;import org.junit.runner.manipulation.Filterable;import org.junit.runner.manipulation.NoTestsRemainException;import org.junit.runner.manipulation.Sortable;import org.junit.runner.manipulation.Sorter;import org.junit.runner.notification.Failure;import org.junit.runner.notification.RunNotifier;import org.junit.runners.BlockJUnit4ClassRunner;/** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be * removed in the next release. Please use * {@link BlockJUnit4ClassRunner} in place of * {@link JUnit4ClassRunner}. * * This may disappear as soon as 1 April 2009 */@Deprecatedpublic class JUnit4ClassRunner extends Runner implements Filterable, Sortable{ private final ListfTestMethods; private TestClass fTestClass; //將要測試的TestCase實例Class對象傳入 public JUnit4ClassRunner(Class klass) throws InitializationError { fTestClass = new TestClass(klass); fTestMethods = getTestMethods(); //對要進行測試的方法展開驗證 validate(); } //獲取@test的方法List protected ListgetTestMethods() { return fTestClass.getTestMethods(); } //對要進行測試的方法展開驗證 protected void validate() throws InitializationError { MethodValidator methodValidator = new MethodValidator(fTestClass); (); (); } @Override public void run(final RunNotifier notifier) { new ClassRoadie(notifier, fTestClass, getDescription(), new Runnable() { public void run() { runMethods(notifier); } }).runProtected(); } protected void runMethods(final RunNotifier notifier) { for (Method method : fTestMethods) invokeTestMethod(method, notifier); } @Override public Description getDescription() { Description spec = (getName(), classAnnotations()); ListtestMethods = fTestMethods; for (Method method : testMethods) (methodDescription(method)); return spec; } protected Annotation[] classAnnotations() { return fTestClass.getJavaClass().getAnnotations(); } protected String getName() { return getTestClass().getName(); } protected Object createTest() throws Exception { return getTestClass().getConstructor().newInstance(); } protected void invokeTestMethod(Method method, RunNotifier notifier) { Description description = methodDescription(method); Object test; try { test = createTest(); } catch(InvocationTargetException e) { testAborted(notifier, description, ()); return; } catch(Exception e) { testAborted(notifier, description, e); return; } TestMethod testMethod = wrapMethod(method); new MethodRoadie(test, testMethod, notifier, description).run(); } private void testAborted(RunNotifier notifier, Description description, Throwable e) { (description); (new Failure(description, e)); (description); } protected TestMethod wrapMethod(Method method) { return new TestMethod(method, fTestClass); } protected String testName(Method method) { return method.getName(); } protected Description methodDescription(Method method) { return Description.createTestDescription(getTestClass().getJavaClass(), testName(method), testAnnotations(method)); } protected Annotation[] testAnnotations(Method method) { return method.getAnnotations(); } public void filter(Filter filter) throws NoTestsRemainException { for (Iteratoriter = (); ();) { Method method = (); if (!(methodDescription(method))) (); } if (()) throw new NoTestsRemainException(); } public void sort(final Sorter sorter) { (fTestMethods, new Comparator() { public int compare(Method o1, Method o2) { return sorter.compare(methodDescription(o1), methodDescription(o2)); } }); } protected TestClass getTestClass() { return fTestClass; }}
類
不同于上一節提到的類
package org.junit.internal.runners;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Collections;import java.util.List;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import org.junit.Test;import org.junit.runners.BlockJUnit4ClassRunner;/** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be * removed in the next release. Please use * {@link BlockJUnit4ClassRunner} in place of * {@link JUnit4ClassRunner}. */@Deprecatedpublic class TestClass{ private final Class fClass; public TestClass(Class klass) { fClass = klass; } public ListgetTestMethods() { return getAnnotatedMethods(); } ListgetBefores() { return getAnnotatedMethods(); } ListgetAfters() { return getAnnotatedMethods(); } public ListgetAnnotatedMethods(Class annotationClass) { Listresults = new ArrayList(); for (Class eachClass : getSuperClasses(fClass)) { Method[] methods = (); for (Method eachMethod : methods) { Annotation annotation = (annotationClass); if (annotation != null && !isShadowed(eachMethod, results)) (eachMethod); } } if (runsTopToBottom(annotationClass)) (results); return results; } private boolean runsTopToBottom(Class annotation) { return () || (); } private boolean isShadowed(Method method, Listresults) { for (Method each : results) { if (isShadowed(method, each)) return true; } return false; } private boolean isShadowed(Method current, Method previous) { if (!().equals(())) return false; if (().length != ().length) return false; for (int i = 0; i < ().length; i++) { if (!()[i].equals(()[i])) return false; } return true; } private List<Class> getSuperClasses(Class testClass) { ArrayList<Class> results = new ArrayList<Class>(); Class current = testClass; while (current != null) { (current); current = (); } return results; } public Constructor getConstructor() throws SecurityException, NoSuchMethodException { return fClass.getConstructor(); } public Class getJavaClass() { return fClass; } public String getName() { return fClass.getName(); }}
類
用于在 類當中進行方法驗證
package org.junit.internal.runners;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.ArrayList;import java.util.List;import org.junit.After;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import org.junit.Test;import org.junit.runners.BlockJUnit4ClassRunner;/** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be * removed in the next release. Please use * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}. */@Deprecatedpublic class MethodValidator { private final ListfErrors= new ArrayList(); private TestClass fTestClass; //類中 //validate()方法中調用該構造函數-----第一步 public MethodValidator(TestClass testClass) { fTestClass = testClass; } public void validateInstanceMethods() { validateTestMethods(After.class, false); validateTestMethods(, false); validateTestMethods(, false); Listmethods= (); if (() == 0) (new Exception("No runnable methods")); } public void validateStaticMethods() { validateTestMethods(, true); validateTestMethods(, true); } //Junit4ClassRunner類中調用第二步 public ListvalidateMethodsForDefaultRunner() { //校驗無參構造方法 validateNoArgConstructor(); //校驗注解方法 validateStaticMethods(); validateInstanceMethods(); return fErrors; } //Junit4ClassRunner類中第三步 public void assertValid() throws InitializationError { if (!()) throw new InitializationError(fErrors); } public void validateNoArgConstructor() { try { (); } catch (Exception e) { (new Exception("Test class should have public zero-argument constructor", e)); } } //校驗要測試的方法 是否靜態方法、是否public方法、是否返回值void、是否無參數 //@param annotation 要測試的annotation類 //@param isStatic 是否要求靜態方法 private void validateTestMethods(Class annotation,boolean isStatic) { Listmethods= (annotation); for (Method each : methods) { if ((()) != isStatic) { String state= isStatic ? "should" : "should not"; (new Exception("Method " + () + "() " + state + " be static")); } if (!(().getModifiers())) (new Exception("Class " + ().getName() + " should be public")); if (!(())) (new Exception("Method " + () + " should be public")); if (() != ) (new Exception("Method " + () + " should be void")); if (().length != 0) (new Exception("Method " + () + " should have no parameters")); } }}
泰州潤揚網絡策劃服務有限公司專注泰州網絡公司,泰州網站建設,
從域名選擇-工信部備案-首頁風格確認-內頁欄目設置-內頁框架設計-后臺搭建管理-新聞定期發布-定期優化設置-效果統計-月度反饋。
泰州網站建設,泰州網絡推廣,交給我們:放心、省心。
我們不做第一,只做唯一,以真誠服務、實在做事的態度為您做好交給我們的每一項工作。
泰州網絡公司、泰州網站建設、泰州網絡策劃、泰州APP開發、泰州網絡推廣、泰州微信營銷、泰州百度信息流推廣,泰州軟件開發,泰州百度愛采購
本文由:潤揚網絡策劃編輯部小編 整理發布、翻版必究 ,如涉及各項侵權請及時與我們聯系修改:13961039617 合作熱線:19825583557 我們期待與您合作