3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Python】競プロをpytestでデバッグしやすく

Last updated at Posted at 2023-05-06

1. はじめに

AtCoderやPaizaのプログラミング課題で標準入力からデータを入力させられることが多いです。

Pythonの場合、

input()

を用いて値を受け取る必要があるので、自分の環境でデバッグする際に少々厄介だと思っていました。 テストケースが複数与えられた場合も入力の手間がかかりますし…

そこで、pytestを用いて一度に複数のテストケース標準入力から入力してデバッグが行えるようなコードを考えてみたので記しておきます。

結論から先に記すとこのように、提出したいコードのままエディタで製作できますし、ブレークポイントを設定してのデバッグも可能です。

image.png

2. 環境

  • エディタ:VScode
  • 言語:Python

VScodeでのPythonの環境構築については省きますが、pytestを用いるので

pip install pytest

でインストールを行います。仮想環境を用いる場合は適宜調整してください。

VScodeでのpytestの利用に関しては、以下のサイトが参考になりました。

3. ソース

例えば、次のようなディレクトリ構成にします。

repo/
├── src
│   ├── input/
│   │   ├── input1.txt
│   │   ├── input2.txt
│   │   ~~~
│   ├── output/
│   │   ├── output1.txt
│   │   ├── output2.txt
│   │   ~~~
│   ├── main.py
│   └── test_main.py
  • input : テストケース(入力)をテキストで記述
  • output : 期待される出力を記述
  • main.py : コーディング課題を記述する。
  • test_main.py : テストケースを呼び出し、テストを行う。

以降Welcome to AtCoderの課題を解くことを例に挙げて記述します。

input#.txtoutput#.txt

それぞれ、次の通りにします。

input1.txt
1
2 3
test
output1.txt
6 test

※テストケース2以降の場合も同様

main.py

main.py
def main():
    # 関数やスクリプトを記述
    a = int(input())
    b, c = map(int, input().split())
    s = input()
    print("{} {}".format(a+b+c, s))

if __name__ == '__main__':
  main()

test_main.py

main.pymain関数を呼び出してテキストで保存したテストケースを読み取り、標準入力として与えます。

test_main.py
from main import *
import pytest
import io

@pytest.mark.parametrize(('fileNo'), [1, 2,]) #適応したいテストケースの番号をリストとして与える
def test_case(capsys, monkeypatch, fileNo):
    inputs, outputs = load_data(fileNo)
    monkeypatch.setattr('sys.stdin', io.StringIO(inputs)) #標準入力にファイルの内容をセット 
    main()
    results, _ = capsys.readouterr()
    assert results == outputs + "\n" #出力が答えと一致するか検証

def load_data(fileNo):
    inputFile = F"src/input/input{fileNo}.txt"
    outputFile = F"src/output/output{fileNo}.txt"
    with open(inputFile, "r") as f:
        inputs = f.read()
    with open(outputFile, "r") as f:
        outputs = f.read()
    return inputs, outputs

4. 実行

VScodeでのテストバッジからpytestを実行すると、テストケースごとの結果得られます。その他デバッグも可能です。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333239333435372f37623732316332632d646139342d643138382d306333302d3937623239306565343365312e706e67.png

5. まとめ

正直に言うと、私は競技プログラミングは超苦手なのでデバッグできるようになって良かったです。

私のgithub上に本記事で紹介したのと同様のものを挙げています。
ココではdevcontainerを用いて諸々が動作する開発環境を構築することができます。

その他参考

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?