読者です 読者をやめる 読者になる 読者になる

simudaru's blog

Python, Rなどのメモを残していこうと思います。  よろしくお願いいたします。

unittestを試してみました その1

テストコードをちゃんと書くことが今まであまりなかったので、unittestを使ってテストコードを書いてみました。
初めて使ったので、まずは最も基本的な使い方だけ。
例は単純なFizzBuzzで。

import unittest

def sample_func(n):
    if n % 3 == 0:
        if n % 5 == 0:
            return "FizzBuzz"
        else:
            return "Fizz"
    elif n % 5 == 0:
        return "Buzz"
    else:
        return n


class FactorialTest(unittest.TestCase):

    def setUp(self):
        pass

    def test_sample_func_with_arg_6(self):
        expected = "Fizz"
        actual = sample_func(6)
        self.assertEqual(expected, actual)

    def test_sample_func_with_arg_20(self):
        expected = "Buzz"
        actual = sample_func(20)
        self.assertEqual(expected, actual)

    def test_sample_func_with_arg_30(self):
        expected = "FizzBuzz"
        actual = sample_func(30)
        self.assertEqual(expected, actual)

    def test_sample_func_with_arg_11(self):
        expected = 11
        actual = sample_func(11)
        self.assertEqual(expected, actual)


if __name__ == "__main__":
    suite = unittest.TestLoader().loadTestsFromTestCase(FactorialTest)
    unittest.TextTestRunner(verbosity=2).run(suite)

クラスFactorialTestのなかに、複数のテスト関数を作ります。
テスト関数のなかでassertを使い、結果が期待通りになっているかをテストします。


assertとしては以下のようなメソッドがあります。

メソッド 確認事項
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)

テストクラスを作り、必要なテストを書いたら、
以下のようにして実行します。

suite = unittest.TestLoader().loadTestsFromTestCase(FactorialTest)
    unittest.TextTestRunner(verbosity=2).run(suite)

出力は以下のようになります。

test_sample_func_with_arg_11 (__main__.FactorialTest) ... ok
test_sample_func_with_arg_20 (__main__.FactorialTest) ... ok
test_sample_func_with_arg_30 (__main__.FactorialTest) ... ok
test_sample_func_with_arg_6 (__main__.FactorialTest) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.067s

OK


もっと簡単に書くなら、

    unittest.main()

でも実行でき、この場合はテストを通った場合は特に出力されません。

Ran 4 tests in 0.009s

OK
Exit code:  False


エラーがあると、エラー箇所を教えてくれます。

import unittest

def sample_func(n):
    if n % 3 == 0:
        return "Fizz"
        #if n % 5 == 0:
        #    return "FizzBuzz"
        #else:
        #    return "Fizz"
    elif n % 5 == 0:
        return "Buzz"
    #敢えてエラーを起こしてみる
    #else:
    #    return n


class FactorialTest(unittest.TestCase):

    def setUp(self):
        pass

    def test_sample_func_with_arg_6(self):
        expected = "Fizz"
        actual = sample_func(6)
        self.assertEqual(expected, actual)

    def test_sample_func_with_arg_20(self):
        expected = "Buzz"
        actual = sample_func(20)
        self.assertEqual(expected, actual)

    def test_sample_func_with_arg_30(self):
        expected = "FizzBuzz"
        actual = sample_func(30)
        self.assertEqual(expected, actual)

    def test_sample_func_with_arg_11(self):
        expected = 11
        actual = sample_func(11)
        self.assertEqual(expected, actual)


if __name__ == "__main__":
    suite = unittest.TestLoader().loadTestsFromTestCase(FactorialTest)
    unittest.TextTestRunner(verbosity=2).run(suite)
test_sample_func_with_arg_11 (__main__.FactorialTest) ... FAIL
test_sample_func_with_arg_20 (__main__.FactorialTest) ... ok
test_sample_func_with_arg_30 (__main__.FactorialTest) ... FAIL
test_sample_func_with_arg_6 (__main__.FactorialTest) ... ok

======================================================================
FAIL: test_sample_func_with_arg_11 (__main__.FactorialTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\yuichi2011\Documents\020.mywork\sourceTreeRepos\python\unittest_sample.py", line 40, in test_sample_func_with_arg_11
    self.assertEqual(expected, actual)
AssertionError: 11 != None

======================================================================
FAIL: test_sample_func_with_arg_30 (__main__.FactorialTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\yuichi2011\Documents\020.mywork\sourceTreeRepos\python\unittest_sample.py", line 35, in test_sample_func_with_arg_30
    self.assertEqual(expected, actual)
AssertionError: 'FizzBuzz' != 'Fizz'

----------------------------------------------------------------------
Ran 4 tests in 0.053s

FAILED (failures=2)


テスト前に行いたい処理は、setUp関数の中に書いておけばよいみたいです。


まずはここまで。
このようなフレームワークを使いながら、
テストをちゃんとしようと思います。

参考:

Life with Python
  http://www.lifewithpython.com/2014/03/unittest.html

公式ドキュメント
  http://docs.python.jp/2/library/unittest.html