python中提供了很是簡單的單元測試方式,利用nose
包中的nosetests
命令能夠實現簡單的批量測試。python
安裝nose
包網絡
sudo pip install nose
編輯測試文件app
# test_true.py def test_true(): assert True def test_false(): assert False
執行測試python2.7
# 命令, nosetests命令會加載全部以test_開頭的文件,並執行全部以test_開頭的函數 nosetests -v # 輸出 test_true.test_true ... ok test_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 False AssertionError ---------------------------------------------------------------------- Ran 2 tests in 0.007s FAILED (failures=1
unittest
是python提供了單元測試的標準庫。ide
# 爲了兼容python 2.6和2.7 try: import unittest2 as unittest except ImportError: import unittest class 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.006s FAILED (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
模塊能夠用來臨時改變當前的測試環境。fetch
import fixtures import os class 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
模塊能夠用來進行模擬測試,其主要功能就是模擬一個函數,類或實例的行爲。ui
因爲網絡測試環境的特殊性,最經常使用的使用就是模擬網絡請求,具體例子以下,
# test_mock.py import requests import unittest import mock class WhereIsPythonError(Exception): pass def 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_get def 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) ... ok test_python_is_not (test_mock.TestPython) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK