質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHPUnit

PHPUnitは、PHP向けのユニット・テスト向けフレームワークで、手動では手間のかかるテスト作業を自動化し、繰り返し実行することが可能です。

Q&A

解決済

1回答

1957閲覧

【phpunit】 ランダムな値を返す場合のテスト記述について

jirou6699

総合スコア4

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHPUnit

PHPUnitは、PHP向けのユニット・テスト向けフレームワークで、手動では手間のかかるテスト作業を自動化し、繰り返し実行することが可能です。

0グッド

0クリップ

投稿2022/04/18 09:26

やりたいこと

以下のようにランダムな値が返ってくるメソッドのテストを実行しようとしています。
assertSameを使用しても当然値がランダムに返ってしまい、テストが通らない状況です。
どういった考え方・コードが必要なのかご教示いただけないでしょうか。

コード

関数でarray_randをしているので、$allcardsからランダムに値を取って
$getCardsに格納しています。プレーヤ1名に対して2枚配布し、53枚のトランプの配列からランダムにカードを取得します。

$this->players = 2 ;
$allCards = ['ハート', 'A'], ['ハート', 2],['ハート', 3], ['ハート', 4], .......(トランプ53枚の配列)

php

1 public function getCards(): array 2 { 3 $allCards = $this->trumpCards(); 4 $number = $this->players * 2; 5 $randomCards = array_rand($allCards, $number); 6 $getCards = []; 7 foreach ($randomCards as $card){ 8 $getCards[] = $allCards[$card]; 9 } 10 return $getCards; 11 }

テスト(PHPunit)

ダメもとですが、今までの知識でテスト書いて見ました。
assertSameを使用し値を設定して見ますが、出力される値が当然ランダムなのでテストは通りませんでした。
そりゃそうですよね、、、

php

1 // ToDO:ランダムに生成した時のテストはどうするの? 2 public function testGetCards() 3 { 4 $card = new Card(2); 5 $this->assertSame([['ハート', 'A'], ['スペード', 2], ['ダイヤ', 3], ['クラブ', 4]], $card->getCards()); 6 }

実行結果

There was 1 failure: 1) blackJack\Test\CardTest::testGetCards Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ Array &0 ( 0 => Array &1 ( 0 => 'ハート' - 1 => 'A' + 1 => 2 ) 1 => Array &2 ( - 0 => 'スペード' - 1 => 2 + 0 => 'ハート' + 1 => 3 ) 2 => Array &3 ( 0 => 'ダイヤ' - 1 => 3 + 1 => 5 ) 3 => Array &4 ( 0 => 'クラブ' - 1 => 4 + 1 => 'A' ) ) /var/www/html/tests/CardTest.php:25 ERRORS! Tests: 3, Assertions: 2, Errors: 1, Failures: 1. Script ./vendor/bin/phpunit handling the phpunit event returned with error code 2

調べてみた事

記事を色々と探して見ましたが、参考になるコードなどは見つけられませんでした。
phpunitでランダムな値のテストについての記載がありましたが、よくわからない感じです。

下記引用
次に、 「ランダム値の場合」 です。
ここでも様々な意見が飛び交いましたが、ピックアップしてご紹介します。
・「srand」を使用し、固定のシード値を指定することで同じ結果を得る
・ランダマイザのようなオブジェクトを外出しにし、モックに差し替える
・「srand」を使用すると全体に影響するため、他のテストに依存させたくない時は前述の @runInSeparateProcess を使用する

https://tech-blog.rakus.co.jp/entry/20220124/php

やってみたこと

他にも色々と探っみたところ下記のように思って試してみました。
主に番目のランダムな状況を作り出してテスト実行するしかないのでは?と考えてみました。

  • 必要なアサーションが他にある?
  • テストコードでランダムな状況を作り出し、それをテストする

テストコード(再)

php

1 public function testGetCards() 2 { 3 $card = new Card(2); 4 $allCards = $card->trumpCards(); 5 // 配列の要素数が正しいかどうか 6 $this->assertCount(4, $card->getCards()); 7 8 $result = []; 9 foreach ($allCards as $card) { 10 $suit = $card[0]; 11 $number = $card[1]; 12 if ($suit === 'ハート' && $number === 'A') { 13 $result[] = [$card[0], $card[1]]; 14 } elseif ($suit === 'スペード' && $number === 2) { 15 $result[] = [$card[0], $card[1]]; 16 } elseif ($suit === 'ダイヤ' && $number === 3) { 17 $result[] = [$card[0], $card[1]]; 18 } elseif ($suit === 'クラブ' && $number === 4) { 19 $result[] = [$card[0], $card[1]]; 20 } 21 } 22 // foreachで回した結果が正しいかどうか 23 $this->assertSame([['ハート', 'A'], ['スペード', 2], ['ダイヤ', 3], ['クラブ', 4]],$result); 24 }

実行結果(再)

composer phpunit > ./vendor/bin/phpunit PHPUnit 9.5.20 #StandWithUkraine Runtime: PHP 8.1.4 Configuration: /var/www/html/phpunit.xml ... 3 / 3 (100%) Time: 00:00.046, Memory: 6.00 MB OK (3 tests, 4 assertions)

考えたこと・思ったこと

そもそも自分でランダムな環境を作り出すとテストの意味はない?と思ってしまいますが、他に考えがなく困っています。
ランダムなテストコードの書き方・考え方をご教示いただけないでしょうか。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

そもそも自分でランダムな環境を作り出すとテストの意味はない?

はい。
特定のインプットに対して特定の値をチェックすることになるので、返却値の内容がランダムなのであれば「文字数」とか「配列の総数」とかくらいしか当てられないと思います。

投稿2022/04/18 22:01

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jirou6699

2022/04/19 14:59

ありがとうございます。 ランダムに値がかえる時はご回答いただいた書き方でテストを実行しようと思います。 同じクラス内にメソッドをいくつも持たていて、ランダムな返り値が他のメソッドにも影響するような書き方をしていた事で、テストをどうすればいいのかわからずにいました。単一責任の法則に従ってメソッドを分割して影響をしないようにやってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問