これはひどい slenium-ideから検証項目表を自動生成

検証をselenium-ideで作っていたが、どーしても検証項目表(テスト表,検証表)がほしいという人がいたので、selenium-ideから検証項目表を自動生成するプログラムを作りました。

事前条件

ファイルの命名規則

テストケースは xxxx 〜こと のように命名すること。
NG ユーザー登録 登録でエラー
OK ユーザー登録できること 登録でエラーにならないこと

カテゴリ名などを先頭につけること

例: ユーザー登録_ユーザー登録できること
バグ_ユーザー登録で1234と入力してもエラーにならないこと

テストは細切れに作ってテストスイートで結合

一つのテストは検証項目表でいう1テスト項目に当たるぐらいの最小単位で作っていく。
後でテストスイートで結合させる。

プログラム

コマンドラインから動作させることを前提としています。
一応webからでも動きますけど。。。

<?

	//selenium の td タグの相当するパラメータを受け取って、
	//非技術者が分かるように日本語化する
	//余計に分かりづらくなるけど細かいところは気にしない.
	//どうせ彼らは何もわか(ry なので数でお茶を濁す.
	function selenium_ide_to_nihongo($base , $t1,$t2,$t3)
	{
		if ( $t1 == "open" )
		{
			$url = $t2;
			if (substr($t2 , 0 , 4) != "http")
			{
				if ( substr($base,-1,1) == "/")
				{
					$url = substr($base,0,strlen($base)-1) . $t2;
				}
				else
				{
					$url = $base . $t2;
				}
			}
			return "URL({$url})にアクセスします。";
		}
		else if ( $t1 == "clickAndWait" )
		{
			return "画面の({$t2})をクリックして次のページに移動します。";
		}
		else if ( $t1 == "click" )
		{
			return "画面の({$t2})をクリックします。";
		}
		else if ( $t1 == "type" )
		{
			return "入力欄 ({$t2})に({$t3})と入力します。";
		}
		else if ( $t1 == "select" )
		{
			return "({$t2})で({$t3})を選択します。";
		}
		else if ( $t1 == "verifyTitle" || $t1 == "assertTitle")
		{
			return "タイトルに ({$t2})と表示されていることを確認します。";
		}
		else if ( $t1 == "verifyTextPresent" || $t1 == "assertTextPresent")
		{
			return "画面に({$t2})と表示されていることを確認します。";
		}
		else if ( $t1 == "verifyTextNotPresent" || $t1 == "assertTextNotPresent" )
		{
			return "画面に({$t2})と表示されていないことを確認します。";
		}
		else if ( $t1 == "verifyValue" || $t1 == "assertValue")
		{
			return "画面の({$t2})に({$t3})と表示されていることを確認します。";
		}
		else if ( $t1 == "verifyNotValue" || $t1 == "assertNotValue")
		{
			return "画面の({$t2})に({$t3})と表示されていないことを確認します。";
		}
		
		//不明なので適当に返す
		if ($t3 == "")
		{
			return "({$t1})によって({$t2})であること";
		}
		else
		{
			return "({$t1})によって({$t2})が({$t3})であること";
		}
	}
	
	//ファイル名をパースします。
	//カテゴリ名_テスト項目
	function selenium_ide_filename_parse($filename)
	{
		$filename = basename($filename);
		$rpos = strrpos($filename,"_");
		if ($rpos === FALSE)
		{
			$category = "";
			$title = $filename;
		}
		else
		{
			$category = substr($filename,0 , $rpos - 1);
			$title = substr($filename, $rpos + 1 );
		}
		
		return 
			array('category' => $category
					,'title' => $title
					);
	}
	
	//ファイルの変更履歴をソース管理から取得する.
	function make_file_history($filename)
	{
		$dir = dirname($filename);

		$s_dir = escapeshellarg($dir);
		$s_filename = escapeshellarg(basename($filename));

		$text = "";
		if ( file_exists("{$dir}/.svn") )
		{//for svn user
			$r = `cd {$s_dir} ; svn log {$s_filename}`;

			//いつ誰が変更したのかだけほしい.
			$regs = array();
			preg_match_all("/(r[0-9]+) \| (.*?) \| (.*?) /us",$r , $regs);

			$count = count($regs[0]);
			for($i = 0 ; $i < $count ; $i ++)
			{
				$text .= "{$regs[2][$i]} {$regs[3][$i]} ({$regs[1][$i]})" . "\r\n";
			}
		}
		return trim($text);
	}

	//selenium ide のテストケースを読み込んで、
	//テストケースで行う内容を日本語にして返します。
	function selenium_ide_to_csv($filename)
	{
		$fileString = file_get_contents($filename);
		if ($fileString === FALSE)
		{
			echo "can not opne : {$fileString}";
			return false;
		}
		$regs = array();

		//ベース
		preg_match('/<link rel="selenium.base" href="(.*?)"/ui',$fileString, $regs);
		$base = $regs[1];

		//td の項目をパース.
		preg_match_all("/<tr>.*?<td>(.*?)<\/td>.*?<td>(.*?)<\/td>.*?<td>(.*?)<\/td>.*?<\/tr>/ums",
			$fileString , $regs);

		$text = "";
		$count = count($regs[0]);
		for($i = 0 ; $i < $count ; $i ++)
		{
			//強引に日本語化
			$text .= selenium_ide_to_nihongo($base , $regs[1][$i],$regs[2][$i],$regs[3][$i]) . "\r\n";
		}
		$text = trim($text);
		
		//テスト作成日と更新日情報をソース管理に問い合わせる
		//鍵交換でノンパスでやり取りできないとフリーズするのでとりあえずコメントアウト
		//$testerText = make_file_history($filename);
		$testerText = "";
		
		//ファイル名からカテゴリとテストの名前を取得.
		$testinfoArray = selenium_ide_filename_parse($filename);
		return		CsvEncode($testinfoArray['category'])	//カテゴリ 
			. ',' . CsvEncode($testinfoArray['title'] )		//テスト名
			. ',' . CsvEncode($text)						//テスト手順と結果
			. ',' . CsvEncode($testerText)					//テスター
			;
	}

	//テストスイート
	function selenium_ide_to_testsuite($filename)
	{
		$fileString = file_get_contents($filename);
		if ($fileString === FALSE)
		{
			echo "can not opne : {$fileString}";
			return false;
		}
		$base = dirname($filename);
		
		//td の項目をパース.
		$regs = array();
		preg_match_all("/<tr>.*?<td><a href=\"(.*?)\">.*?<\/a>.*?<\/td>.*?<\/tr>/ums",
			$fileString , $regs);

		//ヘッダー
		$text=		CsvEncode("カテゴリー")
			. ',' . CsvEncode("テスト名")
			. ',' . CsvEncode("テスト手順と結果")
			. ',' . CsvEncode("テスター")
		 	. "\r\n";

		foreach($regs[1] as $ahref)
		{
			$text .= selenium_ide_to_csv("{$base}/{$ahref}") . "\r\n";
		}
		return trim($text);
	}
	
	//csv形式に変換.
	function CsvEncode($str)
	{
		//エクセルで開くことを前提とするのでsjis化する
		$str = mb_convert_encoding($str,"sjis-win","UTF-8");
		return '"' . str_replace('"','""',$str) . '"';
	}


	//実行!
	//テストスイートを指定します。
	$r = selenium_ide_to_testsuite("testsuite");
	echo $r;

//	$r = make_file_history("/home/rti/svn/aaa/trunk/htdocs/index.php");
//	var_dump($r);
?>