测试 我推荐使用nose 或是py.test 。我大部分情况下用nose 。它们基本上是类似的。我将讲解nose的一些细节。 这里有一个人为创建的可笑的使用nose进行测试的例子。在一个以test_ 开头的文件中的所有以test_ 开头的函数,都会被调用: 1 2 | def test_equality():
assert True = = False
|
不出所料,当运行nose的时候,我们的测试没有通过。 1 2 3 4 5 6 7 8 9 10 11 12 13 | ( test )jhaddad@jons-mac-pro ~VIRTUAL_ENV /src $ nosetests
F
======================================================================
FAIL: test_nose_example.test_equality
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jhaddad/.virtualenvs/test/lib/python2.7/site-packages/nose/case.py" , line 197, in runTest
self. test (*self.arg)
File "/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py" , line 3, in test_equality
assert True == False
AssertionError
----------------------------------------------------------------------
|
nose.tools中同样也有一些便捷的方法可以调用 1 2 3 | from nose.tools import assert_true
def test_equality():
assert_true( False )
|
如果你想使用更加类似JUnit的方法,也是可以的: 1 2 3 4 5 6 7 8 9 10 | from nose.tools import assert_true
from unittest import TestCase
class ExampleTest(TestCase):
def setUp( self ):
self .blah = False
def test_blah( self ):
self .assertTrue( self .blah)
|
开始测试: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ( test )jhaddad@jons-mac-pro ~VIRTUAL_ENV /src $ nosetests
F
======================================================================
FAIL: test_blah (test_nose_example.ExampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py" , line 11, in test_blah
self.assertTrue(self.blah)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 1 test in 0.003s
FAILED (failures=1)
|
卓越的Mock库包含在Python 3 中,但是如果你在使用Python 2,可以使用pypi来获取。这个测试将进行一个远程调用,但是这次调用将耗时10s。这个例子显然是人为捏造的。我们使用mock来返回样本数据而不是真正的进行调用。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import mock
from mock import patch
from time import sleep
class Sweetness( object ):
def slow_remote_call( self ):
sleep( 10 )
return "some_data"
def test_long_call():
s = Sweetness()
result = s.slow_remote_call()
assert result = = "some_data"
|
当然,我们的测试需要很长的时间。 1 2 3 4 5 | ( test )jhaddad@jons-mac-pro ~VIRTUAL_ENV /src $ nosetests test_mock.py
Ran 1 test in 10.001s
OK
|
太慢了!因此我们会问自己,我们在测试什么?我们需要测试远程调用是否有用,还是我们要测试当我们获得数据后要做什么?大多数情况下是后者。让我们摆脱这个愚蠢的远程调用吧: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import mock
from mock import patch
from time import sleep
class Sweetness( object ):
def slow_remote_call( self ):
sleep( 10 )
return "some_data"
def test_long_call():
s = Sweetness()
with patch. object (s, "slow_remote_call" , return_value = "some_data" ):
result = s.slow_remote_call()
assert result = = "some_data"
|
好吧,让我们再试一次: 1 2 3 4 5 6 | ( test )jhaddad@jons-mac-pro ~VIRTUAL_ENV /src $ nosetests test_mock.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
|
好多了。记住,这个例子进行了荒唐的简化。就我个人来讲,我仅仅会忽略从远程系统的调用,而不是我的数据库调用。
nose-progressive是一个很好的模块,它可以改善nose的输出,让错误在发生时就显示出来,而不是留到最后。如果你的测试需要花费一定的时间,那么这是件好事。
pip install nose-progressive 并且在你的nosetests 中添加--with-progressive
|