AIZU ONLINE JUDGE の Go 言語問題をローカル環境で単体テストする

Sep 1, 2018 ( Feb 11, 2022 更新 )

私は、アルゴリズムやデータ構造の知識がなく、プログラミングが苦手なので、「プログラミングコンテスト攻略のためのアルゴリズムとデータ構造」を買って AIZU ONLINE JUDGE(以下 AOJ) に提出しながら読み進めています。

AOJ の問題は、インプットが標準入力からとなり、回答は標準出力に流します。

提出するときは書きなぐってオンラインでテストを走らせてもよいのですが、自分でローカル環境で単体テストケースを書きたかったので次のようにしてテストケースを書いています。 行数が長くなってしまうのですが、今の段階では解ければよいということで気にせずやっています。

実行コード

実行コードは、AOJ のサイトから提出する方のコードです。これをコピペして AOJ のフォームに貼り付けます。

以下のように main()exec() という関数に io.Reader を渡して戻ってきた結果を os.Stdout に流します。

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
	result, err := exec(os.Stdin)
	if err != nil {
		println(err)
		os.Exit(1)
	}

	fmt.Fprintf(os.Stdout, "%v\n", result)
}

func exec(reader io.Reader) (string, error) {
	bufReader := bufio.NewReader(reader)

	str, err := bufReader.ReadString('\n')
	if err != nil {
		// 無視する
	}
  // ここに実装

	return "", nil
}

テストコード

以下はテストコードの例です。

テストケースの input を string として定義します。また、想定する結果(expected)も string として定義します。

定義した input の string は、bytes.NewBuggerString を介して前述した exec 関数に渡します。 exec 関数の戻りは string になっているので、これを expected の string になっているか検証します。

package main

import (
	"bytes"
	"fmt"
	"os"
	"testing"
)

func TestExec(t *testing.T) {
	var tests = []struct {
		input    string
		expected string
	}{
		{"1 2 +", "3"},
		{"1 2 + 3 *", "9"},
		{"1 2 + 3 4 - *", "-3"},
	}

	for _, test := range tests {
		fmt.Fprintf(os.Stdout, "input:\n%v\nexpected:\n%v\n",
			test.input, test.expected)
		actual, err := exec(bytes.NewBufferString(test.input))
		if err != nil {
			t.Errorf("failed. err: %v", err)
		}
		fmt.Fprintf(os.Stdout, "actual:\n%v\nexpected:\n%v\n", actual, test.expected)
		if actual != test.expected {
			t.Errorf("failed. actual: %v, expected: %v", actual, test.expected)
		}
	}
}

もっといい書き方があるかもしれないですが、今はこんな感じで単体テストを書いてから提出するようにしています。

Return to top