『Effective Unit Testing』読書ノート8信憑わがままcode smell

2450 ワード

信頼できるわがまま(Trustworthiness)をどう理解しますか?人を使って比較することができて、1人の信頼できる人は必ず実行して、1人の信頼できない人の言うことは数え切れないで、約束することはできません.テストもそうです.この章では、信頼できるわがままに影響を与えるcode smellを紹介します.
  • 注釈されたテストは簡単で、注釈されたテスト全体よりもこのコードを直接削除したほうがいい.バージョン管理ツールがあります.削除されたコードが見つからない心配はありません.
  • 誤導人の注釈誤導人の注釈は、注釈がないよりも恐ろしい.もう一つ言えば、良い方法名と変数名を通じて、通常はできるだけ注釈を書かないことができます.必ず注釈を書くなら、注釈はwhyを説明するのではなくwhatを説明するべきだ.例えば、私たちは醜いループを書いて、私たちはこのループが何をしているのかを説明する必要はありません.これは良い方法名をつけて達成できる機能ですが、注釈を書いて、このように書かなければならない理由(例えば、より良い性能のために)を書くことができます.
  • は、通常、テストのassertがある条件分岐にしか存在しないため、失敗しないテストという状況が発生した.特に注意しなければならないのは、assertをcatch文に書いたことです.次の例を参照してください.
  •  @Test
    public void includeForMissingResourceFails() {
      try {
        new Environment().include("somethingthatdoesnotexist");
      } catch (IOException e) {
        assertThat(e.getMessage(), contains("somethingthatdoesnotexist"));
      }
    }
    

    この方法はexceptionを投げなければ、テストも同じように合格できますが、これは私たちが望んでいる結果ではありません.テストに合格したのは、条件が満たされていない場合にこのテストを失敗させることを忘れたからです.改善方法は簡単で、fail()を加えます.
     @Test
    public void includeForMissingResourceFails() {
      try {
        new Environment().include("somethingthatdoesnotexist");
        fail();  //
      } catch (IOException e) {
        assertThat(e.getMessage(), contains("somethingthatdoesnotexist"));
      }
    }
    
  • 浅い承諾(shallow promises)これは、テストが実際にその名前を検証していないと主張している内容を指す.
  • 低減の期待(lowered expectations)これは画素レベルの正確な反面であり、所望のassertの論理をざっと判断しただけであり、例えば、ある方法の戻り値が空ではないことを検証するだけで、実際の内容を見ないのではないか.テストが粗雑すぎると、failのはずがfailではないことになります.どのように正確さと粗さの中で度を把握するかは芸術である.
  • プラットフォームの偏見この問題は、正しいユーザーディレクトリを返すなど、異なるプラットフォームで異なる動作を示す必要があるコード機能をテストすることに現れています.興味深いことに、この問題を解決する正しい方法は、コードをテストすることではなく、機能的なコードを設計する際にプラットフォームという概念を抽象化し、テストがある機械の実際のプラットフォームに依存してはならない.
  • 条件化試験(conditional tests)assertがある条件分岐に現れる.これにより、テストがこの条件に間に合わなければ、テストは合格することができます.例:
  • @Test
    public void multipleArgumentsAreSentToShell() throws Exception {
      File dir = createTempDirWithChild("hello.txt");
      String[] cmd = new String[] { "ls", "-1", dir.getAbsolutePath() };
      Process process = new Process(cmd).runAndWait();
      if (process.exitCode() == 0) {
        assertEquals("hello.txt", process.output().trim());
      }
    }
    

    解決の大きな原則は,すべての条件分岐が走り,すべての分岐がfailをテストする可能性があることである.実際には、コードに条件付きブランチが現れるのではなく、ブランチごとに個別のテスト方法を確立する必要があります.
    code smellの紹介は可読性、メンテナンス性、信頼性のわがままの3つの文章で終わり、次の章では私が興味を持っている内容を紹介します:テスト可能な設計、testable design.