【Python】1年近くプログラマーやってFizzBuzzの作り方が変わったのさ
こんばんは、葛の葉です。
以前までの作り方
def fizuubuzz(num): if num % 15 == 0: return 'FizzBuzz!' elif num % 3 == 0: return 'Fizz!' elif num % 5 == 0: return 'Buzz!' else: return str(num)
これからの作り方
ディレクトリを作成する。
├── /app └── /test
このようにテストと本番を別ける。
testアプリケーションを作成する。
pytestで初期実行するconftest.py
を以下のように作成する。
# conftest.py import os import sys sys.path.append(os.path.abspath(os.path.dirname( os.path.abspath(__file__)) + '/../app/'))
これは、テストを実行するときのディレクトリの目線をapp
にするものです。
import等、ディレクトリを読み込むときはapp
ディレクトリがスタートになります。
カレントディレクトリがapp
になるといった感じです。
├── /app └── /test └── conftest.py
列挙型で定数を作る
python
には列挙型であるenum
というものがあります。これの整数列挙型であるIntEnum
というものを使用します。
app/Numbers.py
というpythonプログラム作成し、以下のようにします。
# Numbers.py from enum import IntEnum class Numbers(IntEnum): FIZZ = 3 BUZZ = 5 FIZZBUZZ = FIZZ * BUZZ
これの説明はtest_Numbers.py
というテストプログラムを作成します。
# test_Numbers.py from Numbers import Numbers def test_Numbers(): assert 3 == Numbers.FIZZ assert 5 == Numbers.BUZZ assert 15 == Numbers.FIZZBUZZ
test
ディレクトリをカレントディレクトリにしてから、pytest
と実行すれば1 passed in 0.** seconds
と表示されるはずです。
======================== test session starts ========================= platform linux -- Python 3.6.6, pytest-3.8.1, py-1.6.0, pluggy-0.7.1 rootdir: /home/kuzunoha/sand_box/test, inifile: plugins: pylama-7.6.6 collected 1 item test/test_Numbers.py . [100%] ====================== 1 passed in 0.02 seconds ======================
Numbers.FIZZ
は整数3
とアサート出来ます。
Numbers.BUZZ
は整数5
とアサート出来ます。
Numbers.FIZZBUZZ
は整数15
とアサート出来ます。
これらNumbers
は定数
のように扱うようにします。
├── /app │ └── Numbers.py └── /test ├── conftest.py └── test_Numbers.py
FizzBuzzを作る。
まずは空のapp/FizzBuzz.py
と空のtest/test_FizzBuzz.py
を作成します。
├── /app │ ├── FizzBuzz.py │ └── Numbers.py └── /test ├── conftest.py ├── test_FizzBuzz.py └── test_Numbers.py
そうしてFizzBuzz.py
を作成します。
# FizzBuzz.py from Numbers import Numbers class FizzBuzz(object): def checker(self, insert_number): return 'Fizz!'
test_FizzBuzz.py
を作成します。
# test_FizzBuzz.py import pytest from FizzBuzz import FizzBuzz @pytest.fixture() def fizz_buzz(): # インスタンスを作成 fizz_buzz = FizzBuzz() return fizz_buzz def test_checker(fizz_buzz): assert 'Fizz!' == fizz_buzz.checker(3)
pytest test_checker.py
と実行してパスすればしっかりインポートが成功しています。さて、ここまで作ってようやく、FizzBuzz.py
の実装をいろいろ考えられます。今回はFizzBuzz
クラスのchecker
という関数から文字列を返してもらえばいいように考えます。
def test_checker(fizz_buzz): assert 'Fizz!' == fizz_buzz.checker(3) assert '2' == fizz_buzz.checker(2) # 追加
今の状態ではテストは通りません。テストを通すようにします。
# FizzBuzz.py from Numbers import Numbers class FizzBuzz(object): def checker(self, insert_number: int) -> str: if insert_number % Numbers.FIZZBUZZ == 0: return 'FizzBuzz!' elif insert_number % Numbers.FIZZ == 0: return 'Fizz!' elif insert_number % Numbers.BUZZ == 0: return 'Buzz!' else: return str(insert_number)
pytest
を行う
===================== test session starts ====================== platform linux -- Python 3.6.6, pytest-3.8.1, py-1.6.0, pluggy-0.7.1 rootdir: /home/kuzunoha/sand_box/test, inifile: plugins: pylama-7.6.6 collected 2 items test/test_FizzBuzz.py . [ 50%] test/test_Numbers.py . [100%] =================== 2 passed in 0.03 seconds ===================
テストする項目を増やしてみる。
# test_FizzBuzz.py import pytest from FizzBuzz import FizzBuzz @pytest.fixture() def fizz_buzz(): # インスタンスを作成 fizz_buzz = FizzBuzz() return fizz_buzz def test_checker(fizz_buzz): assert 'Fizz!' == fizz_buzz.checker(3) assert '2' == fizz_buzz.checker(2) assert 'Buzz!' == fizz_buzz.checker(5) assert 'FizzBuzz!' == fizz_buzz.checker(15) assert 'FizzBuzz!' == fizz_buzz.checker(30)
======================== test session starts ========================= platform linux -- Python 3.6.6, pytest-3.8.1, py-1.6.0, pluggy-0.7.1 rootdir: /home/kuzunoha/sand_box/test, inifile: plugins: pylama-7.6.6 collected 2 items test/test_FizzBuzz.py . [ 50%] test/test_Numbers.py . [100%] ====================== 2 passed in 0.03 seconds ======================
もっともっと勉強が必要
がんばらないと