Android测试四----TestRunner源码分析。

通过JUnit,我们可以指定需要运行的测试用例。

  public static Test suite() {
     suite.addTest(new MathTest("testAdd"));
     suite.addTest(new MathTest("testDivideByZero"));
     return suite;
  }

我们可以定义一个静态的suite方法,通过它来添加testXXX,然后返回一个TestSuite。


1.

正如TestRunner.java中提到的:

TestRunner expects the name of a TestCase class as argument.If this class defines a static <code>suite</code> method it
will be invoked and the returned test is run. Otherwise all  the methods starting with "test" having no arguments are run.
When the wait command line argument is given TestRunner waits until the users types RETURN.
TestRunner prints a trace as the tests are executed followed by a summary at the end.

然后我们就可以通过TestRunner的静态公有方法run方法去运行添加的测试用例:

	/**
	 * Runs a single test and collects its results.
	 * This method can be used to start a test run
	 * from your program.
	 * <pre>
	 * public static void main (String[] args) {
	 *    test.textui.TestRunner.run(suite());
	 * }
	 * </pre>
	 */
	static public TestResult run(Test test) {
		TestRunner runner= new TestRunner();
		return runner.doRun(test);
	}

生成一个TestRunner对象,然后调用doRun去运行suite()生成的测试集。


	/**
	 * Creates the TestResult to be used for the test run.
	 */
	protected TestResult createTestResult() {
		return new TestResult();
	}
	
	public TestResult doRun(Test test) {
		return doRun(test, false);
	}
	
	public TestResult doRun(Test suite, boolean wait) {
		TestResult result= createTestResult();
		result.addListener(fPrinter);
		long startTime= System.currentTimeMillis();
		suite.run(result);
		long endTime= System.currentTimeMillis();
		long runTime= endTime-startTime;
		fPrinter.print(result, runTime);

		pause(wait);
		return result;
	}
new了一个TestResult用来保存运行的结果;计算测试用例运行的时间;调用TestSuite的run方法去运行测试用例,并把结果放在result中。


2. TestSuite是如何去调用每个测试用例的?

	/**
	 * Runs the tests and collects their result in a TestResult.
	 */
	public void run(TestResult result) {
		for (Test each : fTests) {
	  		if (result.shouldStop() )
	  			break;
			runTest(each, result);
		}
	}

	public void runTest(Test test, TestResult result) {
		test.run(result);
	}
这里是通过一个for循环去遍历通过addTest添加进来的所有testcase。然后调用TestCase的run方法去运行测试用例。

TestCase.java

	/**
	 * Runs the test case and collects the results in TestResult.
	 */
	public void run(TestResult result) {
		result.run(this);
	}
	/**
	 * Runs the bare test sequence.
	 * @throws Throwable if any exception is thrown
	 */
	public void runBare() throws Throwable {
		Throwable exception= null;
		setUp();
		try {
			runTest();
		} catch (Throwable running) {
			exception= running;
		}
		finally {
			try {
				tearDown();
			} catch (Throwable tearingDown) {
				if (exception == null) exception= tearingDown;
			}
		}
		if (exception != null) throw exception;
	}
Android测试三中有讲到,这里其实最终是运行到runBare中去,然后在runTest中通过java反射机制运行测试用例。


说到这里,大家是不是想起来Android测试三中曾提到过TestSuite中包含多个TestSuite,那么这样的情况TestRunner是如何来处理呢?

这里有一个非常高明的手法,其实明白了也挺简单的。。。


TestSuite和TestCase都实现了Test接口

	public void run(TestResult result) {
		for (Test each : fTests) {
	  		if (result.shouldStop() )
	  			break;
			runTest(each, result);
		}
	}

	public void runTest(Test test, TestResult result) {
		test.run(result);
	}

当执行test.run(result)的时候,就会判断这个时候的test是TestSuite类型还是TestCase类型,如果是TestSuite类型那么就执行TestSuite的run(TestResult result);否则,那就是

TestCase类型,去执行该类型的run方法。看到这里,觉得自己又学到东西了,开源真好。。。


猜你喜欢

转载自blog.csdn.net/nitibu/article/details/48343411
今日推荐