Skip to content

Instantly share code, notes, and snippets.

@kurgm
Last active May 6, 2020 16:15
Show Gist options
  • Save kurgm/c290ebbb6d64d65631e4018a70bef4ab to your computer and use it in GitHub Desktop.
Save kurgm/c290ebbb6d64d65631e4018a70bef4ab to your computer and use it in GitHub Desktop.

使い方

(ぼくはこう使っているという話ですが)

コンテストごとにディレクトリを用意する。

contest-5/
+- python.py   <- 自分が書いたコード
+- c.c         <- 自分が書いたコード
+- node.js     <- 自分が書いたコード
| ...
|
+- test
+- testbox
`- tests/
   +- 1.in     <- テストケースの入力
   +- 1.out    <- テストケースの出力
   +- 1.out.2  <- テストケースの出力 (2通り以上許容されるとき)
   +- 2.in
   +- 2.out
   `- 2.out.2

chmod +x test testbox を忘れずに。

test コマンド

テストケースに通るか調べてくれる

  • 使い方: ./test の後ろに実行するコマンドを続ける

テストに通る場合

$ ./test python3 python.py
TEST 1: OK
TEST 2: OK

通らない場合 (diffが出る)

$ gcc c.c
(ワーニングの嵐)

$ ./test ./a.out
--- tests/1.out	2020-05-04 13:35:41.000000000 +0900
+++ /var/folders/99/bh16wqjd1yz06ngbdjc8rrjm0000gn/T/tmp.gudDipmm	2020-05-07 00:45:48.000000000 +0900
@@ -1 +1 @@
-41568294818252795378451692656417
\ No newline at end of file
+4
\ No newline at end of file
--- tests/1.out.2	2020-05-04 15:51:54.000000000 +0900
+++ /var/folders/99/bh16wqjd1yz06ngbdjc8rrjm0000gn/T/tmp.gudDipmm	2020-05-07 00:45:48.000000000 +0900
@@ -1 +1 @@
-41965987818254755378481626686493
\ No newline at end of file
+4
\ No newline at end of file
TEST 1: FAILED
...

問題ごとに必要な調整

  • 問題ごとに出力中の空白の扱いが違う件(空白は全部無視,前後の空白は無視,空白は無視しない,など)
    • 問題に合わせて適宜testスクリプト内の normalize の定義を切り替える
  • 2,3通りの出力ケースとのdiffでは済まない(正しい出力結果がN通りありえる)場合
    • カスタムのバリデータを書いて実行可能ファイルとして ./validate に置くとそれを使ってくれる。
    • ./validate 出力結果ファイル名 入力ファイル名 で呼び出す
    • バリデータは,OKならば終了コード0で,FAILEDならば0以外で終了するべし
    • この場合エラーでもdiffなどは出ないのでバリデータ側で適切に差分などを吐くようにする

testbox コマンド

esolang-boxで実行した結果がテストケースに通るか調べてくれる (要するに./test docker run ...をしてくれる)

  • 必要なもの: Docker
  • 使い方: ./testbox language program
    • language は,esolang-boxから esolang/ほげ を探して ほげ を入れる
$ ./testbox tex tex.tex
TEST 1: OK
TEST 2: OK
#!/usr/bin/env bash
declare -a command=("$@")
# 問題設定に応じて適宜切り替える
if true; then
# remove all spaces
normalize() {
tr -d $' \n\t\r\f'
}
elif false; then
# trim spaces around
normalize() {
python3 -c 'import sys; sys.stdout.buffer.write(sys.stdin.buffer.read().strip())'
}
else
# as is
normalize() {
cat
}
fi
if [ -x ./validate ]; then
# custom validator
validate() {
local resultfile=$1
local infile=$2
./validate "${resultfile}" "${infile}"
}
else
# diff
validate() {
local resultfile=$1
local infile=$2
shift 2
local result=1
local diffoutfile=$(mktemp)
for outfile; do
if diff -u "${outfile}" "${resultfile}" >> "${diffoutfile}"; then
# echo "Matched with ${outfile}"
result=0
break
fi
done
if [ "$result" = 1 ]; then
cat "${diffoutfile}"
fi
rm "${diffoutfile}"
return "${result}"
}
fi
errors=0
test_one () {
local testname=$1
local infile=$2
shift 2
local resultfile=$(mktemp)
"${command[@]}" < "${infile}" | normalize > "${resultfile}"
if validate "${resultfile}" "${infile}" "$@"; then
echo TEST "${testname}": $'\x1b[1m\x1b[32mOK\x1b[0m'
else
echo TEST "${testname}": $'\x1b[1m\x1b[31mFAILED\x1b[0m'
errors=$((${errors} + 1))
fi
rm "${resultfile}"
}
# テストケースを列挙
test_one 1 tests/1.in tests/1.out tests/1.out.2
test_one 2 tests/2.in tests/2.out tests/2.out.2
exit "$errors"
#!/usr/bin/env bash
if [ ! "$#" != 3 ]; then
echo "usage: $0 language program"
exit 255
fi
language=$1
program=$2
if [ ! -e "${program}" ] ; then
echo "${program} doesn't exist" >&2
exit 255
fi
if [ ! "$(dirname ${program})" = "." ]; then
echo "${program} is not in cwd" >&2
exit 255
fi
exec ./test docker run --rm -i -v "$(pwd):/code:ro" "esolang/${language}" "${language}" "/code/${program}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment