码迷,mamicode.com
首页 > 编程语言 > 详细

Python unittest 学习

时间:2017-03-24 10:52:16      阅读:358      评论:0      收藏:0      [点我收藏+]

标签:ack   mod   response   toc   函数   back   key   assm   log   

import unittest
 
class UTest(unittest.TestCase):
    def test_upper(self):
      self.assertEqual(foo.upper(), FOO)
 
  def test_isupper(self):
    self.assertTrue(FOO.isupper())
    self.assertFalse(Foo.isupper())
 
if __name__ == __main__:
unittest.main()

 

注:
0. unnitest 是 python 自带的库,不需要额外的安装即可用
 
1. 测试用例 (testcase) 都是由 unittest.TestCase 类创建的,对应的 test 开头的 测试方法, 如上例的 test_upper
 
2. setUp() and tearDown() 方法用来定义一些初始化和清理的 指令, 这两个方法分别在 每个测试用例 开始前和结束后执行。
如果只要在所有的测试用例之前和之后只执行一次,则用 setUpClass() 和 tearDownClass()
如果所有的测试用例都需要执行的一些共同步骤可以放在setUp(), 如果做一次就对所有的测试用例生效的就放在setUpClass(),譬如登陆(coolie对所有的测试用例都可以共享)
setupClass() 和 tearDownClass() 必需加上装饰器 @classmethod, 否则会出错。 setUp() 和 tearDown() 则不用。
 
3. unittest.main()提供了一个测试脚本的命令行接口。
 
4. 其他途径运行测试用例有:
suite = unittest.TestLoader().loadTestsFromTestCase(UTest)
unittest.TextTestRunner(verbosity=2).run(suite)

 

5. 命令行: python -m unittest test_module.TestClass 和 python -m unittest test_module.TestClass.test_method
如上面的例子:python -m unittest UTest.UTest
python -m unittest UTest.UTest.test_upper
 
还可以传一个 -v 标志 来获取 更详细的测试结果:python -m unittest -v test_module
如上例: D:\Python>python -m unittest -v UTest
结果: test_isupper (UTest.UTest) ... ok
test_upper (UTest.UTest) ... ok
 
6. 要运行一个class 里的 所有测试用例(所有test开头的方法),有以下几种方法:
A. unittest.main() 对应的命令行 是 ptyon module.py
B. suite = unittest.TestLoader().loadTestsFromTestCase(UTest)
unittest.TextTestRunner(verbosity=2).run(suite)
对应的命令行是 python -m unittest test_module.TestClass
C. 新建一个TestSuite 实例,然后一个一个的把所有的测试用例加到这个测试集,最后通过 TextTestRunner 这个对象的run方法运行测试集
如,此方法比较繁琐,加入有50个测试用例,需要手动的把50个用例一个一个的加到TestSuite 里
suite = unittest.TestSuite()
suite.addTest(UTest(test_isupper))
suite.addTest(UTest(test_upper))
runner = unittest.TextTestRunner()
runner.run(suite)

但是,如果是class 里只有一个测试方法,但测试时需要不同的测试数据,C 的方法派上用场:

a.首先,重写TestCase类的构造函数,把input 作为构造函数的参数(由于测试方法不能传参数,所以只能在构造函数里传入需要的input),如:
def __init__(self, marketcode, stockcode, stocktype,methodName):
    super(Comparison, self).__init__(methodName)
    self.marketcode = marketcode
    self.stockcode = stockcode
    self.stocktype = stocktype
 
b. 然后是测试用例方法对input的引用
def test_getPriceInfo(self):
    stime = Utils.getTimestamp()
    mkt_price = ParseResponse.getMarketLastPrice(self.marketcode,self.stockcode,self.stocktype)
    position_price = ParseResponse.getPositionLastPrice(self.loginKey,self.loginCookie,self.stockcode,self.marketcode)
    self.infoDir["timestamp"] = stime
    self.infoDir["ticker"] = self.marketcode + self.stockcode
    self.infoDir["postionprice"] = position_price
    self.infoDir["marketprice"] = mkt_price
    AlertRecorder.cmpMktPosition(self.infoDir)
    print self.infoDir

 

c. 最后在class 外定义一个运行的方法,其中 Comparison(stockInfo[0],stockInfo[1],stockInfo[2], "test_getPriceInfo") 即是创建一个测试类示例,test_getPriceInfo为测试用例方法名,这个是 unittest.TestCase类需要的参数。

def run():
    suite = unittest.TestSuite()
    stockInfoList = Scheduler.get_mktPostion_stocks()
    for stockInfo in stockInfoList:
        suite.addTest(Comparison(stockInfo[0],stockInfo[1],stockInfo[2], "test_getPriceInfo"))
    runner = unittest.TextTestRunner()
    runner.run(suite)

 

综上,封装起来为:
A. .main(verbosity=2), 其中verbosity=2 是使得结果输出时更详细
B.
def run():
  suite = unittest.TestLoader().loadTestsFromTestCase(testCaseClassName)
  runner = unittest.TextTestRunner(verbosity=2)
  runner.run(suite)
C.
def run():
  suite = unittest.TestSuite()
  suite.addTest(testCaseClassName(test_method))
  runner = unittest.TextTestRunner(verbosity=2)
  runner.run(suite)

 

注意:上述三个运行测试的方法,在IDE上的输出结果有点差别。A 和 C 输出的结果:
set up for class
test_isupper (__main__.UTest) ... ok
test_sum (__main__.UTest) ... ok
test_upper (__main__.UTest) ... ok
 
而B输出结果为:
test_sum (__main__.UTest) ... ok
test_upper (__main__.UTest) ... ok
set up for class
test_isupper (__main__.UTest) ... ok
 
优先还是用 unittest.main() 和 unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(testCaseClassName))
 
 
7. 如果要跳过测试,则可以用到 装饰器 @unittest.skip("reason") 和 @unittest.skipIf(condition,‘reason‘). 如果是针对个别测试用例,则在 测试用例方法加装饰器。如果需要跳过所有的测试(譬如节假日)则在 setUpClass 上加装饰器。这种情况下得注意两个装饰器的先后顺序,先@classmethod 后 @unittest.skipIf()。如:
@classmethod
@unittest.skipIf(True, "To skip the test")
def setUpClass(cls):
print ‘set up for class‘
 
另外,setUp()也可以跳过所有的测试,不过和 setUpClass 有区别: setUpClass 是一次性跳过所有的测试,运行结果显示运行0个测试: Ran 0 tests in 0.000s OK (skipped=1)
但setUp 则是每个测试用例都跳过运行,显示结果是跑了N 个,跳过N 个:
test_isupper (__main__.UTest) ... skipped ‘...reason...‘
test_sum (__main__.UTest) ... skipped ‘...reason...‘
test_upper (__main__.UTest) ... skipped ‘...reason...‘
 
 
8. 如果要获得测试结果中运行的测试用例的总数以及成功和失败的总数,可以从unittest.TestResult 中获得 失败的个数和运行的总数
suite = unittest.TestLoader().loadTestsFromTestCase(UTest)
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
print result.testsRun #运行的测试用例的总数
print len(result.failures) #失败的测试用例的数目

 

关于 failures: A list containing 2-tuples of TestCase instances and strings holding formatted tracebacks. Each tuple represents a test where a failure was explicitly
signalled using the TestCase.assert*() methods.

Python unittest 学习

标签:ack   mod   response   toc   函数   back   key   assm   log   

原文地址:http://www.cnblogs.com/tomweng/p/6609918.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!