BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース よいユニットテストを書くには

よいユニットテストを書くには

ブックマーク

原文(投稿日:2017/01/19)へのリンク

テストを小さくする。適切なツールを使う。プログラマとテストがペアになる。これらは、よいユニットテストを書くための、Adrian Bolboaca氏からの提案だ。 ユニットテストは、プログラミングとテストが混ざり合ったものだ。プログラマは、テスタと共に作業することで、お互いに学び合い、視野を広げることができる。

Adrian Bolboaca氏は、Mozaic Worksの組織と技術に関するコーチであり、ヨーロッパテストカンファレンス 2017において、様々なタイプの自動テストについて話す予定だ。 InfoQは、このカンファレンスについて、Q&A、要約、記事で扱う。

[ヨーロッパテストカンファレンス]は、専門家や実践者が一緒に話し、学び、テスト技術を実践するところです。 私たちは、テストをもっと効果的にするために、先進的な新しい方法を詳しく調べ、より強いコミュニティに成長する基本的な方法を十分に理解するようにします。

自動テストの目的というブログの中で、Bolboaca氏は、ユニットテストがすべきことを定義している。

ユニットテストは、1つのメソッドかクラスに注目します。 ユニットテストは、とても小さいもので、多くても数行のコードにすべきです。 ユニットテストを書いている時に、間違えはいくらでも起こり得るので、これは取るに足りないことではありません。 ユニットテストは小さいので、メモリで実行すべきであり、数ミリ秒で動かなければなりません。 外部依存(データベース、ウェブサービス、ファイルシステム、I/O)のあるテストは、ユニットテストではなく、別のもの(結合テスト、総合的なテスト、受け入れテスト、エンドツーエンドテスト等)です。

InfoQは、よいユニットテストを書くことと、ユニットテストを自動化することについて、Bolboaca氏にインタビューした。

InfoQ: 誰がユニットテストを書くか、開発者か、テスタか、は重要ですか?

Adrian Bolboaca氏: ユニットテストは、技術的なものであり、コーディングの詳細や、プログラム言語の特定のコンセプトにさえ注目することがあります。 ユニットテストは、Javaのような静的プログラミング言語や、Rubyのような動的プログラミング言語とは異なって見えます。 そのため、ユニットテストに対して、主に責任があるのは、プログラマであるべきです。

一方、テスタは、テスト計画の作成方法や、同値分割や境界値分析のような特定の分析によって、テストの興味深い値を割り出す方法をよりよく知っています。 そのため、プログラマは、テスタからこのような知識を"盗む"必要があります。または、ペアになって、一緒にテストを書くこともできますが、実装するのはプログラマです。

私の経験では、ペアになるのが最良の選択肢です。テストとプログラマはお互いよりよく学び、視野を広げられます。

InfoQ: いつユニットテストをすべきですか?

Bolboaca氏: チームは、製品コードが書かれた後で、ユニットテストを書くことができます。 これをテストアフターと呼びます。 しかし、テストアフターでは、テストできるように書くことを考慮して、製品コードを書かなければならないため、難しいことがあります。 このアプローチを選んだ場合、私たちは、製品コードをコードレビューのプロセスに通して、確実にテストできるようにする必要があります。 そうした場合のみ、私たちはプログラマとテスタのペアでテストを作成し続けられます。

また、テストファーストアプローチもあり、仲間から多くのテストの知識を盗むプログラマにはこちらを薦めます。 このアプローチを使う場合、私たちは、まず問題を分析し、1つのユニットテストを書きます。それから、そのテストのために最も簡単な実装コードを書き、それから、1つのユニットテスト、その実装、というように続きます。 チームがこのレベルに達すると、ユニットテストを書いているプログラマは、半分テスタだと言えるでしょう。テストファーストは、多くのテストの知識を必要としますから。 この場合、テスタは、最後にユニットテストをレビューし、受け入れテストを書くことに集中します。

Gil Zilberfeld氏は、インタビューのテストファーストアプローチで、テストファーストアプローチがもたらす利益について語っている。

テストファーストは、何が動くべきかを定義します。 テスト形式で定義があるので、特定の問題を解決するために、どのようなコードを書く必要があるのかを定義します。 テストを実行するだけで、動く機能があるかどうかを簡単に知ることができます。

このようにすれば、ずっと多くのカバレッジを得られます。テストを最後まで残しておくよりも、非常に優れた開発作業になります。

さらに、これらのテストを書いて、シナリオを特定している時に、いろいろな疑問が出てくるので、問題のある場所をより多く見つけられます。 テストアフターでは、そのような議論は全く起きないこともあります。開発者は、解決に必要なことよりも、自分が考えたことをコードにします。

Eli Lopian氏は、QA部門が消えた日という記事で、ユニットテストがQAを潰す可能生があることを説明した。

ユニットテストは、特定のコードが適切に動作し、ソフトウェアのパズルに、正確に取り込まれていることを確認するためのテスト手法です。 ユニットテストでコードの90%を適切にチェックできることが示されています。QAの手動テストツールとは違い、正確にビルドし、自動的にテストするユニットテストは、コードをリアルタイムでテストしながら、コードベースを進化させられます。

InfoQ: ユニットテストでどのように自動化しますか?

Bolboaca氏: ユニットテストは、テスト計画に従い、分析するプロセスであり、テスト計画は自動化できます。

これらのテストを自動化するために、いくつか覚えておくと役に立つことがあります。

  1. テストの名前にドメイン言語を使う
    私たちはテストを書いて、それでおしまいにすることがよくあります。 しかし、コードは、書かれるよりも、読まれることの方が多いのです。 だから、同僚や、未来の自分に優しくするために、テストの名前を明確にしましょう。
    技術的な名前ではなく、ドメインから名前を使いましょう。 "ExceptionOnOverflow" や "TestThree" 、"CustomerTest" のようなテストの名前は、明確ではありません。 代わりに、"WhenTooManyPlayersAreAddedAnErrorIsReturned"、 "ACustomerNeedsAllFieldsValidated"、"ValidCustomerCanBeUsedByOrder"、 "InvalidCustomerIsRejectedByOrder"のような、分かりやすい名前を書くべきです。 このようにすれば、ビジネスドメインを知っているすべての人たちが、そこで何をテストしているのか分かるでしょう。 あなたの顧客でさえも。
  2. テストを短くする
    ユニットテストは、1つの目的を持つ、短くて明確なものです。 最良のテストは、3、4行のコードで、そのコードを読む人は誰でも、すぐに分かるようになっています。
    私たちは、このような数多くの小さいユニットテストが必要です。これらのテストは、製品免疫システムのように、各テストが免疫細胞のように一緒に動きます。 不具合が現れれば、1つの小さなテストが、どこに問題があるのか正確に教えてくれるはずです。 このようにすれば、素早いフィードバックと、簡単な開発とテストサイクルを持てます。
  3. 1つのテストに1つのアサート
    1つのテストに2つ以上のアサートがある場合、2つ以上のことをテストしていることになります。 この場合、テストの名前は奇妙で不明確になります。テストは長すぎて、フィードバックははっきりしません。どのアサートが成功して、どのアサートが失敗したのか、決して知ることはできません。
    順番に3つのアサートがあるとしましょう。 最初のアサートが失敗すると、残りの2つは確認されません。 製品コードを変更した時、残りの2つのアサートは動作を保証してくれません。 この場合、セイフティネットと回帰テストの幻を見たにすぎません。
  4. つながっていないテスト
    テストをつなげる習慣をよく見かけます。 それは、大抵、計画した部分を設定するのが、とても難しいからです。 しかし、これは解決策ではありません。 つながりの中で、他のテストに依存したテストは、そのつながりのトップにあるテストのために、よく失敗します。 この場合、テストが通るようにコードを変えるかもしれませんが、テストが未対応のために、検証されていない欠陥を持ち込むかもしれません。
    免疫システムの免疫細胞のように、テストは、いつもお互いに独立していなければなりません。 テストは、製品には依存しますが、お互いには依存しません。
  5. 適切なツールを使う
    テストフレームワーク、モックフレームワーク、テストランナ、性能テストツール、セキュリティテストツール等、様々なツールがあります。 仕事に対して、適切なツールを使うようにしましょう。 自分が知っているというだけで、そのツールを使わないようにしましょう。 xUnitフレームワークは、大抵、どのタイプの自動化にでも合いますが、性能とセキュリティは専門的なフレームワークを使います。 実行可能な仕様になるように、よいテストを書けば、xUnitも使えますが、自分の人生を簡単にするために、BDDフレームワークを使いたいかもしれません。
    テストフレームワークを選ぶことは、中長期的に決められるべき決定であることを、覚えておいてください。 学習の費用だけでなく、使い方の費用や維持費についても考えましょう。

現在の市場では、ますます速く機能を提供する必要があるので、製品の検証プロセスを賢く検証して、自動化する必要があります。 これが、今日では、自動化が重要である理由です。

InfoQ: よいユニットテストを書くための秘訣は?

Bolboaca氏: ユニットテストは、産業製品から来ていますが、大抵の人たちはそのことを忘れています。 産業では、私たちは小さな部品をそれぞれテストする必要があります。その部品が基準通りの品質であれば、部品を組み立てるために、次の段階でその部品を使えます。 ソフトウェアでは、私たちは、ユニットが何かという明確な定義は持っていません。メソッド、クラス、モジュール等の様々な意見があります。 最初に難しいのは、何がユニットかをすべてのチームメンバで一緒に決めることです。それに応じて、テストを書きます。 私にとって、ユニットはとても小さく、エンジンの中のネジか、家具の釘の大きさです。 だから、私の秘訣は、ユニットが何かを定義して、テストレビューフェーズの間、その決まりを守ることに集中することです。

ユニットテストは、プログラミングとテストが混じり合ったものです。 プログラマは、シンプルで速い、メンテナンスしやすいテストを書くために、数多くのテストコンセプトを知る必要があります。 私がプログラマに勧めるのは、同値分割、境界値分析、テストカバレッジ、ポジティブテスト、ネガティブテストのような、いくつかの必要不可欠なコンセプトについて、同僚のテスタから学ぶことです。

ユニットテストに関して、もう1つ、よく忘れるのは分析についてです。 私たちは、考えずに、直ちにテストを書き始めることはありません。 問題を分析し、可能ならば、分割し、それから、書かなければならないユニットテストは何かを考えます。 ここでアドバイスしたいのは、常にシステムのアウトプットから始めることです。そして、そのアウトプットを生成する、起こりうるインプットを明らかにします。 そのことを私に教えてくれたChris Matts氏に感謝します。

ユニットテストを書いている時に、その問題のドメインから言葉を使うべきです。 テストは、その機能が製品に存在する理由を表すべきです。 ビジネスドメインを知っていて、プログラミングを知らない人が、テストを読めるようにすべきです。 アナリストとペアになることは、その方向で、とても役に立ちます。

Rate this Article

Relevance
Style

この記事に星をつける

おすすめ度
スタイル

BT