【Python】unittestの使い方 実装・実行方法
この記事はPython標準のunittestの基本的な使い方についての備忘録です。
「テストコードの作成方法」「unittestの実行方法」について記載します。
はじめに
作業環境
今回は以下の環境でunittestを実装していきます。
Python 3.7.7
OS:windows
IDE:Visual Studio Code
テスト対象コードを準備
まずはテストしたいコードを作成します。
今回は単純に足し算を行うメソッドと割り算を行うメソッドを持つSampleClass
を作成しました。
# sample.py
class SampleClass():
"""テスト対象クラス"""
def calc_adder(self, num1, num2):
"""引数で受け取った値の和を返却する"""
return num1 + num2
def calc_divide(self, num1, num2):
"""引数で受け取った値の商を返却する"""
return num1 / num2
unittestのテストコードを作成する
上記のSampleClass
のテストコードを以下の手順で作成します。
- testから始まる名称でテストモジュールを作成する。
- テストクラスはunittest.TestCaseクラスを継承する。
- testから始まる名称でテストメソッドを作成する。
- テストメソッドに実施するテストの処理を記載する。
- アサーションメソッドを使用してテスト結果を確認する。
ちなみに、unittestはPython標準の機能であるため、別途インストールは不要です。
# test_sample.py
from unittest import TestCase
from sample import SampleClass
class SampleClassTest(TestCase):
"""SampleClassのテストクラス"""
def setUp(self):
self.sample = SampleClass()
def test_calc_adder(self):
"""calc_adderメソッドのテスト"""
result = self.sample.calc_adder(num1=10, num2=5)
self.assertEqual(result, 15)
def test_calc_divide(self):
"""calc_divideメソッドのテスト"""
result = self.sample.calc_divide(num1=10, num2=5)
self.assertEqual(result, 2)
def tearDown(self):
del self.sample
「test_sample.py」という名称で上記のテストコードを作成しました。
簡単にテストクラスの説明をします。
- 1行目:unittest.TestClassクラスを継承するためにTestClassクラスをimport。
- 3行目:テスト対象クラスのimport。
- 6行目:TestClassクラスを継承したテストクラスを定義。
- 11行目~21行目:テストメソッド。テスト対象のメソッドに任意の数値を渡して実行し、想定通り結果が返ってくるかアサーションメソッドを使用して確認する。
ざっくり説明すると上記の通りです。
また、今回の例ではテストモジュールをtestsというパッケージを作成し、その中にテストモジュールを作成しました。
実際の開発では、テストモジュールを複数作ることになると思うので、テストモジュールを格納する専用のパッケージを用意しています。
ディレクトリ構成は以下のようになります。
$ tree /f
.
│ sample.py
│
└─tests
test_sample.py
setUpメソッド・tearDownメソッド
8行目のsetUp
メソッドはテストメソッドが実行される前に必ず実施されるメソッドです。
23行目のtearDown
メソッドはテストメソッドの実行後に必ず実施されるメソッドです。
上記のテストコードの実行順序は以下のようになります。
②setUpメソッド → test_calc_divide → tearDownメソッド
各テストメソッドで共通の初期処理やテスト対象クラスを実施するための前提条件となる処理等を記載すると良いと思います。
例えば、テスト用のマスタデータなどをテストメソッド実行前にデータベースに登録して、テストメソッド実行後に削除する等といった使い方ができそうですね。
今回の「test_sample.py」では、テストメソッドの実施前にテスト対象クラスのインスタンスを生成し、テストメソッド実行後にインスタンスを破棄するといった用途で使用しています。
unittestを実行する
では実際に上記のテストコードを実行してみます。
unittestの実行は以下のコマンドで行います。
<testsフォルダ内のすべてのテストモジュールを実行する場合>
例:
python -m unittest discover tests
<実行するテストモジュールを指定する場合>
例:
python -m unittest tests.test_sample
<実行するテストクラスを指定する場合>
例:
python -m unittest tests.test_sample.SampleClassTest
<実行するテストメソッドを指定する場合>
例:
python -m unittest tests.test_sample.SampleClassTest.test_calc_adder
今回はテストモジュールを指定して実行してみます。
$ python -m unittest tests.test_sample
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
「Ran 2 tests」と表示されています。これは2つのテストメソッドが実行されたことを意味します。
そして最後に「OK」と表示されています。実行したテストがすべて成功するとこのように「OK」と表示されます。
では、テストメソッドをもう1つ増やしてみましょう。
追加したテストメソッドでは、割る数(num2)がゼロの場合は、0が返ってくることを想定しています。
def test_calc_divide_zerodivide(self):
"""calc_divideメソッドの割る数がゼロの場合のテスト"""
result = self.sample.calc_divide(num1=10, num2=0)
self.assertEqual(result, 0)
今度は追加したテストメソッドだけを実行してみます。
$ python -m unittest tests.test_sample.SampleClassTest.test_calc_divide_zerodivide
E
======================================================================
ERROR: test_calc_divide_zerodivide (tests.test_sample.SampleClassTest)
calc_divideメソッドのテスト
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\python\demo_unittest\tests\test_sample.py", line 25, in test_calc_divide_zerodivide
result = self.sample.calc_divide(num1=10, num2=0)
File "D:\python\demo_unittest\sample.py", line 10, in calc_divide
return num1 / num2
ZeroDivisionError: division by zero
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
今度は「Ran 1 test」となっており、指定したメソッドのみ実行されたことが確認できます。
また、テスト結果が「FAILED (errors=1)」となっており、テスト対象メソッドでZeroDivisionError
が発生していることが確認できます。
calc_divideメソッドでは0割の考慮が漏れていたため割る数がゼロの場合はゼロを返却するように修正します。
def calc_divide(self, num1, num2):
"""引数で受け取った値の商を返却する"""
if num2 == 0:
return 0
else:
return num1 / num2
そして、改めてunittestを実行してみます。
$ python -m unittest tests.test_sample.SampleClassTest.test_calc_divide_zerodivide
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
成功しました。
ちなみに、先ほどのテスト失敗はテスト対象クラスで想定外の例外エラーが発生した場合でしたが、
実行結果と想定値が違う場合は以下のように「AssertionError」が表示されます。
$ python -m unittest tests.test_sample.SampleClassTest.test_calc_divide
F
======================================================================
FAIL: test_calc_divide (tests.test_sample.SampleClassTest)
calc_divideメソッドのテスト
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\python\demo_unittest\tests\test_sample.py", line 21, in test_calc_divide
self.assertEqual(result, 3)
AssertionError: 2.0 != 3
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
まとめ
今回はunittestのテストコードの作成方法、実行方法について記載しました。
特に以下の2点についてはしっかりと抑えて、次の機会に活かしたいと思いました。
①テストモジュールは以下の内容で作成する。
- testから始まる名称でテストモジュールを作成する。
- テストクラスはunittest.TestCaseクラスを継承する。
- testから始まる名称でテストメソッドを作成する。
②unittestの実行単位を状況に応じて使い分ける。
参考文献
実際に作業を実施した際には、以下のサイトを参考にさせていただきました。
・公式ドキュメント
https://docs.python.org/ja/3.7/library/unittest.html
・Python標準のunittestの使い方メモ
https://qiita.com/aomidro/items/3e3449fde924893f18ca#references
・Pythonでunittestを実行する(初心者用)
https://qiita.com/takus69/items/cde279266b46daf9972d
unittestの使い方については、他にもいろいろ記載しています。
よろしければ見ていってください。
ディスカッション
コメント一覧
まだ、コメントがありません