浏览 1794 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-10-30
1、TestRunner 入口点。生成TestRunner实例,首先执行TestRunner的main方法。 public static void main(String args[]) { TestRunner aTestRunner= new TestRunner(); try { //args参数指定的测试类的名称 TestResult r= aTestRunner.start(args); } catch(Exception e) {} } 2、构造生成TestSuite 。suite的概念在于,一个测试类存在多个测试方法,将所有的测试方法抽取存储于一个集合,遍历执行对应操作。 /** * Starts a test run. Analyzes the command line arguments and runs the given * test suite. */ public TestResult start(String args[]) throws Exception { String testCase= args[i]; // 赋值“测试类”名称 String method= ""; boolean wait= false; try { //判断是否执行单个方法的测试 if (!method.equals("")) return runSingleMethod(testCase, method, wait); //构造生成TestSuite Test suite= getTest(testCase); //执行测试 return doRun(suite, wait); } catch (Exception e) {} } 3、TestRunner继承BaseTestRunner,getTest()是BaseTestRunner定义的一个模版方法 /** * Returns the Test corresponding to the given suite. This is * a template method, subclasses override runFailed(), clearStatus(). */ public Test getTest(String suiteClassName) { Class testClass= null; try { //根据类名加载“测试类” testClass= loadSuiteClass(suiteClassName); } catch (ClassNotFoundException e) {} catch(Exception e) {} Method suiteMethod= null; try { //Junit3中可以自定义suite()方法,根据反射尝试获取suite方法对于的Method类 suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]); } catch(Exception e) { // try to extract a test suite automatically clearStatus(); //若不存在suite方法,则构造Junit自动构造测试方法集合suite,返回。 return new TestSuite(testClass); } } 4、正式构造TestSuite /** * Constructs a TestSuite from the given class. Adds all the methods * starting with "test" as test cases to the suite. */ public TestSuite(final Class theClass) { fName= theClass.getName(); Class superClass= theClass; Vector names= new Vector(); //遍历方法,判断是否为“需要测试”方法,构造 while (Test.class.isAssignableFrom(superClass)) { Method[] methods= superClass.getDeclaredMethods(); for (int i= 0; i < methods.length; i++) { addTestMethod(methods[i], names, theClass); } //获取到“父”类,一层层的向上遍历,找寻“Test”方法,添加到TestSuite superClass= superClass.getSuperclass(); } if (fTests.size() == 0) addTest(warning("No tests found in "+theClass.getName())); } private void addTestMethod(Method m, Vector names, Class theClass) { String name= m.getName(); //判断出来,添加进MethodName的集合names if (names.contains(name)) return; if (! isPublicTestMethod(m)) { if (isTestMethod(m)) addTest(warning("Test method isn't public: "+m.getName())); return; } names.addElement(name); // createTest()根据 theClass与name(即方法名),为每个方法构造独立的TestCase的实例,指定TestCase的fName为name值,存储此TestCase于TestSuite //就是说 :一个类有很多的需要测试方法,为每一个测试方法生成一个自身的实例,向上转型为TestCase,给TestCase的属性fName赋值为对应测试方法的名称 addTest(createTest(theClass, name)); } 5、准备执行测试 public TestResult doRun(Test suite, boolean wait) { TestResult result= createTestResult(); //TestResult存储所有的执行结果信息 result.addListener(fPrinter); //添加监听器 long startTime= System.currentTimeMillis(); suite.run(result); //实际执行 long endTime= System.currentTimeMillis(); long runTime= endTime-startTime; fPrinter.print(result, runTime); return result; } 6、开始执行 /** * Runs the tests and collects their result in a TestResult. */ public void run(TestResult result) { //遍历执行所有的测试 for (Enumeration e= tests(); e.hasMoreElements(); ) { if (result.shouldStop() ) break; Test test= (Test)e.nextElement(); runTest(test, result); } } /** * Runs the bare test sequence. * @exception Throwable if any exception is thrown */ public void runBare() throws Throwable { Throwable exception= null; setUp(); //每个测试方法执行前执行的setUp() try { runTest(); //执行测试方法 } catch (Throwable running) { exception= running; } finally { try { tearDown();//tearDown写在finally不论怎么样,在测试执行结束都会执行 } catch (Throwable tearingDown) { if (exception == null) exception= tearingDown; } } if (exception != null) throw exception; } 7、通过反射执行实际的测试方法 /** * Override to run the test and assert its state. * @exception Throwable if any exception is thrown */ protected void runTest() throws Throwable { assertNotNull(fName); // Some VMs crash when calling Method runMethod= null; try { // use getMethod to get all public inherited // methods. getDeclaredMethods returns all // methods of this class but excludes the // inherited ones. //根据反射取得对应方法的Method类 runMethod= getClass().getMethod(fName, (Class[])null); } catch (NoSuchMethodException e) {} try { //通过反射实际执行测试方法 runMethod.invoke(this, (Object[])new Class[0]); } catch (InvocationTargetException e) {} } 8、实际的测试方法 public void testAdd() { Arithmetic a = new Arithmetic(); int expected = 3; assertEquals("失败", expected, a.add(1, 2)); } 9、执行Assert /** * Asserts that two ints are equal. If they are not * an AssertionFailedError is thrown with the given message. */ static public void assertEquals(String message, int expected, int actual) { assertEquals(message, new Integer(expected), new Integer(actual)); } 10、最终的错误的捕捉,以及测试结果打印。通过TestResult实现。 总结 :觉得和很多人说的那样,Junit更多体现的是优秀的设计思想。可惜自己现在还没有领悟到这步,只能简单的对整个的执行流程有初步的认识。继续努力。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |