怎么用TestRunner停止java testcasee

23472人阅读
单元测试作为任何语言的开发者都应该是必要的,因为时隔数月后再回来调试自己的复杂程序时,其实也是很崩溃的事情。虽然会很快熟悉内容,但是修改和调试将是一件痛苦的事情,如果你在修改了代码后出现问题的话,而单元测试可以帮助我们很快准确的定位到问题的位置,出现问题的模块和单元。所以这是一件很愉快的事情,因为我们知道其它修改或没有修改的地方仍然是正常工作的,而我们目前的唯一问题就是搞定眼前这个有点问题的“家伙”。所以工作会在轻松中开始,并且很快将会结束,因为你已经知道很多信息了。
单元测试自然是对程序中最小的可测试模块--函数来进行测试;因为单元测试的对象是函数,也就是说你得被测试对象一定要有输出结果,哪怕就是异常输出,也得有输出,以便单元测试模块能够捕获返回值,并且与预期值进行比较,从而得出测试通过与否。
单元测试的加载方式有2种:一种是通过unittest.main()来启动单元测试的测试模块;一种是添加到testsuite集合中再加载所有的被测试对象,而testsuit里存放的就是单元测试的用例,下面分别列出了2种方法的使用。
1.1 测试模块中的函数:
被测模块:
#!/usr/bin/env python
#encoding: utf-8
def sum( x, y):
return x+y
def sub( x, y):
return x-y
单元测试模块:
#!/usr/bin/env python
#encoding: utf-8
import unittest
import myclass
class mytest(unittest.TestCase):
##初始化工作
def setUp(self):
#退出清理工作
def tearDown(self):
#具体的测试用例,一定要以test开头
def testsum(self):
self.assertEqual(myclass.sum(1, 2), 2, 'test sum fail')
def testsub(self):
self.assertEqual(myclass.sub(2, 1), 1, 'test sub fail')
if __name__ =='__main__':
unittest.main()
测试结果:【F表示一个fail, F前的点表示一个通过,有E的话表示程序自身异常】
======================================================================
FAIL: testsum (__main__.mytest)
----------------------------------------------------------------------
Traceback (most recent call last):
File &C:\Users\xiaowu\workspace\mypython\unitTest.py&, line 19, in testsum
self.assertEqual(myclass.sum(1, 2), 2, 'test sum fail')
AssertionError: test sum fail
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
1.2 测试模块类中的函数:
被测模块:
#!/usr/bin/env python
#encoding: utf-8
class myclass:
def __init__(self):
def sum(self, x, y):
return x+y
def sub(self, x, y):
return x-y
单元测试模块:
#!/usr/bin/env python
#encoding: utf-8
import unittest
import myclass
class mytest(unittest.TestCase):
##初始化工作
def setUp(self):
self.tclass = myclass.myclass()
##实例化了被测试模块中的类
#退出清理工作
def tearDown(self):
#具体的测试用例,一定要以test开头
def testsum(self):
self.assertEqual(self.tclass.sum(1, 2), 3)
if __name__ =='__main__':
unittest.main()
运行结果:
----------------------------------------------------------------------
Ran 1 test in 0.000s
这种方式执行单个测试文件时使用-v参数可以获得更多的测试结果信息。如:mytest.py -v&
2 加载测试套件
好吧,在运用测试套件进行单元测试之前,我想还是稍微研究一下unittest模块的内容有哪些,其大概的运行方式是什么样的。而后在给出根据各种情况如何制定单元测试套件。
首先,自然是查看unittest模块有哪些成员啦!
&&import unittest
&&dir(unittest)
['FunctionTestCase', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'Tes
tSuite', 'TextTestRunner', '_CmpToKey', '_TextTestResult', '_WritelnDecorator',
'__all__', '__author__', '__builtins__', '__doc__', '__email__', '__file__', '__
metaclass__', '__name__', '__package__', '__unittest', '__version__', '_makeLoad
er', '_strclass', 'defaultTestLoader', 'findTestCases', 'getTestCaseNames', 'mai
n', 'makeSuite', 'os', 'sys', 'time', 'traceback', 'types']
可以看到其自身的成员也不是很多,大概包括有:
['FunctionTestCase', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult',
&'TestSuite','TextTestRunner', '_CmpToKey', '_TextTestResult', '_WritelnDecorator',
&'defaultTestLoader','findTestCases', 'getTestCaseNames', 'main', 'makeSuite']
&好吧,我们大概看看具体都是干什么的
&&memblist = ['FunctionTestCase', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult',\
'TestSuite','TextTestRunner', 'defaultTestLoader','findTestCases', 'getTestCaseNames', \
'main', 'makeSuite']
&&for memb in memblist:
cur = getattr(unittest, memb)
print help(cur)
&'FunctionTestCase':函数测试用例,即给一个函数作为参数,返回一个testcase实例,可选参数有set-up,tear-down方法
&'TestCase':所有测试用例的基本类,给一个测试方法的名字,返回一个测试用例实例
&'TestLoader':测试用例加载器,其包括多个加载测试用例的方法。返回一个测试套件
&loadTestsFromModule(self, module)--根据给定的模块实例来获取测试用例套件
&loadTestsFromName(self, name, module=None)
&--根据给定的字符串来获取测试用例套件,字符串可以是模块名,测试类名,测试类中的测试方法名,或者一个可调用的是实例对象
&这个实例对象返回一个测试用例或一个测试套件
&loadTestsFromNames(self, names, module=None) --和上面功能相同,只不过接受的是字符串列表
&loadTestsFromTestCase(self, testCaseClass)--根据给定的测试类,获取其中的所有测试方法,并返回一个测试套件
'TestProgram':命令行进行单元测试的调用方法,作用是执行一个测试用例。其实unittest.main()方法执行的就是这个命令,
而这个类实例时默认加载当前执行的作为测试对象,
原型为 __init__(self, module='__main__', defaultTest=None, argv=None, testRunner=xx, testLoader=xx)
其中module='__main__'就是默认加载自身
'TestResult':测试用例的结果保存实例,通常有测试框架调用
&'TestSuite':组织测试用例的实例,支持测试用例的添加和删除,最终将传递给testRunner进行测试执行
&'TextTestRunner':进行测试用例执行的实例,其中Text的意思是以文本形式显示测试结果。显示测试名称,即完成的测试结果,其过同执行单元测试脚本时添加-v参数
&'defaultTestLoader':其实就是TestLoader
&'findTestCases', 'getTestCaseNames':这个2个就不用解释了
&'main': 其实就是TestProgram
&'makeSuite':通常是由单元测试框架调用的,用于生产testsuite对象的实例
&至此,我们知道了。其实整个单元测试框架的逻辑出来了。分三步走:第一步testloader根据传入的参数获得相应的测试用例,即对应具体的测试方法,
&然后makesuite在把所有的测试用例组装成testsuite,最后把testsiute传给testrunner进行执行。
&而我们通常执行的unittest.main(),其实就是unittest.testprom方法,其执行的功能就是上面分析的三步,在第一步中其传入的参数是自身的模块__main__;
&在第二步中把自身模块中的所有测试类中中的测试方法提取出来,并生成测试套件;最后再把测试套件传递给testrunner进行具体的测试。
&最后给出一个完整的单元测试组织代码,把该代码放到单元测试用例文件的同一个目录后执行该脚本,即可执行所有的测试用例文件。
&【测试用例文件必须为test开头,如:testxxx.py, 当然这个文件本身是一个单元测试的文件】
#!/usr/bin/env python
#encoding: utf-8
#该代码源自深入python
import unittest
import myclass
import sys
def testAllinCurrent():
path = os.path.abspath(os.path.dirname(sys.argv[0]))
files = os.listdir(path)
test = re.compile(&test\.py{1}, re.IGNORECASE)
files = filter(test.search, files)
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
modules = map(__import__, moduleNames)
load = unittest.defaultTestLoader.loadTestsFromModule
return unittest.TestSuite(map(load, modules))
if __name__ == &__main__&:
unittest.main(defaultTest=&regressionTest&)
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:416970次
积分:5286
积分:5286
排名:第2033名
原创:134篇
转载:25篇
评论:80条
(1)(1)(3)(2)(2)(3)(2)(6)(1)(3)(4)(3)(1)(5)(4)(6)(5)(5)(3)(7)(2)(4)(1)(3)(8)(11)(19)(2)(4)(3)(4)(24)(3)(1)(3)SoapUI对于Json数据进行属性值获取与传递
SoapUI的Property
Transfer功能可以很好地对接口请求返回的数据进行参数属性获取与传递,但对于Json数据,SoapUI会把数据格式先转换成XML格式,但实际情况却是,转换后的XML格式往往根本没法用Xpath形式获取到指定的数据了。因此只能用Script脚本形式了。
{"addUsersToDirectoryResponse":{"addUserToDirectoryResponse":[{"ack":"Success","userId":"2745379"}]}}
例如要获得userId的数据,有两种方式
一、建立一个script步骤,然后再建一个Property
Transfer步骤,将script步骤的结果传递到指定的properties中的property中就可以了
import groovy.json.JsonSlurper
def xresponse =
testRunner.testCase.testSteps["addUserToDirectory"].testRequest.response.contentAsString
def slurper = new JsonSlurper()
def result = slurper.parseText(xresponse)
def userId =
result.addUsersToDirectoryResponse.addUserToDirectoryResponse[0].userId
二、直接在script步骤中赋值
import groovy.json.JsonSlurper
def xresponse =
testRunner.testCase.testSteps["addUserToDirectory"].testRequest.response.contentAsString
def slurper = new JsonSlurper()
def result = slurper.parseText(xresponse)
def userId
=&result.addUsersToDirectoryResponse.addUserToDirectoryResponse[0].userId.toString()
//testSteps[]中括号中指定当前testCase中的哪个Properties步骤,setPropertyValue()方法中第一个userId参数指Properties步骤中名为userId的property,
第二个参数设定它的值,即上面从返回结果中获得的userId
testRunner.testCase.testSteps["Properties"].setPropertyValue("userId",userId)
另外,在断言中使用脚本断言时,如果也要获得testCase步骤中的property的话,不能直接使用
testRunner.testCase.testSteps["Properties"].getPropertyValue("userId")这样的形式,
否则会报"No such property: testRunner for clases: Script1"的错误
在Script Assertion中想要获得属性值的话可以用以下形式替代
def number =
messageExchange.modelItem.testCase.testSteps["Properties"].getPropertyValue("userId")
对于项目中的属性可分为这么几个级别Global,&Project,TestSuite,&TestCase
即全局变量、项目级别、用例集级别、单个用例级别
要获得如项目级别的属性变量的话,可以用以下方法
def time_num=context.expand('${#Project#time_num}')
&//##号内为定义哪个级别的属性变量,后面为属性名
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。MenuSet JUnit Test case fail information : Unit Test&&&Development Class&&&JavaSet JUnit Test case fail information
import junit.extensions.TestS
import junit.framework.T
import junit.framework.TestC
import junit.framework.TestS
public class MainClass extends TestCase {
public static void main (String... args) {
junit.textui.TestRunner.run (suite());
public MainClass(String name) {
super(name);
public void testPassNullsToConstructor() {
Person p = new Person(null, null);
fail("Expected IllegalArgumentException because both args are null");
} catch (IllegalArgumentException expected) {
public void testNullsInName() {
fail("sample failure");
Person p = new Person(null, "lastName");
assertEquals("lastName", p.getFullName());
p = new Person("Tanner", null);
assertEquals("Tanner ?", p.getFullName());
public static void oneTimeSetup() {
System.out.println("oneTimeSetUp");
public static void oneTimeTearDown() {
System.out.println("oneTimeTearDown");
public static Test suite() {
TestSetup setup = new TestSetup(new TestSuite(MainClass.class)) {
protected void setUp() throws Exception {
oneTimeSetup();
protected void tearDown() throws Exception {
oneTimeTearDown();
class Person {
private String firstN
private String lastN
public Person(String firstName, String lastName) {
if (firstName == null && lastName == null) {
throw new IllegalArgumentException("Both names cannot be null");
this.firstName = firstN
this.lastName = lastN
public String getFullName() {
String first = (this.firstName != null) ? this.firstName : "?";
String last = (this.lastName != null) ? this.lastName : "?";
return first + " " +
public String getFirstName() {
return this.firstN
public String getLastName() {
return this.lastN
Related examples in the same category1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
&|&Email:info &|&& Demo Source and Support. All rights reserved.如何使用CppUnit做单元测试_百度知道
如何使用CppUnit做单元测试
提问者采纳
CppUnit dynamic import library & testrunneru: CppUnit dynamic library (DLL) &Multithreaded DLL&quot. 在App初始化函数中App: CppUnit static library &quot.addTest( CppUnit.lib :.dll : void setUp();Multithreaded DLL& cppunit_ cppunitd_dll:.run();lib拷出来.2&#92:testcase1() { CPPUNIT_ASSERT(condition1);Multithreaded DLL&quot.dll .Debug Multithreaded DLL& testrunnerud: MFC Unicode TestRunner import library & protected.Debug Multithreaded DLL&Debug Multithreaded DLL&&#47. 加入要测的类叫XXX 我们起这个类的测试叫testXXX 类 #include #include #include &quot.Multithreaded DLL&quot./Debug Multithreaded DLL&quot: CppUnit static library &Multithreaded DLL&Debug Multithreaded DLL&quot:: CppUnit dynamic library (DLL) & 其cpp文件必须要有 CPPUNIT_TEST_SUITE_REGISTRATION(testXXX):TestRunner runner. 在“工具”-选项-目录 C:TestCase { CPPUNIT_TEST_SUITE(testXXX ).makeTest() ).h&quot. A; CPPUNIT_TEST(testcase1);Multithreaded DLL&quot:: MFC Unicode TestRunner import library & TestRunnerDSPlugIn;/Multithreaded DLL& testrunnerud: QT TestRunner dynamic library (DLL) &quot: The add-in you register in VC++: ---------- All the compiled libraries and DLL can be found in the &#39. Most libraries can be build from src/析构你的测试对象 } 下面就是你的测试函数 void testXXX. 在工程配置里面选择RTTI Link下加入 Debug&#92:: void testcase1(); 记得把原来的窗口注掉: MFC TestRunner import library & testrunnerd. 新建一个MFC应用程序 B;Multithreaded DLL&Multithreaded DLL&/;Debug Multithreaded DLL&quot. cppunitd_dll: MFC TestRunner dynamic library (DLL) &quot.10:getRegistry().lib : QT TestRunner import library &quot./testXXX ; &#47::TestFactoryR当然要按照实际的类构造你的测试对象了 } void testXXX,把相应的dll文件也拷到debug目录下 D. qttestrunner.lib ,记得把这辆个文件从cppunit-1: CPPUNIT_TEST_SUITE_END();如果condition1为false激发这个assert CPPUNIT_ASSERT_MESSAGE(”msg“ ;Debug Multithreaded DLL&&#47,不然调用的还是原来的窗口;这里就是我们的testcase的函数原型名字 CPPUNIT_TEST(testcase2):tearDown() {声明我们的测试函数 void testcase2().lib'&#47. testrunneru:: MFC TestRunner dynamic library (DLL) & public.lib :InitInstance()的开头加入 #include #include 在其中加入 CppUnit:; cppunit_cppunitd:setUp() { fixture = new testXXX(): MFC Unicode TestRunner dynamic library (DLL) &quot. directory.dll , condition2): MFC Unicode TestRunner dynamic library (DLL) &quot。 E; }; 然后 void testXXX;/ runner:MfcUiLibraries.lib Debug&#92: CppUnit dynamic import library & testrunner.dll . lib\ void tearDown(): testXXX *CppUnitL cppunitd:: MFC TestRunner import library &quot: public CppU/ fixture = NULL; class testXXX .dsw workspace
其他类似问题
cppunit的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁2063人阅读
JUnit是一个开源的Java单元测试框架,由 Erich Gamma 和 Kent
Beck 开发完成。
8.1.1& JUnit简介
JUnit主要用来帮助开发人员进行Java的单元测试,其设计非常小巧,但功能却非常强
下面是JUnit一些特性的总结:
提供的API可以让开发人员写出测试结果明确的可重用单元测试用例。
提供了多种方式来显示测试结果,而且可以扩展。
提供了单元测试批量运行的功能,而且可以和Ant很容易地整合。
对不同性质的被测对象,如Class,JSP,Servlet等,JUnit有不同的测试方法。
8.1.2& 为什么要使用JUnit
以前,开发人员写一个方法,如下代码所示:
//******* AddAndSub.java**************
public Class AddAndSub {
&&& public static int add(int m, int n) {
&&&&&&& int num = m +
&&& public static int sub(int m, int n) {
&&&&&&& int num = m -
如果要对AddAndSub类的add和sub方法进行测试,通常要在main里编写相应
的测试方法,如下代码所示:
//******* MathComputer.java**************
public Class AddAndSub {
&&& public static int add(int m, int n) {
&&&&&&& int num = m +
&&& public static int sub(int m, int n) {
&&&&&&& int num = m -
&&& public static void main(String args[]) {
&&&&&&& if (add (4, 6) == 10)) {
&&&&&&&&&&& System.out.println(&Test Ok&);
&&&&&&& } else {
&&&&&&&&&&& System.out.println(&Test Fail&);
&&&&&&& if (sub (6, 4) ==2)) {
&&&&&&&&&&& System.out.println(&Test Ok&);
&&&&&&& } else {
&&&&&&&&&&& System.out.println(&Test Fail&);
从上面的测试可以看出,业务代码和测试代码放在一起,对于复杂的业务逻辑,一方面代码量会
非常庞大,另一方面测试代码会显得比较凌乱,而JUnit就能改变这样的状况,它提供了更好的方法来进行单元测试。使用JUnit来测试前面代码的示例如
//******* TestAddAndSub.java**************
import junit.framework.TestC
public Class TestAddAndSub &extends TestCase {
&&& public void testadd() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(4, 6));
&&& public void testsub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(6, 4));
&&& public static void main(String args[]){&
&&&&& &&&junit.textui.TestRunner.run(TestAddAndSub .class);&&& }
这里先不对JUnit的使用方法进行讲解,从上可
以看到,测试代码和业务代码分离开,使得代码比较清晰,如果将JUnit放在Eclipse中,测试起来将会更加方便。
8.2& 建立JUnit的开发环境
为了不使读者在环节配置上浪费太多时间,这里将一步一步地讲解如何下载和配置JUnit。
具体步骤如下:
8.2.1& 下载JUnit
从www.junit.org可以进入到JUnit的首页,JUnit的首页画面如图
本书使用的版本是4.3版本,单击&Junit4.3.zip&即可进入下载JUnit的
画面,如图8.2所示。
下载Junit4.3.zip,下载后解压缩即可。
8.2.2& 配置JUnit
下载Junit4.3.zip完毕,并解压缩到D
盘根目录下后,即可开始配置环境变量。用前面介绍的设定系统变量的方法,设定ClassPath,ClassPath=***;
D:&junit&junit.jar,如图8.3所示。
图8.1& JUnit的首页画面
图8.2& 下载JUnit的画面
查看是否配置好JUnit,在类里添加如下
import junit.framework.TestC
图8.3& 设定系统变量ClassPath
如果编译没有错误,则说明配置成功。
JUnit的使用方法
JUnit的使用非常简单,共有3步:第一步、编写测试类,使其继承TestCase;第
二步、编写测试方法,使用test+&&&的方式来命名测试方法;第三步、编写断言。如果测试方法有公用的变量等需要初始化和销毁,则可以使用
setUp,tearDown方法。
8.3.1& 继承TestCase
如果要使用JUnit,则测试类都必须继承TestCase。当然目前的最新版JUnit
是不需要继承它的,但并不是说TestCase类就没有用了,它仍然是JUnit工作的基础。这里先讲述继承TestCase类的方式,稍后再介绍不继承
下面是前面使用JUnit进行测试
AddAndSub类的代码,这里进行详细的分析:
//******* TestAddAndSub.java**************
import junit.framework.TestC
public Class TestAddAndSub &extends TestCase {
&&& public void testadd() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(4, 6));
&&& public void testsub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(6, 4));
&&& public static void main(String args[]){&
&&&&& &&&junit.textui.TestRunner.run(TestAddAndSub .class);&&& }
代码说明:
这里继承TestCase,表示该类是一个测试类。
然后使用junit.textui.TestRunner.run方法来执行这个测试类。
这里给出TestCase的源代码:
//******* TestCase.java**************
package junit.
import java.lang.reflect.InvocationTargetE
import java.lang.reflect.M
import java.lang.reflect.M
public abstract class TestCase extends Assert implements Test {
&&& /**测试案例的名称*/
&&& private String fN
&&& /**构造函数
&&& public TestCase() {
&&&&&&& fName=
&&& /**带参数的构造函数
&&& public TestCase(String name) {
&&&&&&& fName=
&&& /**获取被run执行的测试案例的数量
&&& public int countTestCases() {
&&&&&&& return 1;
&&& /**创建一个TestResult
&&& &* @see TestResult
&&& protected TestResult createResult() {
&&& &&& return new TestResult();
&&& /**执行run方法,返回TestResult
&&& &* @see TestResult
&&& public TestResult run() {
&&&&&&& TestResult result= createResult();
&&&&&&& run(result);
&&& /**执行run方法,参数为TestResult
&&& public void run(TestResult result) {
&&&&&&& result.run(this);
&&& /**执行测试方法,包括初始化和销毁方法
&&& &* @throws Throwable if any exception is thrown
&&& public void runBare() throws
Throwable {
&&&&&&& Throwable exception=
&&&&&&& setUp();
&&&&&&& try {
&&&&&&&&&&& runTest();
&&&&&&& } catch (Throwable running) {
&&&&&&&&&&& exception=
&&&&&&& finally {
&&&&&&&&&&& try {
&&&&&&&&&&&&&&& tearDown();
&&&&&&&&&&& } catch (Throwable tearingDown) {
&&&&&&&&&&&&&&& if (exception == null) exception= tearingD
&&&&&&&&&&& }
&&&&&&& if (exception != null)
&&& /**执行测试方法
&&& &* @throws Throwable if any exception is thrown
&&& protected void runTest() throws Throwable {
&&&&&&& assertNotNull(&TestCase.fName cannot be null&, fName); //
Some VMs crash when calling getMethod(null,null);
&&&&&&& Method runMethod=
&&&&&&& try {
&&&&&&&&&&& //利用反射机制
&&&&&&&&&&& runMethod= getClass().getMethod(fName, (Class[])null);
&&&&&&& } catch (NoSuchMethodException e) {
&&&&&&&&&&& fail(&Method &&&+fName+&&& not found&);
&&&&&&& if (!Modifier.isPublic(runMethod.getModifiers())) {
&&&&&&&&&&& fail(&Method &&&+fName+&&& should be public&);
&&& &&&& //利用反射机制
&&&&&&& try {
&&&&&&&&&&& runMethod.invoke(this);
&&&&&&& catch (InvocationTargetException e) {
&&&&&&&&&&& e.fillInStackTrace();
&&&&&&&&&&& throw e.getTargetException();
&&&&&&& catch (IllegalAccessException e) {
&&&&&&&&&&& e.fillInStackTrace();
&&&&&&&&&&&
&&& /**测试前的初始化方法
&&& protected void setUp() throws
Exception {
&&& /**测试后的销毁方法
&&& protected void tearDown() throws Exception {
&&& /**返回测试案例的名称
&&& &* @return the name of the TestCase
&&& public String getName() {
&&&&&&& return fN
&&& /**设定测试案例的名称
&&& &* @param name the name to set
&&& public void setName(String name) {
&&&&&&& fName=
代码说明:
& 该类继承了Assert
类,实现了Test接口。
可以看出,TestCase类正是通过runBare实现了在测试方法前初始化相关变量和环境,在测试方法后销毁相关变量和环境。
8.3.2& 编写测试方法
测试方法名要以test+方法名来命名,当
然最新版的JUnit支持直接以方法名来命名测试方法。这是通过TestCase类里的runTest方法来实现的,主要利用了Java的反射机
制,runTest方法的代码如下:
protected void runTest() throws Throwable {
&&&&&&& assertNotNull(&TestCase.fName cannot be null&, fName); //
Some VMs crash when calling getMethod(null,null);
&&&&&&& Method runMethod=
&&&&&&& try {
&&&&&&&&&&& // 获取要测试的方法
&&&&&&&&&&& runMethod= getClass().getMethod(fName, (Class[])null);
&&&&&&& } catch (NoSuchMethodException e) {
&&&&&&&&&&& fail(&Method &&&+fName+&&& not found&);
&&&&&&& //判断要测试的方法是否为公用方法
&&&&&&& if (!Modifier.isPublic(runMethod.getModifiers())) {
&&&&&&&&&&& fail(&Method &&&+fName+&&& should be public&);
&&& &&&& //Java的反射机制
&&&&&&& try {
&&&&&&&&&&& runMethod.invoke(this);
&&& &&&& //抛出调用异常
&&&&&&& catch (InvocationTargetException e) {
&&&&&&&&&&& e.fillInStackTrace();
&&&&&&&&&&& throw e.getTargetException();
&&&&&&& catch (IllegalAccessException e) {
&&&&&&&&&&& e.fillInStackTrace();
&&&&&&&&&&&
8.3.3& 编写断言
JUnit主要有以下断言:
assertEquals(期望值,实际值),检查两个值是否相等。
assertEquals(期望对象,实际对象),检查两个对象是否相等,利用对象的equals()方法进行判断。
assertSame(期望对象,实际对象),检查具有相同内存地址的两个对象是否相等,利用内存地址进行判断,注意和上面assertEquals方法
assertNotSame(期望对象,实际对象),检查两个对象是否不相等。
assertNull(对象1,对象2),检查一个对象是否为空。
assertNotNull(对象1,对象2),检查一个对象是否不为空。
assertTrue(布尔条件),检查布尔条件是否为真。
assertFalse(布尔条件),检查布尔条件是否为假。
这些断言主要定义在JUnit的
Assert类里,Assert类的示例代码如下:
//******* Assert.java**************
package junit.
/**一系列的断言方法
public class Assert {
&&& /**构造函数
&&& protected Assert() {
&&& /**断言是否为真,带消息
&&& static public void assertTrue(String message, boolean condition) {
&&&&&&& if (!condition)
&&&&&&&&&&& fail(message);
&&& /**断言是否为真
&&& static public void assertTrue(boolean condition) {
&&&&&&& assertTrue(null, condition);
&&& /**断言是否为假,带消息
&&& static public void assertFalse(String message, boolean condition)
&&&&&&& assertTrue(message, !condition);
&&& /**断言是否为假
&&& static public void assertFalse(boolean condition) {
&&&&&&& assertFalse(null, condition);
&&& /**断言是否为失败
&&& static public void fail(String message) {
&&&&&&& throw new AssertionFailedError(message);
&&& /**断言是否为失败
&&& static public void fail() {
&&&&&&& fail(null);
&&& /**是否相等的断言,带消息Object
&&& static public void
assertEquals(String message, Object expected, Object actual) {
&&&&&&& if (expected == null && actual == null)
&&&&&&&&&&&
&&&&&&& if (expected != null && expected.equals(actual))
&&&&&&&&&&&
&&&&&&& failNotEquals(message, expected, actual);
&&& /**是否相等的断言,Object
&&& static public void assertEquals(Object expected, Object actual) {
&&& &&& assertEquals(null, expected, actual);
&&& /**是否相等的断言,带消息String
&&& static public void assertEquals(String message, String expected,
String actual) {
&&&&&&& if (expected == null && actual == null)
&&&&&&&&&&&
&&&&&&& if (expected != null && expected.equals(actual))
&&&&&&&&&&&
&&&&&&& throw new ComparisonFailure(message, expected, actual);
&&& /**是否相等的断言,String
&&& static public void assertEquals(String expected, String actual) {
&&& &&& assertEquals(null, expected, actual);
&&& /**是否相等的断言,带消息double
&&& static public void assertEquals(String message, double expected,
double actual, double delta) {
&&&&&&& if (pare(expected, actual) == 0)
&&&&&&&&&&&
&&&&&&& if (!(Math.abs(expected-actual) &= delta))
&&&&&&&&&&& failNotEquals(message, new Double(expected), new
Double(actual));
&&& /**是否相等的断言,double
&&& static public void assertEquals(double expected, double actual,
double delta) {
&&& &&& assertEquals(null, expected, actual, delta);
&&& /**是否相等的断言,带消息float
&&& static public void assertEquals(String message, float expected,
float actual, float delta) {
&&&&&&& if (pare(expected, actual) == 0)
&&&&&&&&&&&
&&&&&&& if (!(Math.abs(expected - actual) &= delta))
&&&&&&&&&&&&&&& failNotEquals(message, new Float(expected), new
Float(actual));
&&& /**是否相等的断言, float
&&& static public void assertEquals(float expected, float actual,
float delta) {
&&&&&&& assertEquals(null, expected, actual, delta);
&&& /**是否相等的断言,带消息long
&&& static public void assertEquals(String message, long expected,
long actual) {
&&& &&& assertEquals(message, new Long(expected), new Long(actual));
&&& /**是否相等的断言, long
&&& static public void assertEquals(long expected, long actual) {
&&& &&& assertEquals(null, expected, actual);
&&& /**是否相等的断言,带消息boolean
&&& static public void assertEquals(String message, boolean expected,
boolean actual) {
&&& &&&& assertEquals(message, Boolean.valueOf(expected),
Boolean.valueOf(actual));
&&& /**是否相等的断言,boolean
&&& static public void assertEquals(boolean expected, boolean actual)
&&&&&&& assertEquals(null, expected, actual);
&&& /**是否相等的断言,带消息byte
& && static public void assertEquals(String message, byte expected,
byte actual) {
&&&&&&& assertEquals(message, new Byte(expected), new Byte(actual));
&&& /**是否相等的断言, byte
&&& static public void assertEquals(byte expected, byte actual) {
&&&&&&& assertEquals(null, expected, actual);
&&& /**是否相等的断言,带消息char
& && static public void assertEquals(String message, char expected,
char actual) {
&&& &&&& assertEquals(message, new Character(expected), new
Character(actual));
&&& /**是否相等的断言,char
& && static public void
assertEquals(char expected, char actual) {
&&&&&&& assertEquals(null, expected,
&&& /**是否相等的断言,带消息short
&&& static public void
assertEquals(String message, short expected, short actual) {
&&& &&&& assertEquals(message, new
Short(expected), new Short(actual));
& && /**是否相等的断言,short
&&& static public void
assertEquals(short expected, short actual) {
&&&&&&& assertEquals(null, expected,
&&& /**是否相等的断言,带消息int
& && static public void
assertEquals(String message, int expected, int actual) {
&&&&&&& assertEquals(message, new
Integer(expected), new Integer(actual));
& && /**是否相等的断言,int
& && static public void assertEquals(int
expected, int actual) {
& &&&&&& assertEquals(null, expected,
&&& /**是否不为null的断言 Object
&&& static public void
assertNotNull(Object object) {
&&&&&&& assertNotNull(null, object);
&&& /**是否不为null的断言,带消息Object
&&& static public void
assertNotNull(String message, Object object) {
&&&&&&& assertTrue(message, object !=
&&& /**是否为null的断言Object
&&& static public void assertNull(Object object) {
&&&&&&& assertNull(null, object);
&&& /**是否为null的断言,带消息Object
&&& static public void
assertNull(String message, Object object) {
&&&&&&& assertTrue(message, object ==
&&& /**是否相同的断言,带消息*/
&&& static public void assertSame(String
message, Object expected, Object actual) {
&&&&&&& if (expected == actual)
&&&&&&&&&&&
&&&&&&& failNotSame(message, expected, actual);
&&& /**是否相同的断言,Object
&&& static public void assertSame(Object expected, Object actual) {
&&& &&& assertSame(null, expected, actual);
&&& /**是否不相同的断言,带消息
&&& static public void assertNotSame(String message, Object expected,
Object actual) {
&&&&&&& if (expected == actual)
&&&&&&&&&&& failSame(message);
&&& /**是否不相同的断言Object
&&& static public void assertNotSame(Object expected, Object actual) {
&&&&&&& assertNotSame(null, expected, actual);
&&& /**相同时失败
&&& static public void failSame(String message) {
&&&&&&& String formatted= &&;
&&&&&&& if (message != null)
&&&&&&&&&&& formatted= message+& &;
&&&&&&& fail(formatted+&expected not same&);
&&& /**不相同时失败
&&& static public void failNotSame(String message, Object expected,
Object actual) {
&&&&&&& String formatted= &&;
&&&&&&& if (message != null)
&&&&&&&&&&& formatted= message+& &;
&&&&&&& fail(formatted+&expected same:&&+expected+&& was
not:&&+actual+&&&);
&&& /**不相等时失败
&&& static public void failNotEquals(String message, Object expected,
Object actual) {
&&&&&&& fail(format(message, expected, actual));
&&& /**格式化消息
&&& public static String format(String message, Object expected,
Object actual) {
&&&&&&& String formatted= &&;
&&&&&&& if (message != null)
&&&&&&&&&&& formatted= message+& &;
&&&&&&& return formatted+&expected:&&+expected+&& but
was:&&+actual+&&&;
从上述代码中,读者可以研读JUnit中有关断言
的实现方式,其实,最终都是使用后面的几个static方法来实现的。
JUnit的新特性
Java 5的发布为JUnit带来了新的特性。自JUnit
4.0之后,JUnit大量使用了annotations特性,使编写单元测试变得更加简单。
8.4.1& 改变测试方法的命名方式
前面讲过,使用JUnit
4.0以上版本可以不用遵循以前JUnit约定的测试方法命名方法,以前命名方法的示例代码如下:
//******* TestAddAndSub.java**************
import junit.framework.TestC
public class TestAddAndSub &extends TestCase {
&&& public void testadd() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(4, 6));
&&& public void testsub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(6, 4));
&&& public static void main(String args[]){&
&&&&& &&&junit.textui.TestRunner.run(TestAddAndSub .class);&&& }
4.0以上版本的命名方式,是在测试方法前使用@Test注释,示例代码如下:
//******* TestAddAndSub.java**************
import junit.framework.TestC
import org.junit.*;
public class TestAddAndSub& extends TestCase {
&&& @Test public void add() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(4, 6));
&&& @Test public void sub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(6, 4));
这个时候,测试方法的命名将不再重要,开发人员可
以按照自己的命名方式来命名。
8.4.2& 不再继承TestCase
新版本的JUnit将不再强制继承
TestCase,但需要import org.junit.Assert来实现断言,示例代码如下:
//******* TestAddAndSub.java**************
import static org.junit.Assert.assertE
import org.junit.*;
public class TestAddAndSub{
&&& @Test public void add() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(4, 6));
&&& @Test public void sub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(6, 4));
8.4.3& 改变初始化和销毁方式
以前,JUnit使用SetUp和
TearDown方法来进行初始化和销毁动作,JUnit
4.0以上版本将不再强制使用SetUp和TearDown方法来进行初始化和销毁,原来使用SetUp和TearDown方法的示例代码如下:
//******* TestAddAndSub.java**************
import junit.framework.TestC
public class TestAddAndSub &extends TestCase {
&&& private int m = 0;
&&& private int n = 0;
&&& //初始化
&&& protected void setUp() {
&&&&&&& m = 4;
&&&&&&& n = 6;
&&& public void testadd() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(m, n));
&&& public void testsub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(n, m));
&&& //销毁
&&& protected void tearDown() {
&&&&&&& m = 0;
&&&&&&& n = 0;
不使用SetUp和TearDown方法的示例代码如下:
//******* TestAddAndSub.java**************
import static org.junit.Assert.assertE
import org.junit.*;
public class TestAddAndSub {
&&& protected int m = 0;
&&& protected int n = 0;
&&& //初始化
&&& @Before public void init() {
&&&&&&& m = 4;
&&&&&&& n = 6;
&&& @Test public void add() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(m, n));
&&& @Test public void sub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(n, m));
&&& //销毁
&&& @After public void destory() {
&&&&&&& m = 0;
&&&&&&& n = 0;
上面示例中的初始化和销毁都是针对一个方法来说的,每个方法执行前都要进行初始化,执行完
毕都要进行销毁。而JUnit的最新版本则提供了新的特性,针对类进行初始化和销毁。也就是说,该类中的方法只进行一次初始化和销毁,方法就是使用
@Before和@After,示例代码如下:
//******* TestAddAndSub.java**************
import static org.junit.Assert.assertE
import org.junit.*;
public class TestAddAndSub {
&&& protected int m = 0;
&&& protected int n = 0;
&&& //初始化
&&& @BeforeClass public void init() {
&&&&&&& m = 4;
&&&&&&& n = 6;
&&& @Test public void add() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(m, n));
&&& @Test public void sub() {
&&&&&&& //断言计算结果与2是否相等
&&& &&& assertEquals(2, AddAndSub.sub(n, m));
&&& //销毁
&&& @AfterClass public void destory() {
&&&&&&& m = 0;
&&&&&&& n = 0;
上述初始化和销毁动作,只执行一次即可。
8.4.4& 改变异常处理的方式
以前,使用JUnit进行单元测试时,如果
遇到异常情况,需要使用try&catch的形式来捕捉异常,示例代码如下:
//******* TestAddAndSub.java**************
import junit.framework.TestC
public class TestAddAndSub &extends TestCase {
&&& private int m = 0;
&&& private int n = 0;
&&& //初始化
&&& protected void setUp() {
&&&&&&& m = 4;
&&&&&&& n = 6;
&&& public void testadd() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10, AddAndSub.add(m, n));
&&& public void testsub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(n, m));
&&& public void testdiv() {
&&&&&&& //断言除数为0
&&&&&&& try {
&&&&&&& &&&&& int n = 2 / 0;
&&&&&&& &&&&& fail(&Divided by zero!&);
&&& &&&& }
&&& &&&& catch (ArithmeticException success) {
&&&&&&& &&&&& assertNotNull(success.getMessage());
&& &&&&& &}
&&& //销毁
&&& protected void tearDown() {
&&&&&&& m = 0;
&&&&&&& n = 0;
JUnit4.0以后的版本将不再使用try&catch的方式来捕捉异常,示例代码如
TestAddAndSub.java**************
import static
org.junit.Assert.assertE
import org.junit.*;
public class TestAddAndSub {
&&& protected int m = 0;
&&& protected int n = 0;
&&& //初始化
&&& @Before public void init() {
&&&&&&& m = 4;
&&&&&&& n = 6;
&&& @Test public void add() {
&&&&&&& //断言计算结果与10是否相等
&&&&&&& assertEquals(10,
AddAndSub.add(m, n));
&&& @Test public void sub() {
&&&&&&& //断言计算结果与2是否相等
&&&&&&& assertEquals(2, AddAndSub.sub(n,
t(expected=ArithmeticException.class)& public void div() {
&&&&&&& //断言除数是否为0
&&&&&&& int n = 2 / 0;
&&& //销毁
&&& @After public void destory() {
&&&&&&& m = 0;
&&&&&&& n = 0;
当然,JUnit还有许多新的特性,限于篇幅原
因,这里只对比较重要的特性进行讲解,其余将不再多讲,想要了解的读者可以到JUnit的相关网站进行学习。
本章首先讲述了JUnit的下载和安装,接着又讲解了JUnit的相关知识,最后讲解了
JUnit的新特性。
JUnit对开发人员进行大规模的单元测试来说,是非常有用的,但对于大量的代码如何来管
理就只有靠CVS了。CVS是一个版本控制系统,主要用来管理开发人员代码的历史,下一章主要讲如何使用CVS。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11875次
排名:千里之外
转载:11篇
(1)(1)(12)

我要回帖

更多关于 django testcase 的文章

 

随机推荐