「テスト駆動開発」(TDD:テスト駆動開発)について聞いたことがあるなら、単体テストは見知らぬ人ではありません。
ユニットテストは、モジュール、関数、またはクラスの正確さをテストするために使用されます。
たとえば、関数abs()の場合、次のテストケースを記述できます。
- 1、1.2、0.99などの正の数を入力し、戻り値が入力と同じになることを期待します。
- -1、-1.2、-0.99などの負の数を入力し、戻り値が入力と反対になることを期待します。
- 0を入力し、0を返すことを期待します。
- TypeErrorがスローされることを期待して、None、[]、{}などの非数値型を入力します。
上記のテストケースをテストモジュールに入れることは、完全な単体テストです。
単体テストに合格すると、テストした機能は正常に機能します。単体テストが失敗した場合は、関数にバグがあるか、テスト条件が正しく入力されていないため、単体テストに合格するには修正が必要です。
ユニットテストに合格するポイントは何ですか?abs()関数のコードを変更する場合は、単体テストを再度実行するだけで済みます。合格した場合は、変更がabs()関数の元の動作に影響を与えないことを意味します。テストが失敗した場合は、元の動作と矛盾する場合は、コードを変更するか、テストを変更してください。
このテスト駆動開発モデルの最大の利点は、プログラムモジュールの動作が設計したテストケースに準拠していることを確認することです。将来の変更では、モジュールの動作がまだ正しいことを大いに保証できます。
Dictクラスを書いてみましょう。このクラスの動作はdictの動作と同じですが、属性を介してアクセスできます。
>>> d = Dict(a=1, b=2)
>>> d['a']
1
>>> d.a
1
mydict.pyのコードは次のとおりです。
class Dict(dict):
def __init__(self, **kw)
super().__init__(**kw)
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
self[key] = value
ユニットテストを作成するには、Pythonに付属のunittestモジュールを導入し、mydict_test.pyを次のように作成する必要があります。
import unittest
from mydict import Dict
class TestDict(unittest.TestCase):
def test_init(self):
d = Dict(a=1, b='test')
self.assertEqual(d.a, 1)
self.assertEqual(d.b, 'test')
self.assertTrue(isinstance(d, dict))
def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEqual(d.key, 'value')
def test_attr(self):
d = Dict()
d.key = 'value'
self.assertTrue('key' in d)
self.assertEqual(d['key'], 'value')
def test_keyerror(self):
d = Dict()
with self.assertRaises(KeyError):
value = d['empty']
def test_attrerror(self):
d = Dict()
with self.assertRaises(AttributeError):
value = d.empty
単体テストを作成するときは、unittest.TestCaseから継承するテストクラスを作成する必要があります。
テストで始まるメソッドはテストメソッドです。テストで始まらないメソッドはテストメソッドとは見なされず、テスト中に実行されません。
test_xxx()メソッドは、テストのタイプごとに作成する必要があります。unittest.TestCaseは多くの組み込みの条件付き判断を提供するため、これらのメソッドを呼び出すだけで、出力が期待どおりかどうかを表明できます。最も一般的に使用されるアサーションはassertEqual()です。
self.assertEqual(abs(-1), 1) # 断言函数返回的结果与1相等
もう1つの重要なアサーションは、指定されたタイプのエラーをスローすることを期待することです。たとえば、d ['empty']を介して存在しないキーにアクセスすると、アサーションはKeyErrorをスローします。
with self.assertRaises(KeyError):
value = d['empty']