相关概念
Ø JUnit是一个开发源代码的Java测试框架用于编写和运行可重复的测试它是用于单元测试框架体系xUnit的一个实例(用于java语言)主要用于白盒测试回归测试
Ø 白盒测试把测试对象看作一个打开的盒子程序内部的逻辑结构和其他信息对测试人
员是公开的
Ø 回归测试软件或环境的修复或更正后的再测试自动测试工具对这类测试尤其有用
Ø 单元测试最小粒度的测试以测试某个功能或代码块一般由程序员来做因为它需要知道内部程序设计和编码的细节
单元测试
单元测试的好处
Ø 提高开发速度测试是以自动化方式执行的提升了测试代码的执行效率
Ø 提高软件代码质量它使用小版本发布至集成便于实现人员除错同时引入重构概念让代码更干净和富有弹性
Ø 提升系统的可信赖度它是回归测试的一种支持修复或更正后的再测试可确保代码的正确性
单元测试的针对对象
Ø 面向过程的软件开发针对过程
Ø 面向对象的软件开发针对对象
Ø 可以做类测试功能测试接口测试(最常用于测试类中的方法)
单元测试工具和框架
目前的最流行的单元测试工具是xUnit系列框架常用的根据语言不同分为JUnit(java)CppUnit(C++)DUnit (Delphi ))PhpUnit(Php )等等
单元测试框架的第一个和最杰出的应用就是由Erich Gamma (《设计模式》的作者)和Kent Beck(XP(Extreme Programming)的创始人 )提供的开放源代码的JUnit
Junit入门简介
JUnit的好处和JUnit测试编写原则
使用JUnit的好处
Ø 可以使测试代码与产品代码分开
Ø 针对某一个类的测试代码通过较少的改动便可以应用于另一个类的测试
Ø 易于集成到测试人员的构建过程中JUnit和Ant的结合可以实施增量开发
Ø JUnit是公开源代码的可以进行二次开发
Ø 可以方便地对JUnit进行扩展
JUnit测试编写原则
Ø 简化测试的编写这种简化包括测试框架的学习和实际测试单元的编写
Ø 使测试单元保持持久性
Ø 可以利用既有的测试来编写相关的测试
JUnit的特征
Ø 使用断言方法判断期望值和实际值差异返回Boolean值
Ø 测试驱动设备使用共同的初始化变量或者实例
Ø 测试包结构便于组织和集成运行
Ø 支持图型交互模式和文本交互模式
JUnit框架组成
Ø 对测试目标进行测试的方法与过程集合可称为测试用例(TestCase)
Ø 测试用例的集合可容纳多个测试用例(TestCase)将其称作测试包(TestSuite)
Ø 测试结果的描述与记录(TestResult)
Ø 测试过程中的事件监听者(TestListener)
Ø 每一个测试方法所发生的与预期不一致状况的描述称其测试失败元素(TestFailure)
Ø JUnit Framework中的出错异常(AssertionFailedError)
JUnit框架是一个典型的Composite模式TestSuite可以容纳任何派生自Test的对象当调用TestSuite对象的run()方法是会遍历自己容纳的对象逐个调用它们的run()方法
JUnit中常用的接口和类
Ø Test接口运行测试和收集测试结果
Test接口使用了Composite设计模式是单独测试用例(TestCase)聚合测试模式(TestSuite)及测试扩展(TestDecorator)的共同接口 它的public int countTestCases()方法用来统计测试时有多少个TestCase另外一个方法就是public voidrun( TestResult )TestResult是实例接受测试结果 run方法执行本次测试
Ø TestCase抽象类定义测试中固定方法
TestCase是Test接口的抽象实现(不能被实例化只能被继承)其构造函数TestCase(string name)根据输入的测试名称name创建一个测试实例由于每一个TestCase在创建时都要有一个名称若测试失败了便可识别出是哪个测试失败
TestCase类中包含的setUp()tearDown()方法
setUp()方法集中初始化测试所需的所有变量和实例并且在依次调用测试类中的每个测试方法之前再次执行setUp()方法
tearDown()方法则是在每个测试方法之后释放测试程序方法中引用的变量和实例
开发人员编写测试用例时只需继承TestCase来完成run方法即可然后JUnit获得测试用例执行它的run方法把测试结果记录在TestResult之中
Ø Assert静态类一系列断言方法的集合
Assert包含了一组静态的测试方法用于期望值和实际值比对是否正确即测试失败Assert类就会抛出一AssertionFailedError异常JUnit测试框架将这种错误归入Failes并加以记录同时标志为未通过测试如果该类方法中指定一个String类型的传参则该参数将被做为AssertionFailedError异常的标识信息告诉测试人员改异常的详细信息
JUnit 提供了大类组断言方法包括基础断言数字断言字符断言布尔断言对象断言其中assertEquals(Object expctedObject actual)内部逻辑判断使用equals()方法这表明断言两个实例的内部哈希值是否相等时最好使用该方法对相应类实例的值进行比较
而assertSame(Object expectedObject actual)内部逻辑判断使用了Java运算符==这表明该断言判断两个实例是否来自于同一个引用(Reference)最好使用该方法对不同类的实例的值进行比对
asserEquals(String messageString expectedString actual)该方法对两个字符串进行逻辑比对如果不匹配则显示着两个字符串有差异的地方
ComparisonFailure类提供两个字符串的比对不匹配则给出详细的差异字符
Ø TestSuite测试包类??多个测试的组合
TestSuite类负责组装多个Test Cases待测得类中可能包括了对被测类的多个测试而TestSuit负责收集这些测试使我们可以在一个测试中完成全部的对被测类的多个测试TestSuite类实现了Test接口且可以包含其它的TestSuites它可以处理加入Test时的所有抛出的异常
TestSuite处理测试用例有个规约(否则会被拒绝执行测试)
⊃ 测试用例必须是公有类(Public)
⊃ 用例必须继承与TestCase类
⊃ 测试用例的测试方法必须是公有的( Public )
⊃ 测试用例的测试方法必须被声明为Void
⊃ 测试用例中测试方法的前置名词必须是test
⊃ 测试用例中测试方法误任何传递参数
Ø TestResult结果类和其它类与接口
TestResult结果类集合了任意测试累加结果通过TestResult实例传递个每个测试的Run()方法TestResult在执行TestCase是如果失败会异常抛出
TestListener接口是个事件监听规约可供TestRunner类使用它通知listener的对象相关事件方法包括测试开始startTest(Test test)测试结束endTest(Test test)错误增加异常addError(Test testThrowable t)和增加失败addFailure(Test testAssertionFailedError t)
TestFailure失败类是个失败状况的收集类解释每次测试执行过程中出现的异常情况其toString()方法返回失败状况的简要描述
Eclipse中JUnit的使用
测试对于保证软件开发质量有着非常重要的作用单元测试更是必不可少JUnit是一个非常强大的单元测试包可以对一个/多个类的单个/多个方法测试还可以将不同的TestCase组合成TestSuit使测试任务自动化
Eclipse同样集成了JUnit可以非常方便地编写TestCaseEclipse自带了一个JUnit的插件不用安装就可以在你的项目中开始测试相关的类并且可以调试你的测试用例和被测试类
Eclipse中JUint使用步骤
以下步骤环境为Eclipse SDK 及JUnit
Ø 新建一个测试用例或选择已有的所想测试的JAVA文件点击File>New>…菜单项或右击文件在弹出的New对话框中选择JUnit Test Case就进入New JUnit Test Case对话框
Ø 在New JUnit TestCase对话框填写相应的栏目主要有Name(测试用例名)SuperClass(若JUnit的版本是则测试的超类一般默认为junitframeworkTestCase 若JUnit版本是JUnit 则默认超类为javalangObject)Class Under Test(被测试的类)Source Folder(测试用例保存的目录)Package(测试用例包名)及是否自动生成mainsetUptearDown方法在此一般填写NAME及选上复选上setUpt和teardown即可
Ø 点击Next>按钮则进入Test Methods在此你可以直接勾选你想测试的被测试类的方法Eclipse将自动生成与被选方法相应的测试方法点击Fishish按钮后一个测试用例就创建好了
Ø 编写完成测试用例后点击Run按钮就可以看到运行结果了
补充要使用JUnit您必须首先将JUnit JAR保存在项目的Build路径上并创建一个测试类将JUnit保存在项目的Build路径上的步骤为
右击项目—>选择菜单底部的Properties选择Java Build Path—>选择Libraries—>点击Add Variable按钮—>查看已有的列表中有无JUnit文件若没有则点击Configure Variable—>New按钮输入JUNIT_LIB作为变量名称编辑该变量并指向解压后的JUnit目录中的一个名为JUnitjar的文件—>然后在选择刚才添加的jar文件依次点击OK即可
Eclipse中JUnit应用示例
下面我们作一个在Eclipse中利用JUnit对HelloWorld的测试 测试方法
Ø HelloWorldsayHello()是否执行正常并且结果也符合要求
Ø HelloWorldadd()方法是否与我们预期一样执行
下一步我们准备对这两个方法进行测试确保功能正常选中HelloWorldjava右键点击选择New>JUnit Test Case
进入下面这个页面在此诸多栏目已经填好即是这个需要测试的文件的相关信息若是想在测试完之后即删除测试文件也可更改路径(本机在Eclipse已有的JUnit的基础上又添加了一个新版本JUnit)
点击Next进入Test Methods在此选择所要测试的方法sayHello及add
点击Finish最后编写完成测试用例代码如下
直接运行Run>Run As>JUnit Test就可以看到JUnit测试结果
绿色表示测试通过只要有个测试未通过就会显示红色并列出未通过测试的方法
后记
从上面的来看JUnit的使用并不很难但关键就是最后一步完成测试码即编写TestCase要编写一个好的TestCase却并非易事一个不好的TestCase往往是既浪费了时间也起不了实际的作用相反一个好的TestCase不仅可以很好的指出代码中存在的问题而且也可以作为代码更准确的文档同时还在持续集成的过程中起非常重要的作用我们在作测试写TestCase时需要注意的几点
Ø 测试的独立性一次只测试一个对象方便定位出错的位置这有两层意思一个TestCase只测试一个对象一个TestMethod只测试这个对象中的一个方法
Ø 给测试方法一个合适的名字 一般取名为原来的方法名后加一个Test
Ø 在assert函数中给出失败的原因如assertTrue( … should be true ……)方便查错在这个例子中如果无法通过assertTrue那么给出的消息将被显示在junit中每个assert函数都有第一个参数是出错时显示消息的函数原型
Ø 测试所有可能引起失败的地方如一个类中频繁改动的函数对于那些仅仅只含有getter/setter的类如果是由IDE(如Eclipse)产生的则可不测如果是人工写那么最好测试一下
Ø 在setUp和tearDown中的代码不应该是与测试方法相关的而应该是全局相关的如针对与测试方法A和B在setUp和tearDown中的代码应该是A和B都需要的代码
Ø 测试代码的组织相同的包不同的目录这样测试代码可以访问被测试类的protected变量/方法方便测试代码的编写放在不同的目录则方便了测试代码的管理以及代码的打包和发布