はじめに
Python の動的な性質により、テストはほとんどのアプリケーションにとって極めて重要です。バグを見つけるためのコンパイラはありません。バグを見つける唯一の方法は、コードを実行して、そのすべての機能を試してみることです。
This tutorial is from open-source community. Access the source code
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
Python の動的な性質により、テストはほとんどのアプリケーションにとって極めて重要です。バグを見つけるためのコンパイラはありません。バグを見つける唯一の方法は、コードを実行して、そのすべての機能を試してみることです。
assert
文は、プログラムの内部チェックに使用されます。式が真でない場合、AssertionError
例外を発生させます。
assert
文の構文。
assert <式> [, '診断メッセージ']
例。
assert isinstance(10, int), 'Expected int'
ユーザー入力(つまり、Web フォームなどで入力されたデータ)をチェックするためには使用しないでください。その目的は、主に内部チェックと不変条件(常に真であるはずの条件)のためです。
契約による設計とも呼ばれ、アサーションを十分に利用することはソフトウェアを設計するためのアプローチです。ソフトウェアのコンポーネントに対して正確なインターフェイス仕様を定義するようソフトウェア設計者に求めます。
たとえば、関数のすべての入力にアサーションを置くことができます。
def add(x, y):
assert isinstance(x, int), 'Expected int'
assert isinstance(y, int), 'Expected int'
return x + y
入力をチェックすることで、適切な引数を使用していない呼び出し元を直ちにキャッチすることができます。
>>> add(2, 3)
5
>>> add('2', '3')
Traceback (most recent call last):
...
AssertionError: Expected int
>>>
アサーションは、単純なテストにも使用できます。
def add(x, y):
return x + y
assert add(2,2) == 4
このようにして、コードと同じモジュールにテストを含めることができます。
利点:コードが明らかに破損している場合、モジュールをインポートしようとするとクラッシュします。
これは網羅的なテストには推奨されません。基本的な「スモークテスト」に近いものです。関数が何らかの例で機能するかどうかです。もし機能しない場合、何かが間違っていることは確かです。
unittest
モジュールsimple.py
にいくつかのコードがあるとしましょう。
## simple.py
def add(x, y):
return x + y
次に、それをテストしたいとします。/home/labex/project/test_simple.py
にこのような別のテストファイルを作成します。
## test_simple.py
import simple
import unittest
そして、テストクラスを定義します。
## test_simple.py
import simple
import unittest
## 注意:unittest.TestCase から継承しています
class TestAdd(unittest.TestCase):
...
テストクラスは unittest.TestCase
から継承する必要があります。
テストクラスの中で、テストメソッドを定義します。
## test_simple.py
import simple
import unittest
## 注意:unittest.TestCase から継承しています
class TestAdd(unittest.TestCase):
def test_simple(self):
## 単純な整数引数でテスト
r = simple.add(2, 2)
self.assertEqual(r, 5)
def test_str(self):
## 文字列を使ったテスト
r = simple.add('hello', 'world')
self.assertEqual(r, 'helloworld')
*重要:各メソッドは test
で始める必要があります。
unittest
の使用方法unittest
にはいくつかの組み込みアサーションがあります。それぞれが異なることをアサートします。
## expr が真であることをアサートする
self.assertTrue(expr)
## x == y であることをアサートする
self.assertEqual(x,y)
## x!= y であることをアサートする
self.assertNotEqual(x,y)
## x が y に近いことをアサートする
self.assertAlmostEqual(x,y,places)
## callable(arg1,arg2,...) が exc を発生させることをアサートする
self.assertRaises(exc, callable, arg1, arg2,...)
これは網羅的な一覧ではありません。モジュールには他にもアサーションがあります。
unittest
の実行テストを実行するには、コードをスクリプトに変換します。
## test_simple.py
...
if __name__ == '__main__':
unittest.main()
そして、テストファイルで Python を実行します。
$ python3 test_simple.py
F.
========================================================
FAIL: test_simple (__main__.TestAdd)
--------------------------------------------------------
Traceback (most recent call last):
File "testsimple.py", line 8, in test_simple
self.assertEqual(r, 5)
AssertionError: 4!= 5
--------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
効果的な単体テストは技術であり、大規模なアプリケーションではかなり複雑になることがあります。
unittest
モジュールには、テストランナー、結果の収集、およびテストのその他の側面に関連する多数のオプションがあります。詳細については、ドキュメントを参照してください。
組み込みの unittest
モジュールはどこでも利用できるという利点があります。Python の一部ですからです。しかし、多くのプログラマーはこれが非常に冗長であると感じています。人気のある代替策は pytest です。pytest を使うと、テストファイルは次のように簡略化されます。
## test_simple.py
import simple
def test_simple():
assert simple.add(2,2) == 4
def test_str():
assert simple.add('hello','world') == 'helloworld'
テストを実行するには、python -m pytest
のようなコマンドを入力するだけです。すると、すべてのテストを見つけて実行します。このモジュールは pip install pytest
を使ってインストールできます。
この例だけでは pytest
についてはまだたくさんありますが、試してみることにした場合は、通常簡単に始めることができます。
この演習では、Python の unittest
モジュールを使う基本的な仕組みを調べます。
以前の演習では、Stock
クラスを含む stock.py
ファイルを書きました。この演習では、7.9 の演習で書かれた型付きプロパティを含むコードを使っていると仮定しています。何らかの理由でそれが機能しない場合は、Solutions/7_9
のソリューションを作業ディレクトリにコピーすることができます。
別のファイル test_stock.py
で、Stock
クラスの単体テストのセットを書きます。始めに、インスタンス作成をテストする小さなコード断片を以下に示します。
## test_stock.py
import unittest
import stock
class TestStock(unittest.TestCase):
def test_create(self):
s = stock.Stock('GOOG', 100, 490.1)
self.assertEqual(s.name, 'GOOG')
self.assertEqual(s.shares, 100)
self.assertEqual(s.price, 490.1)
if __name__ == '__main__':
unittest.main()
単体テストを実行します。以下のような出力が得られるはずです。
Ran 1 tests in 0.000s
OK
機能することが確認できたら、以下をチェックする追加の単体テストを書きます。
s.cost
プロパティが正しい値(49010.0)を返すことを確認する。s.sell()
メソッドが正しく機能することを確認する。s.shares
の値がそれに応じて減少する必要がある。s.shares
属性が整数以外の値に設定できないことを確認する。最後の部分では、例外が発生することを確認する必要があります。それを行う簡単な方法は、以下のようなコードを使うことです。
class TestStock(unittest.TestCase):
...
def test_bad_shares(self):
s = stock.Stock('GOOG', 100, 490.1)
with self.assertRaises(TypeError):
s.shares = '100'
おめでとうございます! あなたはテストの実験を完了しました。あなたの技術を向上させるために、LabExでさらに多くの実験を練習することができます。