PythonのParameterized Test
@rch850さんが何時の日か、「PythonでParametrized Testってできんの?」ということをついったーでつぶやいていたのを見て気になったので実装してみた。
Parameterized Testの詳細はぶっちゃけわからんかったしxUnit Test Patternsのクソ厚いページから探すのはちょっとはばかられたので、id:bleis-tift氏の書いていたNUnitのParameterizedテスト*1の書き方を参考にして自分色に染め上げてみた。
故に間違っている箇所もいくつかあるかもしれない。この辺はあとでちゃんとxUnit Test Patternsなり見てフィードバックしようかと。
コード
というわけで以下。
NUnitがアノテーション(って呼ぶのか?)で実装していたので、それに対応する機能といえばやっぱりデコレータかなあということでデコレータを使って指定。
#! python # coding:utf-8 import unittest def fizzbuzz(num): if num % 15 == 0: return "fizzbuzz" elif num % 3 == 0: return "fizz" elif num % 5 == 0: return "buzz" return str(num) def paramterized_test(**kwargs): def _paramterized_test(func): def __paramterized_test(*args): func(args[0], kwargs) return func return __paramterized_test return _paramterized_test class TestFizzbuzz(unittest.TestCase): def test_return_number(self): self.assertEqual("1", fizzbuzz(1)) def test_return_fizz(self): self.assertEqual("fizz", fizzbuzz(3)) def test_return_buzz(self): self.assertEqual("buzz", fizzbuzz(5)) def test_return_fizzbuzz(self): self.assertEqual("fizzbuzz", fizzbuzz(15)) @paramterized_test(expected="1", func_param=1) @paramterized_test(expected="fizz", func_param=3) @paramterized_test(expected="buzz", func_param=5) @paramterized_test(expected="fizzbuzz", func_param=15) def test_fizzbuzz(self, params): self.assertEqual(params["expected"], fizzbuzz(params["func_param"])) if __name__ == '__main__': unittest.main()
上のファイルの実行結果はもちろんグリーンで
..... ---------------------------------------------------------------------- Ran 5 tests in 0.000s OK
となる。
ちなみに
たしかPython 2.7と3.2でunittestモジュールに実装されるというのを見た気がするんですがどうでしょう?
2.6とか2.5でも使いたいよねというのと、個人的な理解を深めるための自己満のコードなのであしからず。
現状の問題
- 上に載せなかったけど複数の引数とるメソッド or 関数はエラー出たはず。
- 実引数に*argsとかやりargsをタプル型(シーケンス型?)にすると関数に展開してくれるはずなのでそれでいけるはず。
- 問題じゃないけど、assertRaiseって引数が、期待する例外、呼び出し可能なオブジェクト、2番目の関数に渡すの引数(可変)....と続くのでこっちにあわせた方がいいかも。
- 辞書型で期待値とパラメータ指定ってどうなの?
- とにかくどういうインターフェースがいいのかがよくわからん。
そのうち別途また上げようと思いまする。