スクリプトによる自動比較テスト技術

一般的なLinuxとWindowsのコマンド比較

機能 Linuxコマンド Windowsコマンド
ファイル一覧表示 ls dir
ディレクトリ操作 cd/mkdir/rmdir cd/md/rd
ファイル内容表示 cat/more type/more
ファイル内容比較 diff fc
ファイル属性変更 chmod attrib
ファイルコピー cp copy/xcopy
ファイル削除 rm del
ファイル名変更 mv ren
文字列出力 echo echo
コマンドライン終了 exit exit
ファイル内検索 grep find
環境変数操作 set set
ヘルプ表示 man <コマンド> help <コマンド>

スクリプトによる自動テスト

Windowsバッチスクリプト例

@echo off
:loop
	データ生成器 > input.txt
	プログラムA < input.txt > resultA.txt
	プログラムB < input.txt > resultB.txt
	fc resultA.txt resultB.txt
if not errorlevel 1 goto loop
pause

Linux Bashスクリプト例

#!/bin/bash
while true; do
	./ランダム生成器 > input.txt   # テストデータ生成
	./対象プログラムA < input.txt > 出力A.txt
	./正解プログラムB < input.txt > 出力B.txt
	diff 出力A.txt 出力B.txt          # 結果比較
	if [ $? -ne 0 ] ; then break; fi # 差異があれば終了
done
上記スクリプトをtest.shとして保存後、chmod +x test.shを実行すると、./test.shで実行できます。

比較テストの実装方法

開発や競技プログラミングにおいて、プログラムの正確性を検証したりバグを特定したりする必要が頻繁に発生します。比較テスト手法を適用することで、プログラムの信頼性を大幅に向上させることが可能です。基本的なアプローチとして、時間計算量を無視して正確性のみを保証する単純な実装(ブルートフォース法)と、検証対象のプログラムの出力結果を比較します。これに加えて、テスト用のランダムデータを生成するデータジェネレータが必要です。スクリプトを利用したバッチ処理により、自動的に2つのプログラムの結果を比較検証します。

  • ブルートフォース法による実装プログラム
  • 検証対象のプログラム
  • テストデータ生成器
  • 自動実行スクリプト

ランダム数生成の実装

OSに標準で搭載されている乱数生成機能を活用します。Windows環境では環境変数%random%、Linux/Bashでは$RANDOM変数を使用できます。これらは0~32767の範囲で一様な整数を生成します。

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;

#define ランダム範囲(a,b) ((a)+rand()%((b)-(a)+1))
const LL 最大値 = 1e16 + 10;

stringstream データストリーム;

LL 生成長い乱数(){//long long型の乱数を生成
	LL 結果 = 0;
	for(int カウント= 0; カウント<4; カウント++){
		結果 *= (LL)1<<15;
		結果 += rand();
	}
	return 結果;
}

int main( int 引数数, char *引数[] ) //スクリプトから乱数シードを受け取る
{ 
    srand(atoi(引数[0]));
    
    printf("%lld %lld\n", 生成長い乱数(), 生成長い乱数());
    return 0;
}

自動比較スクリプト

@echo off
:loop
	データ生成器 %random% > テスト入力.txt ;ランダム入力データ生成
	対象プログラムA < テスト入力.txt > 結果A.txt
	正解プログラムB < テスト入力.txt > 結果B.txt
	fc 結果A.txt 結果B.txt      ;2つの結果ファイルを比較
if not errorlevel 1 goto loop ;一致すればループ継続
pause

C言語による自動比較プログラム

#include <stdio.h>
#include <stdlib.h>

int main() {
  // Windows環境向け実装
  // 比較テスト時はファイル入出力を無効化
  // このプログラムはバッチ処理としても実装可能
  while (true) {
    system("データ生成器 > テスト用入力.txt");  // データ生成器が入力ファイルにデータを書き込む
    system("テスト対象プログラムA.exe < テスト用入力.txt > 出力A.txt");  // プログラムAの出力を取得
    system("正解プログラムB.exe < テスト用入力.txt > 出力B.txt");  // プログラムBの出力を取得
    if (system("fc 出力A.txt 出力B.txt")) {
      // この行で2つの出力を比較
      // fcが0を返す場合は出力が一致、非0なら差異がある
      system("pause");  // 差異を確認しやすくするため一時停止
      return 0;
      // この入力データはテスト用入力.txtに保存され、デバッグに直接利用可能
    }
  }
}

Windows環境での実行結果

  • 2つのプログラムの結果に差異がない場合: スクリプトは継続実行
  • 差異が検出された場合: 差異箇所が表示され、プログラムが一時停止

タグ: スクリプト バッチ処理 自動テスト データ生成 アルゴリズム検証

7月9日 17:33 投稿