PyUnit提供的动态方法,只编写一个测试类来完成对整个软件模块的测试,这样对象的初始化工作可以在setUp()方法中完成,而资源的释放则可以在tearDown()方法中完成。
使用PyUnit可以像xunit那样设置一个个函数,分别测试不同的数据和不同的用例。
例如,构建下面的测试类,测试远程API服务
1 class Request: 2 def __init__(self): 3 pass 4 def request(self,RequestMethod,RequestURL,param,requestHeaders): 5 return Request.__dict__[RequestMethod](self,RequestURL,param,requestHeaders) 6 def get(self,RequestURL,param,requestHeaders): 7 RequestURL=RequestURL+"?"+urllib.parse.urlencode(param) 8 req = url.Request(RequestURL) 9 result = url.urlopen(req).read() 10 return result 11 def post(self,RequestURL,param,requestHeaders): 12 postdata= json.dumps(param) 13 req = url.Request( 14 url = RequestURL, 15 data = postdata.encode("utf-8"), 16 headers = requestHeaders 17 ) 18 result = url.urlopen(req).read() 19 return result
想要知道其中执行结果,构造下面的测试类
1 class APITest(unittest.TestCase): 2 def setUp(self): 3 self.r=Request() 4 def test_UserPermisionQueryPost(self): 5 RequestURL="http://10.125.198.137/permission/table/listUserTablePermissions.json" 6 RequestMethod="post" 7 requestHeaders={"Accept":"*/*",} 8 param={ 9 "tablePermissionParam": { 10 "currentPage": 1, 11 "pageSize": 50, 12 "tablename": "s_auction_auctions", 13 "usernames": [ 14 "067765" 15 ] 16 } 17 } 18 expectResult=b'{"returnCode":"0","returnValue":[{"id":2067,"username":"067765","tablename":"s_auction_auctions","packagename":"yunti1.taobao","readlevelpermission":2,"permissiontime": 19 "2014-03-18 06:02:10","distabletime":"2015-03-18 06:02:08","permissionstatus":1,"gmtCreate":"2014-03-18 06:02:10","gmtModify":"2014-03-18 06:02:10","columns":["id","title"]}]}' 20 self.assertEqual(self.r.request(RequestMethod,RequestURL,param,requestHeaders),expectResult) 21 def test_UserPermisionQueryGet(self): 22 RequestMethod="get" 23 RequestURL="http://10.125.198.137/permission/table/listUserTablePermissions" 24 param={"tablename":"s_auction_auctions"} 25 expectResult=b'{"returnCode":"0","returnValue":[{"id":2067,"username":"067765","tablename":"s_auction_auctions","packagename":"yunti1.taobao","readlevelpermission":2,"permissiontime": 26 "2014-03-18 06:02:10","distabletime":"2015-03-18 06:02:08","permissionstatus":1,"gmtCreate":"2014-03-18 06:02:10","gmtModify":"2014-03-18 06:02:10","columns":["id","title"]},{"id":2066, 27 "username":"068521","tablename":"s_auction_auctions","packagename":"yunti1.taobao","readlevelpermission":2,"permissiontime":"2014-03-18 06:02:10","distabletime":"2015-03-18 06:02:08", 28 "permissionstatus":1,"gmtCreate":"2014-03-18 06:02:10","gmtModify":"2014-03-18 06:02:10","columns":["id","title"]}],"count":2}' 29 self.assertEqual(self.r.request(RequestMethod,RequestURL,param,""),expectResult)
PyUnit模块中定义了一个名为main的全局方法,使用它可以很方便地将一个单元测试模块变成可以直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中的测试方法,并自动执行它们。如果Python程序员能够按照约定(以test开头)来命名所有的测试方法,那就只需要在测试模块的最后加入如下几行代码即可:
if __name__=='__main__': unittest.main()
或者通过自己添加的方式决定哪些用例需要真正的被执行
def suite(): suite = unittest.TestSuite() suite.addTest(APITest("test_UserPermisionQueryGet")) suite.addTest(APITest("test_UserPermisionQueryPost")) runner = unittest.TextTestRunner() runner.run(suite)
当选择main函数作为入口的时候,还可以获取到帮助信息
python3 ./Request.py -h Usage: Request.py [options] Options: -h, --help show this help message and exit -v, --verbose Verbose output -q, --quiet Quiet output -f, --failfast Stop on first fail or error -c, --catch Catch ctrl-C and display results so far -b, --buffer Buffer stdout and stderr during tests
直接在命令行中指定testSuite.testcase
python3 ./Request.py APITest.test_UserPermisionQueryGet . ---------------------------------------------------------------------- Ran 1 test in 0.179s OK