はじめに
PE部谷です。
テストコードという言葉は聞いたことあるけど、書いたことがなかったので、初めて調べてみました。
Pythonにはテストをサポートしてくれるライブラリがいくつかあるようで、今回はunittestを使ってみました。
テストコードってなに
自分が書いたコードが想定した通りに動いているかを確認するためのもの。
引数の2つの値を足して返す関数があるとします。 この関数に1と2を渡したら3で返ってくることを確認するのがテストコードです。
テストコードを書くメリット
機能を想定してテストコードは書かれるので、仕様書代わりになる。
不具合の再現がすぐにできる
デメリットとしては、コードを余計に書かなければいけないし、継続的にメンテナンスが必要になります。
これらのデメリットを少しでも軽くするために、テストをサポートしてくれるライブラリやツールがあります。
unittest
そんなテストコードを書くサポートをしてくれるライブラリのひとつがunittestです。 Python標準のライブラリなので、インストール不要です。
unittest公式ページ
書いてみる
環境はPython 3.6.8
app(アプリケーションコードを置く)とtests(テストコードを置く)の2つのディレクトを用意します。
基本的な計算をしてくれる関数を書いていきます。
app/calc.py
class Calc: def add(self, x, y): return x + y def minus(self, x, y): return x - y def multiply(self, x, y): return x * y def divide(self, x, y): return x / y
これに対するテストコードを書きます。
いくつか注意点があります。
unittestを使う場合、テストはTestCaseクラスのサブクラスとして作成します。
テストを行うメソッド名は"test"で始める必要があります。
TestCase クラスは失敗の検査と報告を行う多くのアサートメソッドを提供しています。
ここでは、assertEqual(a,b)を使って、a == bであることを確認します。
他にもいくつかメソッドが用意されているので、確認してみてください。
tests/test_calc.py
import unittest from app.calc import Calc sut = Calc() class CalcTestCase(unittest.TestCase): def test_add(self): self.assertEqual(sut.add(1, 2), 3) def test_minus(self): self.assertEqual(sut.minus(3, 2), 1) def test_multiply(self): self.assertEqual(sut.multiply(1, 2), 2) def test_divide(self): self.assertEqual(sut.divide(8, 2), 4) def foo(self): print("foo!!")
実行してみます。
$ python3 -m unittest tests.test_calc -v test_add (tests.test_calc.CalcTestCase) ... ok test_divide (tests.test_calc.CalcTestCase) ... ok test_minus (tests.test_calc.CalcTestCase) ... ok test_multiply (tests.test_calc.CalcTestCase) ... ok ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
テストメソッドが成功しています。
testがついていないfooメソッドは、実行されていません。
test_minusメソッドを
def test_minus(self): self.assertEqual(sut.minus(5, 2), 2)
にしてわざと失敗させてみます。
test_add (tests.test_calc.CalcTestCase) ... ok test_divide (tests.test_calc.CalcTestCase) ... ok test_minus (tests.test_calc.CalcTestCase) ... FAIL test_multiply (tests.test_calc.CalcTestCase) ... ok ====================================================================== FAIL: test_minus (tests.test_calc.CalcTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/ec2-user/kensho/tests/test_calc.py", line 11, in test_minus self.assertEqual(sut.minus(5, 2), 2) AssertionError: 3 != 2 ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1)
test_minusメソッドだけFAILになり、AssertionErrorになっています。
まとめ
テストコードの書き方わからない状態は脱することができました。
初歩的な使い方は理解できましたが、実際の開発でテストコードをどのように使っていくのかを勉強していきます。