こんにちは、本日が39回目の誕生日の @illypon です。
別にバグをすべて見つけてしまっても構わんのだろう?
さて、ACCESS Advent Calendar 2019 12日目は、ソフトウェアテストが本業でない方に向けて、
暗黙的要求のうち、ぱっと思いついたものを5154連発で紹介したいと思います。
ここでの暗黙的要求とは、要件定義書や外部設計ドキュメントには明示的には書かれていない、
もしくは省略されがちだけれども、当然のように期待されている機能やふるまいのことを示しています。
ワーディング編
No.1 ワーディング仕様に一貫性がある
- 用語や略称が定義されていること。
- 表現にゆらぎがないこと。
- ですます調がいずれかに統一されていること。
No.2 メッセージが冗長でない
- 「~することができる」のような冗長な表現を回避する。
- 例でいうと「通知することができます。」➔「通知できます。」または「通知します。」にする。
- 受動態で表現するのも基本的には回避した方がよい。
- 「○○は削除されます。」よりも「○○を削除します。」の方が短くなる。
No.3 メッセージが長すぎない
- 文章の量を減らせない場合は別途ヘルプサイト、FAQサイト、マニュアルに誘導する。
No.4 エラーメッセージが誘導的である
- どんなエラーが起きたのかだけでなく、そのエラーが起きたときユーザーはどう対処するべきなのかが明解に分かるエラーメッセージとする。
- 回復可能なのか、リトライする意味があるのか、復旧するまで待つしかないのかわかるようにする。
- 場合によっては誰に問い合わせるべきなのかを明確にするとよい。メーカーなのか、管理者なのか。
デバイス依存編
No.5 キーボードだけでも操作できる
- マウスなどのポインティングデバイスのないPC環境を考慮しておくことが大切。
- どこにフォーカスが当たっているのか明瞭になるようにUIを描画すること。
- キーボードだけで操作できないシステムはアクセシビリティの考慮が欠けている。
No.6 タッチパネルだけでも操作できる
- タッチパネル操作、ソフトウェアキーボードの利用で操作できないことがない。
- 小さすぎて指で操作するのが大変になるようなコンポーネントを作らないことが大切。
No.7 狭い画面でもレイアウトが破綻しない
- 具体的にはHD解像度(1366x768)のような狭い画面でレイアウトが破綻しないこと。
- 低解像度環境は特に企業ユーザーに多い。相手先企業で一般的に使われているPCのスペックを聞くのもよい。
No.8 大きい画面を生かす
- No.7とは逆で、Full HDや4Kモニタなどを利用したときに、その画面サイズを生かすこと。
- 何の情報表示にも使われないマージンが意図せず大きくなりがち。もちろんあえて余白を作ることもある。
No.9 表示スケールを変更しても正しく表示できる
- Windows 10であれば、ディスプレイ設定の表示スケールの設定に依存せずに正しく表示できること。
UIコンポーネント編
No.10 長すぎる文字列を表示しなくてはならないときの表現方法を明確にする
- テーブルなどで長すぎる文字列を表示しなくてはならないときの表現を明確にしておく。
- 一定文字数までは表示して省略するか、すべて表示するか、改行させるかさせないかなど。
No.11 ボタンなど、UIコンポーネントは見た目通り直感的に操作できる
- ボタンなのにラベルの部分しかクリックできないボタンなどは作りがちなので気を付ける。
No.12 不必要に横スクロールしない
- 極端にデータが多い画面やプレビュー機能などを除き、横スクロールさせないこと。
- 横スクロールしないと見えないところにデータを置くべきではない。
- 横スクロールバーの高さの分だけ縦方向の情報量が減ってしまう、また、レイアウトが崩れやすい。
No.13 モーダルやアラートに過剰な実装をしない
- モーダルやアラートはもっぱら通知や簡素なインタラクションのために用いること。
- モーダルやアラート上で情報の編集などの複雑な処理をさせない。
No.14 ESCキーでモーダルは閉じる
- モーダル表示中にESCを押すとキャンセル扱いとする。
No.15 モーダルの外をクリックすればモーダルは閉じる
- モーダル表示中にモーダルの外側をクリックするとキャンセル扱いとする。
No.16 モーダルを表示中は背景を操作できない
- モーダルが表示されている最中、ドラッグ操作やマウスホイール操作の対象はモーダルである。
- 背景のボタンを押せてはいけない。
- TABキーを押してもフォーカスが背景のコンポーネントにあたってしまわないようにする。
No.17 モーダルの背景の明度を下げすぎない
- モーダルの背景が読めない場合、モーダルを使用する意味を喪失する。
- モーダルとは、背景の情報を見ながら何か意思判断をするためのものだということを忘れないこと。
- 背景を暗くする場合は視認性まで失わないように注意する。
No.18 モーダルの位置をずらせる
- モーダルで隠れている裏に処理対象の肝心な情報がある場合、モーダルをずらして見れるようにする。
No.19 連打してほしくないものを連打できないようにする
- 大きいデータをPOSTする処理やバックエンドに非同期処理を依頼するものなど、連打してほしくないものに対する連打抑制をすること。
- マウスクリックの連打だけでなく、エンターキー押しっぱなしなどもケアする。
- ユーザーがキーボードの上に物を置いたままにしたことによってダウンしたWebサービスを見たことがある。
No.20 UIコンポーネントに無尽蔵にデータを入力できないようにする
- どのような実装手段でも構わないが、無尽蔵に文字列を入力できたりしないように、UIコンポーネントに制限をかけること。
- 入力制限のないテキストフィールドに大量に文字をいれるだけで、大抵のWebブラウザーはいずれフリーズする。
No.21 パンくずリストは階層単位でクリックできる
- パンくずリストがただの文字列ではなくショートカットとして機能するようにする。
- どの階層にもワンクリックで遷移できること。
- ページcを表示していて、パンくずリストが
Top/a/b/c
という見た目であれば、Top
a
b
がそれぞれ有効なリンクとなること。
No.22 不必要なパンくずリストを実装しない
- すでにわかりやすいページ構成になっていたり、小規模なシステムではパンくずリストの存在自体が冗長になることが多い。
No.23 初期値でいずれも選択されないようなラジオボタンを実装しない
- ユーザーが選択するまではどれも選択されていない状態を許容するようなラジオボタンによる実装を行わない。
- 選択していないことが何を意味しているのか不明になってしまう。
- また、ラジオボタンは一度選択すると非選択の状態にできないので初期値に戻せなくなる。
気の利いたUI・機能編
No.24 初期値に戻すことができる
- 初期値、初期設定に戻すことができる機能がある。
- 初期値仕様が明確である。
No.25 特定の条件のときのみ利用する設定値を保存しておく
- 例でいうと、ある機能のON/OFFをONにしたときにだけ追加の設定が可能になるようなUIで、その機能をOFFに変更しても追加の設定が失われないこと。
No.26 サイドバーがコンテンツに引きずられてスクロールしすぎない
- 縦長のコンテンツをスクロールしたとき、サイドバーはつられてスクロールしないように考慮する。
- メニューやサイドバーが何のために存在しているか考え直す。
No.27 ソート方法や1ページ表示数といった表示オプションを保存する
- ログインユーザー単位で、ソート方法や1ページ表示数といったちょっとした表示オプションの選択を保存する。
- Webブラウザー単位で覚えさせるのではなく、アカウントに紐づけて保存する。
No.28 設定の意味、効果がわかりにくいものは画面に書いておく
- マニュアルを読ませたりFAQに飛ばすのではなく、画面上にこの設定はどのように機能するかを示しておく。
- テプラの貼られた7cafeのコーヒーマシンのように、見た目が悪くても使い方がわかる方がはるかにマシ。
- 詳細はヘルプサイト、FAQサイトに誘導する。
No.29 入力値の有効範囲がわかりにくいものは画面に書いておく
- はじめからわかりづらいの入力規則を要求するのであれば、静的な文章でフロントエンドに書いてユーザーに見せるようにしなければならない。
- バリデーションが走って初めてエラーメッセージが出るというシステムは気が利かないシステムであり生産性が低い。
No.30 エラーが発生してもユーザーの今までの入力を消さない
- バリデーションに引っかかったり、エラーが発生しても、ユーザーが今まで入力した文字列等を再入力しなくてはならないような事態を回避する。
No.31 時間がかかる処理をしている最中はプログレスバーを表示する
- プログレスバー、スピナーを表示する。
- あわせてプログレスバーを表示している最中にユーザーが同じ操作を連続して行わないように無効化の対処をする。
No.32 時間がかかるフロントエンドの処理をする場合は警告する
- フロントエンドで重い処理をさせる場合、Webブラウザーを閉じないようメッセージを表示する。
- Webブラウザーが応答を停止する恐れがある場合にも警告する。
No.33 重大な処理をする前にはユーザーに確認をする
- 削除や一括置換のような影響度の大きい処理をする際には、本当に実行していいかユーザーに確認をすること。
No.34 意味のあるソート方法になっている
- その画面のユースケースを考慮したときに最もふさわしいソート方法をデフォルトのソート方法とすること。
- 意外と何も考えずに内部的なID順、作成順などでソートされがち。
ファイル運用編
No.35 CSVファイルのカラム順を自由に変更できる
- CSVファイルの解釈をする際にカラム順を固定でみなさず、ヘッダーカラムを解釈するようにする。
- ユーザーは柔軟にCSVファイルを編集することができ、ヘッダーカラムさえ正しければ処理される。
- この暗黙的要求への対応は重いので、許容しない場合には、仕様書に対応しない旨を明記するのがコツ。
No.36 受け入れるデータの仕様を変更した場合、過去に作らせたデータが無駄にならないようにする
- インポート可能なCSVファイルのフォーマット仕様を大きく変更する場合など、ユーザーがアップロード時にフォーマットを選択できるようにし、過去の資産が無駄にならないようにする。
No.37 特定の文字コードしか処理できない場合はまず文字コードを判定する
- よくあるのがUTF-8エンコードのファイルしか受け付けない仕様なのに、入力したファイルがUTF-8かどうかをチェックしないケース。
- 大量の文字化けデータ登録してしまわないように、文字コードを判定する処理をかならず入れる。
No.38 ダウンロードされるファイルの命名規則を決めておく
- 毎回同じ名前でダウンロードされるのはユーザーからすると気の利かないシステムだし、業務のミスにつながる。
- ダウンロードファイルの命名規則は忘れがちなので気を付けること。
- prefixとtimestampの組み合わせなどで、いつ時点の何のファイルかわかるようにするのがよい。
ログイン状態編
No.39 セッションタイムアウトしたら半自動的にログイン画面に遷移する
- セッションタイムアウトしたらユーザーに通知、ログイン画面に遷移して再ログインを促すところまで案内する。
- セッションタイムアウト後も一見使えるように見えてしまうと、データ損失につながりやすいので注意する。
No.40 ログインしていない状態で特定のページにアクセスしたらログイン画面にリダイレクトする
- 404エラーを見せて終わり、ということがないようにする。
No.41 ログインしていない状態で特定のページにアクセスしたらログイン画面にリダイレクトし、ログインしたら最初に行こうとしていたページに遷移する
- ログイン画面にリダイレクトする際に、リファラーのURLを覚えておく。
- ログインした後、初期画面に行くのではなく、ユーザが見ようとした画面に遷移する。
No.42 ログイン済みの状態でログイン画面を開いたら初期画面に遷移する
- ログイン済みなのにログイン画面を操作させないようにする。
セキュリティ・運用編
No.43 ロール権限による機能制限をUI導線の制御だけで実現しない
- ロール権限によって使用できない機能がある場合、機能への導線にフタをするだけではなく、直接、画面やAPIにアクセスされても問題のないようにする。
No.44 ログイン履歴や操作ログなどを監査できる
- どんな方法でもよいが、ログイン履歴や操作ログといったものを残してあとで見る手段を用意する。
No.45 テナントやユーザーを削除しても、関連するデータは引き続き閲覧できる
- テナントやユーザーアカウントを削除した場合、それらの情報に密接に紐づいていた機能・画面はどのようにふるまうべきか考慮する。
- 削除するべきでないデータについては論理削除として無効化するにとどめるなど。
No.46 サービスをダウングレードしても過去に作成したデータが利用可能
- たとえばオプションサービスを解約した後も、過去にそのオプションで作ったデータの閲覧だけはこれからもしたい、といったことはよくある。
- このようなときに対応できる設計となっているか。
No.47 一度使ったトークンは再利用できないようにする
- アカウント作成や、メールアドレス変更の処理に使ったトークンは一度使ったら無効にする
No.48 新しくトークンを発行したとき、古いトークンを無効化する
- アカウント作成や、メールアドレス変更の処理を繰り返した場合、最新のトークン以外は無効にする
No.49 トークンに有効期限を設け明示する
- トークンの有効期限を明示し、それを過ぎたら処理に失敗するようにする
- その場合新しくトークンを生成するために、ユーザーに操作を最初からするように促す
- トークンの有効期限を示す場所はWeb画面であったり、ユーザーに配信したメールの文中でよい
重箱の隅編
Mo.50 受け入れる文字コードと改行コードの仕様をはっきりさせる
- UTF-8のときBOMはいるのかいらないのかどっちでもいいのか。
- 改行コードはCR+LFなのかLFなのかどっちでもいいのか。
No.51 CSVインポートする際に既存データを変更しない方法と、既存データを空にする方法を明確にする。
- たとえばCSVのセルが空のときは何もしない、CSVのセルが
|NULL|
なら空にする、CSVのセルが|DEF|
なら初期値に戻す、などといった仕様を明確にする。 - 特にどうやったら空にできるのかは忘れがちなので気を付ける。
No.52 設定値と真偽の意味の関係性を統一する
- あるオプションでは1だとON、0だとOFFという意味なのに、別のオプションだと1がOFF、2がONだったりすることがないようにする。
- 作った人や時期が違うとバラバラになりがち。
No.53 パラメーターを省略したときのふるまいを明確にする
- 設定ファイルのオプションや、API仕様で省略可能なパラメーターを省略したとき、どのようなふるまいをするのかを明確にする。
- 初期値を明確にすることと考え方は似ています。
No.54 設定やパラメーターを重複定義した場合のふるまいを明確にする
- 長い設定ファイルなどで同じ設定を2か所に重複して書いてしまった場合など、後勝ちになるのかそれともプログラムがエラーになるか明確にする。
終わりに
仕様書通りにしっかり作ったはずなのに、やたらとテストチームや営業担当者からバグ報告や改善依頼が来る場合、暗黙的要求を満たしていないことが多いです。
また暗黙的要求は、特定の業界の人(お客さん)にとっては常識事項だということも多く、満たしていないと大きな問題に発展することもあります。
中には「前に使っていた他社製品と同じように使えるようにして欲しい」みたいな理不尽な暗黙的要求もありますが、乗り換えビジネスをするのであればそういったことも真剣に考える必要があります。
いずれにしても、バグや改善依頼として報告されたものをあとから直すのは労力が大きくかかります。
普段からなるべく多くの暗黙的要求の要素を知識として持っていて損はないでしょう。
外部仕様書は頼りになる存在ですが、それがすべてではないし、間違っていることもあるってことです。
さて、明日は @aRyoKuroda が何かLinuxネタを書いてくれるみたいです。お楽しみに!