テストの重要性について&テスト用ソフトウェア×23選

テストの重要性について&テスト用ソフトウェア×23選

Webシステムの開発に限ったことではありませんが、開発の現場で常に言われるのが「テスト」の重要性についてです。現在、プログラミングの世界ではユニットテストと呼ばれるような仕組みなどによって「テストファースト」が行えるようになってきています。が、実際の所は利用率は20%以下と思われます(そんなにもないかも知れません)。 そこで今回はなぜそのような状況にあるのかという点、そしてテストの重要性について考えたいと思います。

なぜテストを行わないのか

テストファーストやユニットテストといった言葉はその重要性は説かれていながらも実際の現場には浸透しているとは言えません。なぜかと言われた場合に以下のような理由が挙がるかと思います。

  • 自分の書いたコードにはバグがない(テストしなくても大丈夫)
  • テストを書いている時間がない
  • 仕様が変わるのでその度にテストを書き換えていられない
  • 面倒くさい。習得コストがかかる。

1. 自分の書いたコードにはバグがない(テストしなくても大丈夫)

バグがない、それは素晴らしいです。でも本当でしょうか。人間は誰しもミスを犯します。そのミスはデジタルであるコンピュータ上では特に顕著になります。バグを回避するというのはまず不可能なことであり、仕方がないことです。問題はそれをどうやって防ぐかになります。

一つの考えとしては、はじめからきちんと書くということがあります。これはコンパイル系の言語によく見られる方式で、Javaや.NETなどのようにIDEやフレームワークで品質をある程度担保するというものです。が、これでもバグが0になるということはまずありません。そしてスクリプト言語の場合、実行時に評価されるので向かない方式になります。そこでテストファーストでは、仕様をテストという形でコードに落とし込むことで、開発がある程度終わった段階でテストを定期的に細かく行うことで手戻りのリスクを下げられるようにします。

2. テストを書いている時間がない

時間がないというのもよく聞かれる言葉です。これはプロジェクトの終盤になってからテストをどうするか考えるために起こるものになります。言わばウォーターフォール的な考えで、開発が一段落した段階ですべてをテストしようとするために、開発の段階でテストの工数まで削ってしまい、時間がなくなってしまう事態に陥ります。テストファーストはその名称の通り、最初にテストを書きます。そのため時間のある時にテストを書けるので安心して仕上げることができます。そして実際のコードを各段階においても一度テストコードを書いているため仕様が把握できており、時間をかけずにコーディングができるようになります。

3. 仕様が変わるのでその度にテストを書き換えていられない

これは事細かにテストを書くから起こる問題です。例えばデータベースにINSERTする、UPDATEする、DELETEするといったコードを書いて、それが正しく動いたとして何の意味があるでしょうか。動いて当たり前(フレームワークレベルなど)なものについてはテストを書く必要性はないと考えています。独自のロジックについてテストを書くようにすれば、テストは限られた部分になりますし、ロジックであれば重要な部分であり間違った場合の手戻りが高くなることを考えれば、テストを書いておくのはメリットになるでしょう。

4. 面倒くさい。習得コストがかかる。

最後の面倒くさいというのは開発者の本音ではないでしょうか。確かに書かなくとも良いように思えるコードを書くというのは面倒な作業に見えるでしょう。が、先ほども書いたように一度ドラフトとしてコーディングをしておくことで、実際の実装が容易になるメリットがあります。また、テストのコードは言わば理想的に動作するコードを書けるので、ロジックが明確で実際の実装もスパゲティーになることなく開発できるようになります。ロジックがきちんとモデルとコントロールに分離して描ければ、コードはより短く、分かりやすいものになり、バグの潜む要因が減るはずです。

テストファーストのメリット

既に幾つかの要因は挙げていますが、テストファーストの最大のメリットは奇麗なコードが描けるようになることにあると思われます。何か問題があった時に、場当たり的に書いていくとコントローラ部分のロジックが長くなる傾向があります。が、テストファーストで理想的なコードを予め記述しておけば、ビジネスロジックとモデル内のロジックが分離され、より明確なコードが書けるようになります。

なぜテストファーストなのか

テストファーストは言わば検査機です。工業の世界において、何かを作成するということはまず検査機器が先にあります。例えば削った量を調べたり摩擦係数を調べたりする機器がはじめにあり、それを使って新たに作成した部品が要求性能内に収まっているかどうか調べることができます。なので工業の世界においてはテストファーストが当たり前なのです。

ですがシステム開発はそこまで汎用的なものではありません。検査機器も自分たちで作る必要があります。とは言えJUnitやTest::Unitなど部品を作るためのシステムは存在します。これらを利用することでより短時間で検査機器を作成し、開発したものについて検査が可能になります。

テストは早い段階で繰り返し行っておくのが重要です。そうすることでバグが小さいうちにつぶせるようになります。開発が進んでしまうとバグが大きくなり、修正コストも高くなります。さらに悲惨なのはバグを修正したことによって、元々正確に動作していた部分が不具合を起こしてしまうような事態を引き起こすことです。こうなると最早手がつけられなくなったり、場当たり的な対応が必要になってきます。

Joel on Softwareより

ジョエル氏によれば、開発を細かく区分して(その一区分をイテレーションと呼びます)行う場合、そのイテレーションごとにバグを徹底的につぶすべきとしています。つぶすべきバグが次のイテレーションに含まれたまま開発がスタートすると、そのバグによって次の行程の開発が阻害されることになってしまいます。そのためにもバグはできるだけ早い段階において取り除いておく必要があります。

よくあるケースとしては、開発者はバグがあるのを知っていつつも次の開発を進めており(そのバグは致命的ではなかったとしても)、テストやその開発状況を確認する人たちはそのバグによってシステム全体の品質を怪しんでしまい、次の行程に進まずにいるというケースがあります。これもユニットテストなど細かい範囲でのテストが的確に行われてれば解決する問題です。

テストは誰が行うか

ここでいうテストはユニットテストではなく、実際の出来上がったものに対するテストになります。これは開発者以外の方がすべきです。テストはシステム内部を知らないブラックボックスな状態でで行い、システム的なバグに限らず、違和感を感じた不具合的なものについても洗い出すようにします。開発者は開発とあがってくる不具合修正依頼に専念させることで、テストは別な人たちにお願いできるという安心感を与える必要があります。

テストの網羅性と正確性

テストを行う際に、全ての項目についてリストアップしなければテストできないと考える人たちがいます。例えばユーザ登録一つとっても、全てのパターンと各データの入力許容値などを全てリストアップし、表計算にまとめないとテストしたことにならないと考える人たちです。しかしこれは本当に有益なのでしょうか。

もちろん網羅性がないに越したことはありませんが、仕様を決める段階においてそこまで洗い出しているのでしょうか。また電話番号が11桁から15桁になったことによって甚大な被害につながることがあるのでしょうか。テストは網羅的にできればベストではありますが、仕様が100%網羅されていない限り,テストで100%対応するのは不可能です。そう考えると、テストはビジネスロジックであったり、サービスの売りになるポイントについて適切に行われれば十分ということになります。また、網羅性がないからテストができないというのは愚の骨頂です。やらないよりはやった方がよく、どのようなテストを行ったかきちんとまとめておく必要があります。大抵、そのようなことを言われる方は、自分自身が行うテストは怠惰的なものであり、結果と記録していないことが多いものです。

デバッグ情報を受け取る

ブラックボックスのテストが開始され、その後リリースされた後の行程について言えば、重要なのは利用者がある操作をした結果起こったエラーの内容をきちんと受け取るということです。エラーメッセージやそのファイル名と行数、変数の値などを受け取れれば大抵エラーの原因は分かるものです。それをきちんと記録し、まとめていくことでエラー原因の究明と修正を行えるようになります。リリース後のエラーは問題ですが、ブラックボックスのテストを行っている期間でもこのような対応をすることで8割以上のエラーはつぶせるかと思います。

結合テスト、総合テスト

結合テストや総合テストは本番環境や、他のインタフェースと接続してはじめて行えるテストになります。サービスのスムーズな立ち上がりを願うのであれば、できるだけ早い段階でテストを行うことに限ります。全てのメソッドが実装されていなかったとしても、モックを利用するなどしてインタフェースのテストが行えていれば改修も早い段階で可能になります。本番環境もできるだけ早い段階で用意し、その上でテストを行うべきです。開発環境はどこまでいっても開発環境でしかなく、実際の環境に移してはじめて起こるエラーは数多くあります。それらをぎりぎりのタイミングで対応するのではなく、できるだけ早い段階で本番環境を利用してスムーズに立ち上げられるようにしておくのが良いかと思います。

徹底してエラーをつぶしてもバグは出ると認識する

もし十分にテストを行い、全くもって問題がないと判断してリリースしたとしても、バグは必ず発生します。これは人が作るものである以上致し方がないことです。また状況の変化や仕様の把握ずれによってバグでない部分までバグになってしまうケースもあります。つまり100%は絶対にあり得ないと予め考えておくことで、品質が90%を越えた段階でリリースする等と決め、その後の運用状況の中で発生したバグについてつぶしていく形が良いのではないでしょうか。もちろん、その品質判断はシステムの種類によって異なります。

ソフトウェア

Winium - Windows向けソフトウェアでもSeleniumでテストしよう

画像

ソフトウェアのテストは幾つかの種類がありますが、実際にデモでソフトウェアを操作して行うテストとして有名なのがSeleniumです。当初はWebアプリケーション向けの仕組みでしたが、Appiumによってスマートフォンアプリのテストも行えるようになっています。さらに今回紹介するのはWiniumです。名前からも分かる通り、Windowsアプリの自動操作テストに使えるSelenium系ソフトウェアです。

STF – 無数のAndroidデバイスをWebブラウザから操作

画像

Androidはデバイスの種類が多いのでテストするのも大変です。そのため、一人で全てのデバイスをテストするのが困難で、ついついエミュレータベースでテストしてしまいます。しかし解像度が異なる場合や機能やスペックが異なるために快適な操作が得られるかは分かりません。そこで使ってみたいのがSTF(Smartphone Test Farm)です。Mac OSXやLinuxにつないだAndroidをWebブラウザから操作できるリモートコントローラです。

ie8linter - IE8互換性をチェック

画像

HTML5対応したWebサイトが増えています。新しいタグ、API、スタイルシートの設定をばんばん使いこなしていきたいですよね。しかし世の中には足を引っ張る存在がいます…それがIE8です。HTML5に対応していないながらも決して無視できないシェアをもっているため、面倒な存在です。そんなIE8に対応しているかどうか、チェックできるのがie8linterです。プロパティのチェックやHTML5専用のタグをチェックできるようになっています。IE8の時だけ読み込むスタイルシートを指定することでデザイン崩れは防げるはずなので、そういったライブラリを入れてチェックしましょう。

Monkey.js – Webベースのモンキーテストライブラリ

画像

テストは様々なパターンが存在します。ユニットテストもあれば結合テスト、負荷テストなどもあります。いずれも目的に合わせて選択する必要があります。しかしテスト項目は人が考えるもので、ある意味限界があるかも知れません。そこで試してみたいのがMonkey.js、Webベースのモンキーテストライブラリです。とにかく適当に触って入力してを繰り返すことで何か起きるかも知れない、そんな可能性を秘めています。デモでは一つのページ上だけで行われますが、Monkey.jsを全ページで呼び出しつつ、自動実行し続ければ何かエラーが起こる可能性があります。URLごとに遷移してしまう場合はまだいいですが、Webアプリケーションで画面遷移を行わないシステムの場合はJavaScriptでエラーを起こす可能性はあります。

Vangogh - iOSアプリのアクセシビリティテスト

画像

スマートフォンはあっという間に世間一般に知れ渡っていきました。爆発的に広がっていく中で利用者層も広がりを見せています。その中には健常者だけなく、何らかのハンディキャップを持った人もたくさんいます。アプリにおいてもそういった人たちに対するアクセシビリティが求められるようになってくるでしょう。色覚に問題がある状態をシミュレーションできるライブラリがVangoghです。iOS自体にも色覚を補助する機能がありますが、それと合わせた時にどう見えるかをテストしたり、色のコントラストが悪くて視認性が悪くなる部分がないかといったテストに向いているでしょう。

PaperTester – SIer感涙。テスト画面のスクリーンショットをExcelに貼付

画像

SIerなどで良く聞かれる話で、テストを行う際には1画面ずつスクリーンショットを撮ることが要求されます。中小企業のシステム開発会社からすると信じがたいのですが、テストを行ったという確認にもなるのであながり無意味ではないのかも知れません(それをダブルチェックしているかは不明ですが)。そんなSIerの方にぜひ使っていただきたいのがPaperTester、IE×Excel連携のテストツールになります。これはSIerに限ったものではなく、スクリーンショットがあることでエラー部分が分かったり、Excelベースなのでテスト仕様書が書きやすい(特に職人向け)といったメリットがあるのではないでしょうか。手作業っぽいスクリーンショット撮影を自動化テストに乗せる、優れたツールですね。

gremlins.js - Webアプリケーションでもモンキーテストを実現

画像

モンキーテストという言葉があります。例えばテストにおいて、ユーザ登録フローをやって欲しいと言われれば誰でもユーザ名を入力したり、パスワードを入れたりします。まったく関係ないところを100回クリックして問題がないか確認するなんてことはしない訳です。それを全く意に介せず行うのがモンキーテストです。意外なメモリーリークを探したり、普通やらないだろうといったバグを発見できる可能性があります。それをWebアプリケーションで実現するのがgremlins.jsです。

NightWatch - node製のSeleniumクライアント

Seleniumは多数のブラウザを操作してテストを自動化できます。RubyやJavaなど様々なプログラミング言語向けにソース出力が可能で、各言語で作られたシステムと組み合わせることができます。そんなSeleniumをnodeと組み合わせて使えるのがNightWatchです。書き方も使い方も柔軟で、これはテスト以外の用途でも活躍しそうです。

Serverspec - サーバ検証を自動化

画像

ユニットテストではSpecファイルにテスト内容を記述し、それが想定したレスポンスを返すかどうかでテストを行います。この基本はとてもシンプルで、プログラミング言語以外でも応用が効くでしょう。ということで作られたのがServerspecです。名前の通り、サーバが想定した通りに設定されているかどうかをテストするツールです。Rubyで記述できるのでプログラミングを組み合わせることで自在にテストができるでしょう。

Selenium VBA - 自動テストがExcelパワーで一気に便利に!

画像

Seleniumと言えばブラウザを擬似的に操作してテストを自動化したり、ちょっとしたスクレイピング系の操作をするのに便利なソフトウェアです。Google Chrome/Firefox/IE/PhantomJSなどに対応しており、マルチブラウザでテストができます。そんなSeleniumはRubyやPython、Java、C#といった言語向けにテストコードを出力できるのですが、さらにVBAでも使えるようにしたソフトウェアがSelenium VBAです。

Resurrectio - CasperJS向けのテストコードをWebブラウザ上で生成

画像

WebアプリケーションのUI上のテストをするというのは大変です。そこでよく使われるのが操作を記録し、再現することでテストコードの大枠を生成してしまうという方法です。Seleniumでもそういった手法がよく使われています。PhantomJSを使ったCasperJSというテストユーティリティがありますが、そのCasperJS向けのテストコードを生成してくれるのがResurrectoiです。ResurrectoiはGoogle Chrome機能拡張としてインストールしますので、テストコードの作成が手軽です。

HTTP負荷テストをしよう「Vegeta」

画像

VegetaはGo製のオープンソース・ソフトウェア(MIT License)です。HTTPの負荷テストツールは幾つかありますが、今回は最も新鋭と思われるVegetaを紹介します。コマンドラインで動作するのでインストールも簡単ですぐに使い始められます。アクセス先のURL指定はメソッドとURLを指定します。GETはもちろんPOSTやHEADアクセスによる負荷も計測可能です。レポートはテキストの他、SVGでの出力もできます。VegetaはGoで作られており、Goのプログラム中でライブラリとして呼び出して使うこともできます。

Facebook製。操作を記録しスクリーンショットを撮る「Huxley」

画像

HuxleyはPython製のオープンソース・ソフトウェア(Apache Licnese 2.0)です。Webサービスのテストをしていて面倒なのがエラーが起きた時の再現性です。そしてエラーウィンドウを閉じてしまったらもう二度と同じ表示ができないかも知れません。そこで使ってみたいのがHuxleyです。HuxleyはPython製のソフトウェアと、Seleniumを使ってテスト時のログとスクリーンショットを残してくれます。録画とプレイバックができるようになっています。Facebook製とあって、実用性高いソフトウェアなのではないでしょうか。

ランダムな操作でiOSアプリの自動テスト「CrashMonkey」

画像

CrashMonkeyはRuby製、iOS用のオープンソース・ソフトウェア(MIT License)です。iOSアプリはGUIを持ったアプリケーションであり、タップ、スワイプなど様々な操作があります。それらの正常系をテストするのはさほど難しくありませんが、異常系をテストするのはとても時間がかかります。そこで使ってみたいソフトウェアがCrashMonkeyです。後は見ているだけで勝手に様々な操作が行われます。その中で落ちればテストした意味があると言えるでしょう。

Seleniumを使ったiPhoneアプリの自動操作テストツール「Appium」

画像

AppiumはiOSのテストを自動化するSeleniumを使ったテストツールです。iOSのテストはユニットテストが基本と思われます。実際の操作については人が細かくテストを行っているのではないでしょうか。その面倒なUIテストを自動化してくれるのがAppiumです。AppiumはテストコードをJava/Ruby/PHP/node.js/Pythonで書くことができます。さらにSeleniumを使って開発されているのも特徴です。テストは分離しているため、既存のアプリに何らかのSDKを組み込んだりする必要はありません。近く、Androidもサポートされるそうです。

Facebook製。モバイルWebブラウザテスター「Ringmark」

画像

RingmarkはモバイルのWebブラウザテスターです。3つの輪が描かれたUIが特徴です。RingmarkはFacebookからリリースされたモバイルデバイスにおけるHTML5サポート状況チェックツールです。W3Cに寄贈されました。Ringmarkは3層の輪からなっており、内側ほど重要度の高い機能となっています。現時点で400種類のテストを行うようになっており、今後さらに増える予定とのことです。

継続的インテグレーションに。iOSを自動操作してテスト「KIF」

KIFはObjective-C製、Apache License 2.0のオープンソース・ソフトウェアです。Webのテストにおいてもユニットテストはもちろんのことながら実際に役立つのはSeleniumのような実際に操作してみてテストするタイプのソフトウェアではないでしょうか。単純に表示やデータの授受だけでなく、実際に入力したりクリックしてみて起こる問題も多いはずです。iOSについてもそれは同様です。特にWebと異なる画面遷移であるために辿って戻ってという操作を行うとおかしくなったり、メモリ解放のタイミングによって起こる問題もあります。そうした面倒と思える問題について、KIFをうまく使えば解決できるものは多そうです。

まとめ

アジャイルに限ったことではありませんが、テストを徹底的に行える環境を作れればプロジェクトはまずうまくいきます。テストが適切に行えない、時間がない状態にしてしまうと火を噴くのは必至です。またウォーターフォールなどでは最終行程にまわされてしまっているために、開発が延びるとテストの工数が必然的に削られてしまいます。テストファーストのやり方を取り入れることでテストの行程を最前にし、結果的に開発の工数も減らせるというのが理想ではないでしょうか。テストはシステムの品質を高めるのみならず、コードを最適化してシステムの寿命も延ばしてくれます。また、見やすいコードは手が加えやすく、拡張性も高くなります。プロジェクトの早い段階、まだ余裕のあるうちにテストを作りこむようにしてみてください。

PR_infeed

PR_Relative

オウンドメディア運営会社の皆様へ

s

ページトップ