次プロジェクトへ向けて、社外への開発会社への要件定義や、その要件を満たしているかどうかの検収方法について考えていた時に、
テストを行った結果の可否のみがシンプルだという答えになり、
Unity上でのテストを行う手段の一つとして、「TestRunner」という機能があるようなので、
テストしてみた。
今回は、そもそもテストとは何なのだろう?という考察
めちゃくちゃ長い内容なので、最後のまとめから逆走してみると、興味が切れなくていいかも。
〇テストって何?
まず、なぜこのトピックを考察する必要があるかと言うと、
「テスト」という目的は、具体的にはどういう事か説明できるのかどうか、という事だ。
読者の皆様に質問だが、下記の項目の定義を、自分自身で明確に出来ているだろうか?
・デバッグ
・テスト
・QA
ここに関しては、それぞれの回答があって良い。
ただし、ごっちゃになっていたり、明確な違いを定義出来ていない場合は、
テストについて手段を考える前に、テストの目的を明確にした方が良いと思う。
筆者が想定している各定義は、
〇デバッグ
「プログラム実装作業者(=受注側)」が行うプロセス。
作成した成果物が、要件定義された挙動を行うかを確認する作業の事。
〇テスト
「発注側」が行うプロセス。
場合によっては、「受注側」も行うかもしれない。
「受注側」が納品してきた物を、「発注側」の要件を満たしているかどうかの、
「満たしている」を確認する為に行う作業の事。
これを満たさなかった場合は、検収不可となる。
〇QA
「発注側」が行うプロセス。
成果物の内容が、きちんと製品としての価値があるか、
「クオリティを担保しているか」どうかを確認する作業の事。
「クオリティ」という物は、これまた話すと一つのトピックになってしまうので、あまり掘り下げないが、
要は「これで、世に出して良いのかどうかの判断を行う事」とでも思っておけば良い。
デバッグはQA作業の中の一つの側面でしかなく、テストは最低限クリアすべき作業の一つでしかない。
ここに関しては、「受注側」は無関係だ。
QAの結果、受注側に要件定義を変更した上で、再開発依頼などを行うかもしれないが、
QA業務自体は、受注側は絡まない。
そして、本記事で説明してる「テスト」とは、
>「発注側」が行うプロセス。
>場合によっては、「受注側」も行うかもしれない。
>「受注側」が納品してきた物を、「発注側」の要件を満たしているかどうかの、
>「満たしている」を確認する為に行う作業の事。
>これを満たさなかった場合は、検収不可となる。
これを行う事を目的とし、その手段を取り上げる。
目的が異なる場合は、参考にならないかもしれない。
〇要件定義書の通りに動いているとは
先ほどの定義で、
>「受注側」が納品してきた物を、「発注側」の要件を満たしているかどうかの、
>「満たしている」を確認する為に行う作業の事。
としている以上、
・要件定義書(=仕様書)があり
・納品された物が、要件定義書の通りに動いているかを、確認する作業
であると言える。
では、
>要件定義書の通りに動いているか
は、どうやって定義するのかを考えると、解決に近づいていく。
恐らく、大多数のゲーム制作チームでは、ここの部分を
・更新されていない仕様書を見ながら、もしくは見ないで
・とりあえず、納品されたゲームを実機で適当に動かしてみて
・何かおかしくないかどうか、勝手な主観によって判断して修正を行う
といった業務、いや、これをテストの「定義」として、無自覚に行っている物と推測される。
テストの定義がこれで良ければ、筆者のこれから話す内容を実践する必要は無い。
筆者は、これでは問題がある、というより、発注者側としてこれでは困る事が多いと思っている。
特に、
>勝手な主観によって判断して修正を行う
この、人の捉え方によって評価が変わってしまうというのが、問題だ。
なので、筆者のテストの定義は
「成果物(Unityプロジェクト)に対して、記述したテストプログラムが、全て正常の結果を出す事」
とした。
こうすれば、人によって認識が変わるといった余地はなくなる。
〇実際に何をチェックすればよいのか
「要件定義書の通りに動いているかどうか」
は、
「記述したテストプログラムが、全て正常の結果を出す事」
という定義が出来た。
では、実際にゲーム開発でのテストプログラムは何をチェックすれば良いのだろうか?
まずは、その取っ掛かりとして「正常」とは何なのかを考えるといいだろう。
・正常とは?
筆者は、そのチェックを行う瞬間に状態が、想定している状態であれば「正常」と定義している。
想定している状態というのは、具体的に言えば
・表示されている画像
・表示されている文字
・表示されているオブジェクト
・内部的な数値(ダメージ計算結果など)
などだ。
例えば、ホーム画面に入ったある瞬間を切り取り、そこでテストを実行した際に、
想定される画像と、実際に表示されている画像を比較し、同じかどうかを確認する、
といった事を、テストしたい項目分記述すればよい。
>そのチェックを行う瞬間
これの事を便宜上「スナップショットを取った瞬間」とでもしておく。
つまり、テストとは、
要件定義者が、検収を行うために、
どれだけ
「スナップショットを取った瞬間」
が必要かを洗い出し、
それらのスナップショットに対して、
「その瞬間には、こうなっているはずだ」
という、正常系のまとまりとなる。
・テスト範囲
テストで「正常」を確かめるのであれば、正常以外は全て「異常」となる。
ただし、「異常系」が無い事を全てチェックするのは、際限がない為、お勧めしない。
例えば、
・設定ボタンを押したら、所持金が1000増えない事
といった事を気にしていたら、無限にテストを記述する事になる。
なので、テスト範囲はあくまで「正常系かどうか」のみに焦点を当てる。
テストでは検知できないが、見た目上、明らかにおかしい事柄についての検知は、
こういう物こそ、「QA」の範疇となる。
つまり、テストを通すということは、あくまで最低限の事であり、
製品として成り立っているかどうかの作業は、テストだけでは不十分なのだ。
纏めると、
・正常系とは、ある瞬間の状態が、想定している状態と同じと言える事を確認する事と、定義する
・テストとは、ある瞬間の状態が、想定している状態と同じと言える事、の大量の寄せ集めである
・テストは、正常系のみを扱う
・正常系以外で発生する問題は、別途対応を行う
こんな感じだ。
〇実際にテストを書こうと思うと、実装側の設計から関わる事になる
では、
>・テストとは、ある瞬間の状態が、想定している状態と同じと言える事、の大量の寄せ集めである
このテストプログラムを書こうと思うと、すぐに気づくことがある。
画像が同じかどうかを比較しようと考えるとわかる。
さて、表示されている画像を比較の為に取得するには、どうすればいいのだろうか?
この辺りの内容は、かなり内部的な話になるので詳細は次回以降にするが、
テストを行うために、比較用のオブジェクトやパラメータを取得する為の、何らかのルールが必要になる。
・例えば、オブジェクトを名前で取得する場合は、同名の名前を付けられると「GameObject.Find()」で取得してこれないので、
同名の名前は付けない
・例えば、内部的なパラメータを管理しているクラスのパラメータが想定している数値かどうかを確認する為に、
ゲームには使わないが、Privateパラメータを取得する、テスト用のGetメソッドを作成する必要がある
などだ。
テストを書く(設計する)人間は、エンジニアのスキルセットが必要になる。
できればプロジェクト初期から、設計に関わる必要がある。
〇まとめ
1.テストとは、「発注側の要件を満たしているかどうかの、「満たしている」を確認する為に行う作業の事。」と定義する
2.「要件を満たしているかどうか」とは、「成果物(Unityプロジェクト)に対して、記述したテストプログラムが、全て正常の結果を出す事」と定義する
3. 実際にチェックする内容は、ある瞬間の状態が、想定されている状態かどうかをチェックする。これを大量に行う事である。
4. テストを実際に行おうとした場合は、設計に密接に関係するので、エンジニアのスキルセットが必要になる
こんなところだろうか。
次回以降、この内容を前提として、実際にどのようにプログラムを書いていけば目的を達成できるか、説明していく。