Pythonの単体テストを書く
世間は新元号が発表されましたがそれはそうとして今回は unittest
というPython標準のモジュールを利用して単体テストを書いてみたいと思います。
テスト対象
FizzBuzzというビギナー開発者にありがちな課題を雑に書き下したものです。3の倍数でFizzを、5の倍数でBuzzを、公倍数でFizzBuzzという文字列を出力するというアレですね。イメージ湧かない方はナベアツの3の付く数字と3の倍数でバカになるネタを思い浮かべていただければ。
def fizzbuzz(number):
"""
3の倍数ならFizz、5の倍数ならBuzz、15の倍数ならFizzBuzzを出力する
Parameters
----------
number : int
数値
Returns
-------
ret : str, int
倍数に対応する文字列、もしくは入力された数値そのもの
"""
if type(number) != int:
raise TypeError
if number % 15 == 0:
return "FizzBuzz"
if number % 5 == 0:
return "Buzz"
if number % 3 == 0:
return "Fizz"
return number
if __name__ == "__main__":
for i in range(1, 101):
print(fizzbuzz(i))
テストコード
シンプルに通常の数値を返すケースとFizz、Buzz、FizzBuzzそれぞれを返すケース、あとパラメータに数値以外が渡された例外ハンドルのケースも書いてみます。 exit=False
としているのはVSCodeでデバッグした時に問答無用で異常終了するのが気持ち悪かったという精神安定剤的な意味合いです。
import unittest
from src.fizzbuzz import fizzbuzz
class FizzBuzzTest(unittest.TestCase):
"""
FizzBuzzのテストクラス
"""
def setUp(self):
"""
テストフィクスチャの準備のために呼び出されるメソッド
"""
return super().setUp()
def tearDown(self):
"""
テストメソッドが実行され、結果が記録された直後に呼び出されるメソッド
"""
return super().tearDown()
def test_normal(self):
"""
数字を返すケース
"""
self.assertEqual(1, fizzbuzz(1))
def test_fizz(self):
"""
Fizzを返すケース
"""
self.assertEqual("Fizz", fizzbuzz(3))
def test_buzz(self):
"""
Buzzを返すケース
"""
self.assertEqual("Buzz", fizzbuzz(5))
def test_fizzbuzz(self):
"""
FizzBuzzを返すケース
"""
self.assertEqual("FizzBuzz", fizzbuzz(15))
def test_typeerror(self):
"""
TypeErrorを返すケース
"""
with self.assertRaises(TypeError):
fizzbuzz("abc")
if __name__ == "__main__":
unittest.main(exit=False)
で、実行します。
$ python -m unittest discover tests --verbose
test_buzz (test_fizzbuzz.FizzBuzzTest) ... ok
test_fizz (test_fizzbuzz.FizzBuzzTest) ... ok
test_fizzbuzz (test_fizzbuzz.FizzBuzzTest) ... ok
test_normal (test_fizzbuzz.FizzBuzzTest) ... ok
test_typeerror (test_fizzbuzz.FizzBuzzTest) ... ok
----------------------------------------------------------------------
Ran 5 tests in 0.000s
OK