日本Androidの会テスト部が、いままで培ってきたAndroidアプリ開発におけるテストのノウハウを、実際のテストコード例とともに紹介していきます
著名なソフトウェア開発プロセスモデルに「Vモデル」があります。
開発プロセスの中でいつ、誰が(左側が開発、右側がテストを示す)、どんな役割を果たすべきか、を順序立てて表したモデルで、Androidテスト部におけるワーキンググループも、この右側を上下に分割する形でカテゴライズしています。お察しの通り、これまでの連載では、このVモデルにおける下層の部分、ユニットテスト(単体テスト)と結合テストに当たる部分を主に取り扱ってきました。
連載第7回では、このV字モデルから「ユーザーフィードバック」を少しはみ出させた形の何字(筆記体のV?)とも形容しがたい、でも、実際のBtoC向けスマホアプリによくある形の開発プロセスと、それにまつわるテストレベルを考えてみたいと思います。
上層のテストに取り掛かるとき(本当はプロジェクトが始まるときが望ましいのですが)最初に考えるべき要素に、「その製品がどうなっていたら“良い”と言えるのか」という品質のモデルがあり、大きく「機能要件」「非機能要件」に分かれます。
「機能要件」は、広い意味での顧客が求める要件や、問題の解決を直接取り扱う実装を指します。「非機能要件」は、すでに満たされている機能(≒実装)が、例えば動作を完了するまでの速度であったり、動作に必要なリソースの使用量であったり、という「どのように振る舞うのか」という観点を指します。
また、「SLA」「レギュレーション」などが事前に取り交わされている場合は「そこに記載された可用性や完全性を、どのように担保するのか?」といった観点も必要です。
「品質」は成果物に触れる人それぞれにポリシーや重要に思えることが異なるため、一概にその特性を「この項目とこの項目である」と定められません。故に、さまざまな団体から「例えば、こうである」とした“品質モデル”が提唱されています。現状、ソフトウェアのそれとして世界的に最も有名なモデルが「ISO/IEC 9126」です。
ユニットテストでは、選択されたアーキテクチャにおける最小限の内部機能単位、結合テストではその組み合わせ、特にコンポーネント間のインターフェイスに注目し、主にUIを介さない形でテスト実装を行い、実行します。
システムテストでは逆にUIを利用し、内部を完全にブラックボックス化して、最終的にユーザーが使うのとほぼ同じ状態でテストを設計、実行します。このように、システムテストは対象をあらゆる方面から総合的に試験するため、「総合テスト」とも呼ばれることがあります。
ではユニットテストや結合テストを十分に実施したうえでも見つかる、言うなれば「Vモデルにおける“下層”のテストで取りこぼす不具合」には、どんなものがあるでしょうか。端的には、速度や資源の有効利用、ユーザビリティ、セキュリティなど、非機能要件で定義される特性の多くが当てはまります。
これはインターフェイス結合時に「正しく疎通できること」を念頭にテストが考えられるからで、先述のような観点を持つことが少ないのが原因です。全体を結合する前に速度や資源を計測しても、あまり意味がなかったり、テストを記述するのに膨大なコストが掛かるケースが多いため、スコープとしては適切であると考えられます。
故に、すべてのコンポーネントが結合し、UIをかぶせた状態で行うテストを「QAテスト」と呼称し、主にアジャイルの文脈におけるテストエンジニアの主たるスコープであるととらえる向きもあります。これは機能要件が前段階でほぼ完全にテストされていることが前提になりますが、筆者は「それは難しいのではないか」というスタンスです。
なぜなら、ソフトウェア、特にスマホアプリは実利用環境に近づけば近づくほど主に外的要因による不確定要素が高まっていくからです。そのアプリに対するリテラシーの違いは思わぬ操作を引き起こしますし、利用環境の違い、並列実行環境や、ほかのアプリとの連携は、結合テスト時点ではなかなか想定しにくいものです。
ここで、システムテストレベルにおける実際の機能テストの一例を挙げてみましょう。ソフトウェアテストを考えるには対象のアプリが必要ですので、ここではメールクライアントの一部を考えてみます。
とあるメールクライアントの受信部分の仕様が下記のように定まっていたとします。
仕様としては心もとないですが、ともあれここから何らかの「モデル」を起こすことがソフトウェアテストの第一歩です。今回は上記の仕様から状態遷移図を起こしてみます。
さて、いきなり仕様に書いていない遷移が出てきていますが、[戻る]キーを押すと、1つ前のActivityが呼び出されるのは、Androidの通常想定される振る舞いでもあります。しかし、状態とActivityは必ずしも1対1ではありません。状態遷移表を起こす前に、まずこの状態遷移図の段階で開発チームと認識があっているかを詰めておくと良いでしょう。
状態/トリガ | 送受信ボタン押下 | 新着メール受信完了 | Subjectをタップ | [戻る]キー押下 |
---|---|---|---|---|
初期画面 | メール受信中 | N/A | N/A | アプリ終了 |
メール受信中 | メール受信中 | 受信メールボックス画面 | N/A | アプリ終了 |
受信メールボックス画面 | N/A | N/A | メール表示画面 | 初期画面 |
メール表示画面 | N/A | N/A | N/A | 受信メールボックス画面 |
表1 図2から起こした状態遷移表 |
前述の状態遷移図から、開発チームと認識を擦り合わせたうえで出来上がったのが上記の状態遷移表です。縦の列が状態を表し、この状態から横の列のイベントを発生(トリガ)させると、交差するセルの状態へ遷移する、というテストケースになります。「N/A」は何も起こらない、または、この状態でこのトリガを発生させることが不可能ということです。これが開発チームと合意のうえであることに注意です。本当にN/Aでしょうか? テスターの血が騒ぎますね。
結合試験まではテストの方針が「正しく」振る舞うことに焦点が置かれます。また、「正しい振る舞い」のイメージは、その時点での成果物でしか持ち得ません。これは仕方のないことです。よって、結合テストとシステムテストのちょうど中間辺りに、どうしてもカバーし切れない領域が生まれてしまうものの、実際のユーザーの利用環境とほぼ同等の成果物において論理的に導き出した有限のパターンを網羅することが、とても重要です。
次ページでは、Androidアプリ開発特有のシステムテストの難しさと対策について解説します。
Copyright © ITmedia, Inc. All Rights Reserved.