ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

PHPで、MVCにわけ、処理、画面別々に、ユニットテストを行う例と、方法

2005-11-23 20:03:40 | PHP

 前のブログ PHP等でMVCにわけて、アジャイルっぽく開発できるようにするためのコーディング方略と例 で、カオル姫-テンさん方式(分散)、つまり、
 ・コントローラーをいれて
 ・画面部分と処理部分をわけ
 ・画面部分は、セッションの中身を表示するだけ
 ・処理部分は、画面表示内容をセッションに設定して、コントローラー呼び出し
の方法を示しました。

 で、今回は、その方法で、画面だけ、あるいは処理部分のPHPプログラムだけをテストする、ユニットテストの方法をしめします。




■■ 方略
 どうやって、ユニットテストをやるかということについて、画面(VIEW)と処理部分(モデル)とにわけて説明します。

●画面の場合
 ドライバ側で、セッションに、表示する値を設定して、
 headerで、画面のPHPを呼び出します。
  →セッションに設定した値が表示されるはずです。

●処理部分の場合
 ドライバ側で、セッションに、処理に必要な値を設定して、
 セッションのdebug_modeに"YES"を設定して、
 headerで、その処理PHPを呼び出します。
 →かならず、コントローラーにもどることになります。
  で、コントローラーでは、debug_modeがYESの場合は、nextURLの値にかかわらず
  debug.phpを呼び出しますので
 debug.phpで、セッションの中身を表示すれば、OKです。

ということで、ドライバとdebug.phpを作成し、ドライバから、値をセッションに設定、debug_modeをYESにして、画面なり、処理するPHPを呼び出せば、デバッグできそうです。




■■具体例

 では、今回は、処理プログラムshori.phpをテストしてみます。
 処理のテストの場合は、ドライバとdebug.phpを用意すればOKです。

●ドライバ側

 以下のようなドライバ側のPHPを作成します。
<?
//==============================================//
//						//
//	テストドライバ				//
//						//
//==============================================//

	//	セッション開始
	session_start();

	//	値設定
	$_SESSION['username']	=	"課長";
	$_SESSION['nextURL']	=	"shori.php";

			//	デバッグモードで
	$_SESSION['debug_mode']	=	"YES";

	//	機能呼び出し
	header("Location:shori.php¥n¥n");

?>

(上記の < > ¥ は実際には半角です)

 セッションをスタートし、データをセット、デバッグモードをYESにして、処理プログラムを呼び出します(コントローラーではありません。処理プログラムshori.phpを呼び出してくださいね)

● デバッグ表示用(debug.php)

 以下のようなデバッグ表示用のPHPを作成します。
<?

//////////////////////////////////////////////////////////
//	ここで使う関数					//
//////////////////////////////////////////////////////////

	//==============================================================//
	//	関数:print_dispdata					//
	//	内容:表示します					//
	//	引数	$data	表示するもの				//
	//		$mae	表示時、行の前の文字(スペース)	//
	//==============================================================//
	function print_dispdata($data,$mae)
	{
		foreach($data as $key => $val)
		{
			if ( is_array($val)	==	true)
			{
				print $key . "は、配列<BR>";
				print_dispdata($val,$mae . " ");
			}
			else
			{
				print $mae . $key . ":" . $val . "<BR>";
			}
		}
	} 
?>

<?
//////////////////////////////////////////////////////////
//	プログラム開始					//
//////////////////////////////////////////////////////////
	session_start();

?>

<html>
<head><title>テスト結果</title><head>
<body>

<h3>テスト結果</H3>
<? 
	print_dispdata($_SESSION,"");
?>

</body>
</HTML>

(上記の < > ¥ は実際には半角です)

 表になっているところは、配列なので、配列の場合は、キーと中身を再帰的に表示するようにしています。

 あとは、前のブログ で作成したファイル(コントローラーctl.phpとshori.phpが必要)を用意しておきます。

 そして、ドライバ用として作成したファイルを開いてください(http://127.0.0.1/ドライバ用ファイル.php のように、httpプロトコルのURLを入れて呼び出してね。C:¥program files¥なんとかかんとかみたいなかんじのファイル形式で呼び出さないでね!!ファイルをIEにドロップしても、ファイル形式になってしまうので、プログラムが見えるだけだよ!!)。

こんなかんじで、処理結果が見えます

テスト結果

username:課長 nextURL:OK.php debug_mode:YES dengonは、配列 1は、配列   simei:社長   naiyo:健康に注意して馬車馬のように働け 2は、配列   simei:部長   naiyo:オレの給料を上げるため、お前らは死ぬほど働け 3は、配列   simei:係長   naiyo:あのー、できないことを要求されても、できません





 で、実際には、ユニットテストだけでなく、ある程度処理をまとめて、結合してテストしたいわけです。その場合、画面表示までやるのであれば、デバッグモードをYESにしないで、テストすればいいし、いくつかの処理をさせたあとで、表示させたければ、コントローラー(ctl.php)の

if ( $_SESSION['debug_mode'] == "YES")

のところを、

if ( $_SESSION['nextURL'] == とめたいURL)

 のようなかんじで、nextURLに、とめたいURLの値がセットされていたら、debug.phpを表示するように書き換えればOKです。そこまでの処理結果がdebug.phpで表示されます。




 ということで、テスト方法についても書いたので、
 つぎは、コントローラーで集中管理する方法(カオル姫-テンさん方式(集中))です。
(覚えていて、気が向いたら)



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PHP等でMVCにわけて、アジャイルっぽく開発できるようにするためのコーディング方略と例

2005-11-23 13:37:03 | PHP

 PHPで、画面と処理部分に分けるお話で、ちゃんとコントローラーをいれることにより、ユニットテストもできるようにするためのコーディング規約、
 つまり、カオル姫-テンさん方式について、ここにご披露いたします。

 今回は、カオル姫-テンさん方式の分散のほう、つまり、コントローラーは、汎用的で何にでも使えるが、コントローラーをみても、次の画面については、なにもわからない(次の画面指定は、VIEWやモデルで指定する)について、具体例を示して、説明します。
 なお、今回は、テスト部分は、説明しません。ユニットテストの方法は、次回以降、気が向いたときにします。
 で、この方法は、ちょっとひねると、CGIでも、なんにでも使えるはずっす。




■■ 方法の概略
 この方法の概略は、こんなかんじ
・はじめのフォーム入力画面で、
  FormのAction先をコントローラーに指定します
  input type="hidden" name="nextURL"で、valueに、処理を行う(モデルとなる)
  URLを指定します。

・コントローラーは、
  セッションをスタートし、
  フォームの値等、$_POST,$_GETに入っている値をセッションに入れて
  セッションのnextURLで指定されたURLへ、遷移する
   →nextURLには、次の処理先や、遷移したい画面(VIEW)が入ってる

・処理プログラム(モデル部分)は
  セッションの値をもとに、DBアクセスなどをして、
  次の処理や表示する画面をきめて、セッションのnextURLに、URLをセット
  次の処理で使う値や、画面に表示する値をセッションに入れて
  headerのLocationにコントローラーのURLをセットし、
   コントローラーに戻る。
   →コントローラーに戻った後は上記のコントローラーの処理で
    nextURLに指定した画面または、次の処理へ遷移する

・画面では、セッションをスタートし
  動的部分に関しては、セッションの値をもとに、表示する
  なので、基本的に、foreachと、printくらいしかない。

という感じになります。




■■ 具体例
 では、以下に具体例をしめします。
 今回は、こんな伝言板を考えます。

 1.画面から、ユーザー名をいれます。
 2.ユーザー名が課長でなければエラー画面(再入力)
   課長なら、伝言をセットします
 3.エラー画面は、ユーザー名が再入力できて、2へ行きます
   正常画面は、伝言を表示します。

 では、以下、ソースを示します。




●はじめの、ユーザー名入力画面
ユーザー名入力画面は、こんなかんじ。
<HTML>
<HEAD><TITLE>てすとだぴょん</TITLE></HEAD>
<BODY>
<Form action="ctl.php "method="post">
    <input type="hidden" name="nextURL" value="shori.php">
    Name:  <input type="text" name="username"><br>
<input type="submit" name="submit" value="実行">
</form> 

(上記の< > は、実際には、半角です)

FORMのactionに、コントローラー(ctl.php)を指定し、
inputのhiddenで、nextURLに、処理プログラム(shori.php)を指定しています。

●コントローラー
 コントローラーは、今回のプログラムにかかわらず、どれも同じです。
<?
//==============================================//
//						//
//	コントローラー(どんなときでも共通)	//
//						//
//==============================================//
	//	セッションをスタートさせる
	session_start();

	//	引数をセッションにいれる
	foreach($_POST as $key => $val)
	{
		$_SESSION[$key] = $val;
	}
	foreach($_GET as $key => $val)
	{
		$_SESSION[$key] = $val;
	}

	//	次のURL(VIEWまたはモデル)へ遷移
	if ( $_SESSION['debug_mode'] == "YES")
	{	//	デバッグモードのときには、デバッグ用画面
		$headwd = "Location:debug.php¥n¥n";
	}
	else
	{	//	それ以外のときは、次のURL画面
		$headwd = "Location:" . $_SESSION['nextURL'] . "¥n¥n";
	}
	header($headwd);

?>

(上記の< > ¥ は、実際には、半角です)

 セッションを開始し、$_POST,$_GETの値(フォームの値)を、$_SESSIONにいれ、nextURLで指定されたURLに遷移します。なお、デバッグモードに関しては、次回以降で説明します。

●処理プログラム(モデル)
 モデル部分は、こんなかんじです
<?
//==============================================//
//						//
//	伝言設定処理部分			//
//						//
//==============================================//

  	//	セッション開始
	session_start();

	//	データセット
	//	本当は、DB検索とかをする
	$rec['simei'] = "社長";
	$rec['naiyo'] = "健康に注意して馬車馬のように働け";
	$data[1] = $rec;

	$rec['simei'] = "部長";
	$rec['naiyo'] = "オレの給料を上げるため、お前らは死ぬほど働け";
	$data[2] = $rec;

	$rec['simei'] = "係長";
	$rec['naiyo'] = "あのー、できないことを要求されても、できません";
	$data[3] = $rec;

	$_SESSION['dengon'] = $data;

	//	次のURLを設定
	if ( $_SESSION['username'] == "課長" )
	{
		$_SESSION['nextURL'] ="OK.php";
	}
	else
	{
		$_SESSION['nextURL'] ="NG.php";
	}

	//	コントローラーに戻す
	header("Location:ctl.php¥n¥n");
?>

(上記の< > ¥ は、実際には、半角です)
セッションをスタートし、表示する値などを取得、セッションに設定して(本当はDBからとってきたりするんですけど、ここでは、固定値を入れます)値によって、次の処理や画面を決定して、nextURLに設定し、コントローラーに遷移します。

●画面表示部分(VIEW)

まず、エラー(NG)画面は、こんなかんじです
<?
//==============================================//
//						//
//	NG画面(もう一度再入力)		//
//						//
//==============================================//
	session_start();
?>
<HTML>
<BODY>

<h1><font color="red">入力した名前は間違えています</font></h1>

<Form action="ctl.php "method="post">
    <input type="hidden" name="nextURL" value="shori.php">
    Name:  <input type="text" name="username" value="<? print $_SESSION['username']?>"><br>

<input type="submit" name="submit" value="実行">
</BODY>
</HTML>

(上記の< > ¥ は、実際には、半角です)

 画面表示なので、セッションをスタートさせ、printで値をセッションから取り出し、表示しています。同時にこの画面は(再)入力画面なので、はじめに取り上げた入力画面同様、FORMのactionをコントローラーにして、処理先(shori.php)を、input のtype=hidden name=nextURLで設定しています。

 正常(OK)画面は、こんなかんじです。
<?
//==============================================//
//						//
//	OK画面(伝言表示)			//
//						//
//==============================================//
	session_start();
?>

<HTML>
<BODY>

<? print $_SESSION['username']?>さんへ<p>

今日の伝言<p>
<table border=1>
<? foreach($_SESSION['dengon'] as $rec){ ?>
<tr><td><? print $rec['simei'] ?></td><td><? print $rec['naiyo'] ?></td></tr>
<? }?>
</table>
</BODY>
</HTML>

(上記の< > ¥ は、実際には、半角です)
 
 セッションをスタートし、セッションの内容をprintで表示しています。




 ということで、ここまででも、結構長くなってしまったので、プログラム規約のまとめや、テスト方法に関しては、記事を改めて書きます。

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする