atcoderのabc問題を解いている。
atcoderは競技プログラミングなので、テストを書く必要はない。むしろ、テストを意識した実装にすることでコード量が増え実行時間が長くなる可能性もある。
ただ、過去問を使った練習だということ、最低限与えられた入出力例は自動で正誤判定できるようにしたかったこと、何よりTDDでの実装を見につけたかったこと。これらの要因からテストを書いている。
まず、実装とテストの雛形を生成する。これはfish shellで作ったスクリプトを使う。
if test (count $argv) -eq 0 echo "Plz pass problem title" exit 1 end set problem $argv[1] if test -e atcoder_beginner_contest/abc_$problem.py echo "$problem files already exist." exit 1 end ## make exec python file printf "\ def execute(value): pass if __name__ == '__main__': print(execute(input())) " > atcoder_beginner_contest/abc_$problem.py ## make test python file printf "\ # /usr/bin/env python # coding: utf-8 from unittest import TestCase from atcoder_beginner_contest.abc_$problem import execute class TestABC$problem(TestCase): def test_execute_(self): self.assertEqual(execute(), ) " > abc_test/test_abc_$problem.py
問題番号をつけてこれを実行することで、問題を解くためのPythonファイルが出力される。
fish make_abc.fish 023A
次に、与えられた入力・出力例を元にテストを修正し、赤が返ってくることを確認する。
# /usr/bin/env python # coding: utf-8 from unittest import TestCase from atcoder_beginner_contest.abc_023A import execute class TestABC023A(TestCase): def test_execute_1(self): self.assertEqual(execute(23), 5) def test_execute_2(self): self.assertEqual(execute(70), 7) def test_execute_3(self): self.assertEqual(execute(99), 18)
> pytest abc_test/test_abc_023A.py abc_test/test_abc_023A.py FFF 3 failed in 0.12 seconds
execute関数が問題の解答を作るための関数になっている。
問題によって与えられるパラメータや解答の出力方法が異なるため、そのあたりは適宜対応するようにしている。
テストが失敗することが確認できたので、実装の方を修正する。
テストを通すだけならexecute関数だけを修正すればよいが、最終的にはatcoder上でパスするためのものなので、main関数も合わせて修正する。
def execute(X): return int(X / 10) + X % 10 if __name__ == '__main__': print(execute(int(input())))
実装が修正できたので、再度テストを実行する。
(env) fujii@MBP ~/p/atcoder> pytest abc_test/test_abc_023A.py abc_test/test_abc_023A.py ... 3 passed in 0.03 seconds
これで、実装したexecute関数は例題に対して正しく答えられることが確認できた。
最後に、main関数に不具合がないかを確認するためにコンソール上で一度実行する。
> python3 atcoder_beginner_contest/abc_023A.py 23 5
あとは実装部分をコピペしてatcoderに提出する。