unittest附带了许多断言方法。我使用内置的Python assert
和比较运算符vs内置的简单unittest断言进行了时间测试。
#!/usr/bin/python
import timeit
s = """\
import unittest
class TestRepomanManExtFunctions(unittest.TestCase):
def test1(self):
someObj = object()
newObj = someObj
self.assertEqual(someObj, newObj)
def test2(self):
str1 = '11111111111111111111111111111111111111'
str2 = '33333333333333333333333333333333333333'
self.assertNotEqual(str1, str2)
if __name__ == '__main__':
unittest.main()
"""
t = timeit.Timer(stmt=s)
print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
s2 = """\
import unittest
class TestRepomanManExtFunctions(unittest.TestCase):
def test1(self):
someObj = object()
newObj = someObj
assert someObj == newObj
def test2(self):
str1 = '11111111111111111111111111111111111111'
str2 = '33333333333333333333333333333333333333'
assert str1 != str2
if __name__ == '__main__':
unittest.main()
"""
t = timeit.Timer(stmt=s2)
print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
结果
yeukhon@yeukhon-P5E-VM-DO:/tests$ python t.py
1203.46 usec/pass
873.06 usec/pass
yeukhon@yeukhon-P5E-VM-DO:tests$ vim t.py
yeukhon@yeukhon-P5E-VM-DO:tests$ python t.py
1300.33 usec/pass
956.35 usec/pass
yeukhon@yeukhon-P5E-VM-DO:tests$ python t.py
1208.82 usec/pass
865.18 usec/pass
使用unittest的内置断言方法的一个优点是它告诉用户实际比较的是什么。我的实际测试的一个例子:
======================================================================
FAIL: test_000_write_to_file_directory_not_exist (__main__.TestRepomanManExtFunctions)
Test writing content to a new file whose parent directory
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1224, in patched
return func(*args, **keywargs)
File "test_ext.py", line 71, in test_000_write_to_file_directory_not_exist
self.assertNotEqual(mk_exists.call_args_list, exists_call_list)
AssertionError: [call('/tmp/test/fake/')] == [call('/tmp/test/fake/')]
这是使用简单的assert X = Y
======================================================================
FAIL: test_000_write_to_file_directory_not_exist (__main__.TestRepomanManExtFunctions)
Test writing content to a new file whose parent directory
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1224, in patched
return func(*args, **keywargs)
File "test_ext.py", line 72, in test_000_write_to_file_directory_not_exist
assert exists_call_list != mk_exists.call_args_list
AssertionError
除了这个优势之外,利用内置self.assert_*(...)
还可以做些什么呢?
为什么原料更快?我知道访问属性和对类的检查通常较慢。但是我想知道发生了什么?我希望这是一个有效的问题。
由于
答案 0 :(得分:1)
断言*函数可能较慢,因为调用它有开销(将参数推送到堆栈,调用,从堆栈中弹出返回地址等),与内联执行的assert关键字相比。断言*函数有一些其他很好的属性,如你所提到的,比如打印预期值和实际值。
你是出于好奇而不是这是一个真正的问题吗?我很惊讶地发现任何断言速度都是瓶颈的情况。
答案 1 :(得分:0)
当单元测试由您使用的单元测试库提供的断言时,会收集有关测试的更多信息。他们收集枯萎测试成功或失败,导致错误的原因,捕获抛出的异常以及测试的任何输出。然后将此数据集合操作为stdout或xml文件所需的任何输出。这只需要花费时间并且需要大量的功能开销才能完成,其中单个断言就像或多或少的内联一样,并且显示错误以及文件和行号。
幕后两者之间存在巨大差异。