本文共 3725 字,大约阅读时间需要 12 分钟。
python中提供了非常简单的单元测试方式,利用nose
包中的nosetests
命令可以实现简单的批量测试。
安装nose
包
sudo pip install nose
编辑测试文件
# test_true.pydef test_true(): assert Truedef test_false(): assert False
执行测试
# 命令, nosetests命令会加载所有以test_开头的文件,并执行所有以test_开头的函数nosetests -v# 输出test_true.test_true ... oktest_true.test_false ... FAIL======================================================================FAIL: test_true.test_false----------------------------------------------------------------------Traceback (most recent call last): File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) File "/xxxx/workspace/py/test/test_true.py", line 5, in test_false assert FalseAssertionError----------------------------------------------------------------------Ran 2 tests in 0.007sFAILED (failures=1
unittest
是python提供了单元测试的标准库。
# 为了兼容python 2.6和2.7try: import unittest2 as unittestexcept ImportError: import unittestclass TestKey(unittest.TestCase): def test_keyh(self): a = ['a'] b = ['a', 'b'] self.assertEqual(a, b)
输出如下,
test_keyh (test_true.TestKey) ... FAIL======================================================================FAIL: test_keyh (test_true.TestKey)----------------------------------------------------------------------Traceback (most recent call last): File "/home/y/workspace/py/test/test_true.py", line 8, in test_keyh self.assertEqual(a, b)AssertionError: Lists differ: ['a'] != ['a', 'b']Second list contains 1 additional elements.First extra element 1:b- ['a']+ ['a', 'b']----------------------------------------------------------------------Ran 1 test in 0.006sFAILED (failures=1)
此外,unittest.skipIf
可以通过判断条件来选择是否进行测试,
class TestSkipped(unittest.TestCase): @unitttest.skip("Do not run this") def test_failt(self): self.fail("This should not be run") @unittest.skipIf(mylib is None, "mylib is not available") def test_mylib(self): self.assertEqual(1, 1)
此外,自定义setUp
和tearDown
函数可以单元测试开始和结束时自动调用。
fixtures
模块可以用来临时改变当前的测试环境。
import fixturesimport osclass TestEnviron(fixtures.TestWithFixtures): def test_environ(self): fixture = self.useFixture( fixtures.EnvironmentVariable("FOOBAR", "42")) # 临时增加一个环境变量FOOBAR self.assertEqual(os.environ.get("FOOBAR"), "42") def test_environ_no_fixture(self): self.assertEqual(os.environ.get("FOOBAR"), None) # 上面增加的环境变量的操作对于其他函数无效
mock
模块可以用来进行模拟测试,其主要功能就是模拟一个函数,类或实例的行为。
由于网络测试环境的特殊性,最常用的使用就是模拟网络请求,具体例子如下,
# test_mock.pyimport requestsimport unittestimport mockclass WhereIsPythonError(Exception): passdef is_python(): try: r = requests.get("http://python.org") except IOError: pass else: if r.status_code == 200: return 'is python' in r.content raise WhereIsPythonError('something happened')def get_fake_get(status_code, content): m = mock.Mock() m.status_code = status_code m.content = content def fake_get(url): return m return fake_getdef raise_get(url): raise IOError("unable to fetch url %s" % url)class TestPython(unittest.TestCase): @mock.patch('requests.get', get_fake_get( 200, 'is python, hello' )) def test_python_is(self): self.assertTrue(is_python()) @mock.patch('requests.get', get_fake_get( 200, 'is not python, hello' )) def test_python_is_not(self): self.assertFalse(is_python())
输出如下,
# 命令nosetests --tests=test_mock -v# 结果test_python_is (test_mock.TestPython) ... oktest_python_is_not (test_mock.TestPython) ... ok----------------------------------------------------------------------Ran 2 tests in 0.001sOK本文转自cococo点点博客园博客,原文链接:http://www.cnblogs.com/coder2012/p/5092190.html,如需转载请自行联系原作者