`
石建武
  • 浏览: 74937 次
  • 性别: Icon_minigender_1
  • 来自: 陕西
社区版块
存档分类
最新评论

测试工作(1.1 -- 补Junit3执行流程)

阅读更多
补:Junit3执行流程分析

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更多体现的是优秀的设计思想。可惜自己现在还没有领悟到这步,只能简单的对整个的执行流程有初步的认识。继续努力。
分享到:
评论

相关推荐

    jenkins-2.277.4-1.1-plugins.tar.gz

    - 测试工具:如JUnit、Selenium,用于自动化测试。 - 部署工具:如Docker、JClouds,用于应用部署。 - 代码质量检查:如Checkstyle、PMD,用于代码质量管理。 - 持续交付/部署:如Pipeline,用于定义和执行持续...

    EShop网上商城系统.V1.1 - 基本流程.zip

    《EShop网上商城系统.V1.1 - 基本流程》是一个基于Java技术的实践学习案例,旨在帮助开发者理解并掌握如何构建一个简单的电子商务平台。这个系统通过控制台模拟了用户在商城中的购物体验,从浏览商品到完成支付的...

    来自ZTE(中兴)的单元测试资料-----下载不扣分,回帖加1分,欢迎下载,童叟无欺。

    【单元测试】是软件开发过程中的重要环节,它主要用于验证代码的各个独立模块是否按预期工作。本资料包由ZTE(中兴)提供,包含了关于单元测试的多个文档和教程,适合Java开发者学习和参考。 《JAVA单元测试(公司...

    apache-ant-dotnet-1.1-src.tar.gz

    1. **任务驱动**:Ant的工作基于一系列的任务(tasks),每个任务执行特定的操作,如编译源代码、打包JAR文件或运行测试。 2. **依赖管理**:Ant可以跟踪项目中的文件依赖,确保在构建过程中按照正确的顺序执行操作...

    测试员速成-单元测试

    - **白盒测试**:通过测试内部结构或工作流程来查找代码中的错误。 - **黑盒测试**:仅基于程序的功能需求规格说明,完全不考虑程序内部结构和内部特性。 ##### 2.2 测试的内容 单元测试通常包括以下内容: - **...

    activiti工作流所需jar包(完整)

    8. **测试和支持库**:开发过程中可能还包括一些测试和工具库,如`junit-*.jar`用于单元测试,`commons-lang3-*.jar`提供通用语言功能,`commons-io-*.jar`处理I/O操作。 综上所述,这个压缩包提供的jar文件涵盖了...

    openjdk-18.0.1.1(openjdk-18.0.1.1_macos-x64_bin.tar.gz)

    开发过程中,利用内置的 Javadoc 和 JUnit 支持,可以方便地编写、测试和调试 Java 代码。 **6. 性能优化** OpenJDK 不断优化性能,18.0.1.1 版本可能包含了一些针对 macOS 平台的特定优化。开发者可以使用 `-XX:+...

    接口测试白皮书--淘宝(中国)软件有限公司

    日常工作中,接口测试的工作流程可能更侧重于: - 定期维护测试环境; - 更新和优化测试用例; - 执行定期的回归测试; - 监控持续集成过程中的异常情况。 #### 5. 接口测试的技术简介 本节将简要介绍几种常用的...

    半小时轻松搞定 JUnit4

    相比于JUnit3,JUnit4最大的改进在于引入了注解(Annotations),这使得测试代码变得更加简洁且易于维护。 **1.1 注解的引入** - **注解简介**:在JUnit4中,注解是一种特殊的Java语法特性,用于描述源代码的元...

    Junit的使用介绍

    - **持续集成**:将JUnit测试整合到持续集成流程中,可以在每次提交代码后自动运行测试,及时发现潜在问题。 **1.2 环境配置** 本节将详细介绍如何在Eclipse环境中配置JUnit测试环境。 **1.2.1 下载JUnit包** ...

    ant-antunit-1.1.jar.zip

    AntUnit借鉴了JUnit的模式,但将其集成到Ant的构建流程中,允许开发者在构建过程中运行单元测试,确保代码质量。AntUnit的任务可以嵌入到Ant构建脚本中,这样每次构建时,测试都会自动执行,从而及时发现潜在的问题...

    webservice测试工具

    - 自动化测试:可以创建和执行预定义的测试套件,减少手动工作。 - 请求构造器:允许用户构建和编辑SOAP或RESTful请求,包括设置HTTP头、查询参数等。 - 结果分析:显示详细的响应信息,包括HTTP状态码、响应时间...

    junit使用指南及作业规范

    JUnit属于白盒测试类型,允许开发者编写测试用例来验证程序各个部分是否按照预期工作。 **项目主页**:http://www.junit.org/ **下载地址**: - https://github.com/KentBeck/junit/downloads - ...

    自动化测试知识ppt包含qtp实践

    ##### 1.1 为什么使用自动化测试? - **快速(Fast)**:自动化测试能够显著减少测试时间,尤其是在频繁迭代的环境中。 - **可靠(Reliable)**:通过自动化测试,可以避免人为错误,提高测试结果的准确性。 - **可...

Global site tag (gtag.js) - Google Analytics