- Python Boot Camp に行ってきた
- テストドリブン FizzBuzz
— ドキュメント
— 環境
— FizzBuzz とは
— 最初のテスト
— fizz buzz 関数の実装(1)
— テスト(2)
— fizz buzz 関数の実装(2)
— テスト(3)
— fizzbuzz 関数の実装(3)
— テスト(4) - 以上
Python Boot Camp に行ってきた
pyconjp.connpass.com
言語を基礎から学ぶ機会が得られて本当に良かった。
ということで、教材の「2. Pythonをはじめよう」で FizzBuzz のサンプルがあったので UnitTest を使ってテストドリブンで FizzBuzz を実装してみた。
テストドリブン FizzBuzz
ドキュメント
環境
今回は以下のような環境で FizzBuzz する。
$ python -V Python 3.6.2
FizzBuzz とは
もはや説明不要の泣く子も黙るゲーム。
- 1 から順に数字を発言する
- 数字が 3 で割り切れる場合は「Fizz」と発言する
- 5 で割り切れる場合は「Buzz」と発言する
- 3 と 5 で割り切れる場合は「FizzBuzz」と発言する
最初のテスト
以下のようなテストを書く。
import unittest class Testfizzbuzz(unittest.TestCase): def test_should_return_normal_number(self): self.assertEqual(fizzbuzz(1), "1") def test_3_should_return_Fizz(self): self.assertEqual(fizzbuzz(3), "Fizz") def test_5_should_return_Buzz(self): self.assertEqual(fizzbuzz(5), "Buzz") def test_3_and_5_should_return_FizzBuzz(self): self.assertEqual(fizzbuzz(15), "FizzBuzz") if __name__ == '__main__': unittest.main()
テストを走らせてみる。
$ python fizzbuzz_test.py EEEE ====================================================================== ERROR: test_3_and_5_should_return_FizzBuzz (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 16, in test_3_and_5_should_return_FizzBuzz self.assertEqual(fizzbuzz(15), "FizzBuzz") NameError: name 'fizzbuzz' is not defined ====================================================================== ERROR: test_3_should_return_Fizz (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 10, in test_3_should_return_Fizz self.assertEqual(fizzbuzz(3), "Fizz") NameError: name 'fizzbuzz' is not defined ====================================================================== ERROR: test_5_should_return_Buzz (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 13, in test_5_should_return_Buzz self.assertEqual(fizzbuzz(5), "Buzz") NameError: name 'fizzbuzz' is not defined ====================================================================== ERROR: test_should_return_normal_number (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 7, in test_should_return_normal_number self.assertEqual(fizzbuzz(1), "1") NameError: name 'fizzbuzz' is not defined ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (errors=4)
そもそも、fizzbuzz
という関数が定義されていないのでテストは失敗どころかエラーになってしまう。
ここからはじめてみる。
fizzbuzz 関数の実装(1)
ファイル名を fizzbuzz.py として、以下のように fizzbuzz 関数を実装してみる。
def fizzbuzz(num): return str(num) for num in range(1, 21): print(fizzbuzz(num))
実行すると以下のように出力される。
$ python fizzbuzz.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
テスト(2)
fizzbuzz_test.py を以下のように修正して fizzbuzz 関数を import する。
import unittest from fizzbuzz import fizzbuzz class Testfizzbuzz(unittest.TestCase): def test_should_return_normal_number(self): self.assertEqual(fizzbuzz(1), "1") ... 略 ... if __name__ == '__main__': unittest.main()
改めてテストを実行する。
$ python fizzbuzz_test.py ... 略 ... FFF. ====================================================================== FAIL: test_3_and_5_should_return_FizzBuzz (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 17, in test_3_and_5_should_return_FizzBuzz self.assertEqual(fizzbuzz(15), "FizzBuzz") AssertionError: '15' != 'FizzBuzz' - 15 + FizzBuzz ... 略 ... ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=3)
テストが 1 つ成功した。
fizzbuzz 関数の実装(2)
以下のように fizzbuzz 関数に実装を加える。
def fizzbuzz(num): if num % 3 == 0 and num % 5 == 0: return 'FizzBuzz' else: return str(num) for num in range(1, 21): print(fizzbuzz(num))
実行すると以下のように出力される。
$ python fizzbuzz.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 FizzBuzz 16 17 18 19 20
テスト(3)
fizzbuzz_test.py を実行してテストする。
$ python fizzbuzz_test.py ... 略 ... .FF. ====================================================================== FAIL: test_3_should_return_Fizz (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 11, in test_3_should_return_Fizz self.assertEqual(fizzbuzz(3), "Fizz") AssertionError: '3' != 'Fizz' - 3 + Fizz ====================================================================== FAIL: test_5_should_return_Buzz (__main__.Testfizzbuzz) ---------------------------------------------------------------------- Traceback (most recent call last): File "fizzbuzz_test.py", line 14, in test_5_should_return_Buzz self.assertEqual(fizzbuzz(5), "Buzz") AssertionError: '5' != 'Buzz' - 5 + Buzz ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=2)
テストが 2 つ成功したぜ。
fizzbuzz 関数の実装(3)
Fizz と Buzz も追加実装してみる。
def fizzbuzz(num): if num % 3 == 0 and num % 5 == 0: return 'FizzBuzz' elif num % 3 == 0: return 'Fizz' elif num % 5 == 0: return 'Buzz' else: return str(num) for num in range(1, 21): print(fizzbuzz(num))
実行すると以下のように出力される。
$ python fizzbuzz.py 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz
おお。
テスト(4)
改めて fizzbuzz_test.py を実行してテストする。
$ python fizzbuzz_test.py 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz .... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
テスト成功!!
以上
すごくシンプルだけどテストドリブンが体験出来た。なんか楽しいなあ。