VSCodeのタスクでAtCoderのテストを簡単に実行

はじめに

こんにちは、Pike8です。みなさんはAtCoderで問題を解くときに、VSCodeのタスクは使っていますか。例えばcppファイルの作成や、サンプルのテストケースの実行など、タスクにより自動化できる部分はいくつかあります。タスクを使うことで人為的なミスを減らし、また時間の節約にもつながります。今回はPike8が使っているVSCodeのタスクとスクリプトを紹介したいと思います。

やりたいこと

VSCodeのタスクを利用してAtCoderで何度も行うことを自動化します。

具体的には

  • cppファイルの作成
  • コードのビルドと実行
  • サンプルのテストケースで実行
  • テストケースの追加

などが簡単にできるようになります。

VSCodeのタスク

VSCodeでは .vscode/task.json に実行可能なファイルやシェルコマンドをタスクとして登録することができます。このとき、開いているファイルのパスなどを引数として渡すことができます。

{
    "tasks": [
        {
            "label": "show path",
            "type": "shell",
            "command": "echo path is \"${relativeFile}\"",
        },
    ],
    "version": "2.0.0"
}

タスクは Terminal > Run Task などから起動したいタスクを選択します。例えば abc300/a.cpp というファイルを開いた状態でこの show path タスクを起動すると、ターミナルに path is abc300/a.cpp と表示されます。

環境

  • VSCode: 1.78.2

タスク

Pike8がAtCoderで普段使っている .vscode/task.jsonこちらです。この中でよく使っているものをいくつか紹介します。

add cpp file

{
    "label": "add cpp file",
    "type": "shell",
    "command": "${workspaceFolder}/.script/add_cpp_file.sh",
    "args": [
        "${workspaceFolder}"
    ],
    "presentation": {
        "focus": true
    }
}

コンテストの開始前にcppファイルを作成するためのタスクです。起動してパスと追加するcppファイルの個数を入力すると、ディレクトリとファイルが作成されます。

このタスク自体は .script/add_cpp_file.sh を起動しています。また、presentation.focus をtrueに設定することで、タスクの起動時にターミナルにフォーカスが移り、パスや個数の入力をスムーズに行えます。

run

{
    "label": "run",
    "type": "shell",
    "command": "${fileDirname}/build/${fileBasenameNoExtension}",
    "dependsOn": [
        "build"
    ],
    "presentation": {
        "clear": true,
        "focus": true
    }
},

コードを実行するためのタスクです。VSCodeの拡張機能のCode Runnerを使ってもよいですが、単に実行するだけならタスクで十分です。dependsOn ではこのタスクを実行する前に実行するタスクを指定できます。この場合、run タスクの前に build タスクが実行されます。また、command には build タスクで生成された実行可能な成果物を指定しています。

run タスクは競技中に何度も実行することになるので、キーバインドを登録すると良いでしょう。~/Library/Application Support/Code/User/keybindings.json に以下のように記述することでキーバインドを登録できます。

[
    {
        // 利用しやすいキーバインドを設定
        "key": "alt+r",
        "command": "workbench.action.tasks.runTask",
        "args": "run"
    },
]

run test case

{
    "label": "run test case",
    "type": "shell",
    "command": "${workspaceFolder}/.script/run_test_case.sh",
    "args": [
        "${relativeFile}"
    ],
    "dependsOn": [
        "build"
    ],
    "presentation": {
        "clear": true
    }
},

サンプルのテストケースで実行するためのタスクです。コンテスト中は一番利用するタスクです。実行すると、パス名とファイル名をもとに問題のページのURLを組み立て、ページからサンプルのテストケースをダウンロードし、./build/testcase/[ファイル名] に保存します。その後、テストケースを実行し、実行結果が正しいかどうかを判定します。

このタスク自体は .script/run_test_case.sh を起動しています。このスクリプトは内部でonline-judge-toolsのコマンドを利用しているため、事前にこちらのツールをダウンロードし、oj コマンドにパスを通す必要があります。

run test case タスクも競技中に何度も実行することになるので、キーバインドを登録しておくと良いでしょう。

[
    {
        // 利用しやすいキーバインドを設定
        "key": "alt+t",
        "command": "workbench.action.tasks.runTask",
        "args": "run test case"
    },
]

add test case

{
    "label": "add test case",
    "type": "shell",
    "command": "${workspaceFolder}/.script/add_test_case.sh",
    "args": [
        "${relativeFile}"
    ]
},

サンプルのテストケースだけではデバッグが難しいときに、テストケースを追加するためのタスクです。実行すると、./build/testcase/[ファイル名]user-[数字].inuser-[数字].out が作成され、エディタが開きます。こちらにインプットとアウトプットを記述しておくと、run test case タスクでサンプルと一緒にテストされます。このタスク自体は .script/add_test_case.sh を起動しています。

clean build

{
    "label": "clean build",
    "type": "shell",
    "command": "find . -name build | xargs rm -rf"
},

ビルド成果物やダウンロード、追加したテストケースを削除するためのタスクです。気が向いたときに実行しています。

所感

サンプルのテストケースを実行するタスクは特におすすめです。キーバインドで簡単にサンプルのテストケースを実行できることで、それをさぼって提出してWAになることがありません。また、実行結果を目で比較するのに時間がかかったり、ミスが出ることを予防します。デバッグログの削除忘れなども改善できます。皆さんもぜひタスクを利用して、怠惰なプログラマを目指しましょう。