一、为何须要单元测试
数组
软件开发的标准过程包括如下几个阶段:[需求分析阶段]、[设计阶段]、[实现阶段]、[测试阶段]、[发布]。其中测试阶段经过人工或者自动手段来运行或测试某个系统的过程,其目的在于检验它是否知足规定的需求或弄清预期结果与实际结果之间的差异。按照软件工程思想,软件测试能够分为单元测试、集成测试、功能测试、系统测试等。功能测试和系统测试通常来讲是测试人员的职责,但单元测试和集成则必须由开发人员保证。框架
1)单元测试:单元测试时开发者编写的一小段代码,用于检验目标代码的一个很小的、很明确的功能是否正确。一般而言,一个单元测试用于判断某个特定条件或特定场景下某个特定函数的行为。在一个状况下,一个功能模块每每会调用其余功能模块完成某项功能,如业务层的业务类可能会调用多个DAO完成某项任务。对某个功能模块进行单元测试时,咱们但愿屏蔽对外功能模块的依赖,以便将焦点放在目标功能模块的测试上。这时模拟对象是最有力的工具,它依据外在模块的接口模拟特定操做行为,这样单元测试就能够在假设关联模块正确工做的状况下验证本模块逻辑的正确性了。函数
2)集成测试:集成测试是在功能模块开发完成之后,为验证功能模块之间匹配调用的正确性而进行的测试。在单元测试时,每每须要经过模拟对象屏蔽外在模块的依赖,而集成测试偏偏是要验证模块之间集成后的正确性。工具
3)功能测试:功能测试主要检查已实现的软件是否知足了需求规格说明中肯定了的各类需求,以及软件功能是否彻底、正确。单元测试
4)系统测试主要对已经通过肯定的软件归入实际运行环境中,与其余系统成份组合在一块儿进行测试。测试
二、测试的好处优化
1)是软件质量最简单、最有效的保证;ui
2)是目标代码最清晰、最有效的文档;设计
3)能够优化目标代码的设计;对象
4)是代码重构的保障;
5)是回归测试和持续集成的基石。
三、单元测试基本概念
1)被测系统:SUT(System Under Test)
被测系统表示正在被测试的系统,目的是测试系统可否正确操做。软件系统测试的一个特例是对应用软件的测试,称为被测应用程序(AUT,Application Under Test)。SUT也代表软件已经到了成熟期,由于系统测试在测试周期中是集成测试的后一阶段。
2)测试替身:Test Double
在单元测试时,使用Test Double减小对被测对象的依赖,使得测试更加单一。同时,让测试案例执行的时间更短,运行更加稳定,同时能对SUT内部的输入输出进行验证,让测试更加完全深刻。可是,Test Double也不是万能的,Test Double不能被过分使用,由于实际交付的产品是使用实际对象的,过分使用Test Double会让测试变得愈来愈脱离实际。
要理解测试替身,须要了解一下Dummy Object, Test Stub,Test Spy, Fake Object这几个概念。
a、Dummy Object:Dummy Object泛指在测试中必须传入的对象,而传入的这些对象实际上并不会产生任何做用,仅仅是为了可以调用被测对象儿必须传入的一个东西。
b、Test Stub:测试桩是用来接受SUT内部的间接输入(indirect inputs),并返回特定的值给SUT。能够理解Test Stub是在SUT内部打的一个桩,能够按照咱们的要求返回特定的内容给SUT,Test Stub的交互彻底在SUT内部,所以,它不会返回内容给测试案例,也不会对SUT内部的输入进行验证。
c、Test Spy:Test Spy像一个间谍,安插在了SUT内部,专门负责将SUT内部的间接输出(indirect outputs)传到外部。它的特色是将内部的间接输出返回给测试用例,由测试案例进行验证,Test Spy只负责获取内部情报,并把情报发出去,不负责验证情报的正确性。
d、Mock Object:Mock Object和Test Spy有相似的地方,它也是安插在SUT内部,获取到SUT内部的间接输出(indirect outputs),不一样的是,Mock Object还负责对情报(intelligence)进行验证,总部(外部的测试案例)信任Mock Object的验证结果。
e、Fake Object:常常,咱们会把Fake Object和Test Stub搞混,由于它们都和外部没有交互,对内部的输入输出也不进行验证。不一样的是,Fake Object并不关注SUT内部的间接输入(indirect inputs)或间接输出(indirect outputs),它仅仅是用来替代一个实际的对象,而且拥有几乎和实际对象同样的功能,保证SUT可以正常工做。实际对象过度依赖外部环境,Fake Object能够减小这样的依赖。
3)测试夹具:Test Fixture
测试夹具(Fixture),就是测试运行程序(test runner)会在测试方法以前自动初始化、回收资源的工做。在Junit4中经过@Before来初始化字段和配置环境,经过@After来进行注销。这能够保证各个测试之间的独立性和互不干扰,可是效率低。
一个测试用例能够包含若干个打上@Test注解的测试方法,测试用例测试一个或多个类API接口的正确性,固然在调用类API时,须要事先建立这个类的对象及一些关联的对象,这组对象就称为测试夹具(Fixture),至关于测试用例的“工做对象”。
4)测试用例:Test Case
在JUnit3中,测试方法都必须以test为前缀,且必须时public void的,JUnit4之后,就没有这个限制,只要在每一个测试方法标注@Test注解,方法签名能够是任何取名。能够在一个测试用例类中添加多个测试方法,运行器为每一个方法生成一个测试用例实例并分别运行。
5)测试套件:Test Suite
经过TestSuite对象将多个测试用例组装成一个测试套件,则测试套件批量运行。须要特别指出的是,能够把一个测试套件整个添加到两一个测试套件中,就像小箩筐装进大箩筐变成一个筐同样。
套件机制用于将测试从逻辑上分组并将这些测试做为一个单元测试来运行。Junit4为了替代老版本的套件测试,套件被两个新注解替代:@RunWith、@SuteClasses。经过@RunWith指定一个特殊的运行器,即Suite.class套件运行器,并经过@SuiteClasses注解,将须要进行测试的类列表做为参数传入。
建立步骤说明:
* 建立一个空类做为测试套件的入口(这个空类必须使用public修饰符,并且存在无参构造函数);
* 将@RunWith、@SuiteClasses注释修饰这个空类;
* 把Suite.class做为参数传入@RunWith注释,以提示Junit将此类指定为运行器;
* 将须要测试的类组成数组做为@SuiteClasses的参数。
6)断言:Assertions
断言(assertions)是测试框架里面的若干个方法,用来判断某个语句的结果是否为真或判断是否与预期相符。