web-dev-qa-db-ja.com

目的がわからないコードのテストを書く

最近、ブラックボックスリファクタリングを完了しました。テスト方法がわからないので、チェックインできません。

高レベルで、私は初期化がいくつかのクラスBから値を取得することを含むクラスを持っています。クラスBが「空」の場合、それはいくつかの実用的なデフォルトを生成します。この部分を、クラスBを同じデフォルトに初期化するメソッドに抽出しました。

どちらのクラスの目的/コンテキスト、またはそれらがどのように使用されるかについてはまだ解明していません。そのため、空のクラスBからオブジェクトを初期化して、適切な値を持っているかどうか、正しいことを確認することはできません。

私の最良のアイデアは、元のコードを実行し、初期化されたメンバーに応じてパブリックメソッドの結果にハードコードし、それに対して新しいコードをテストすることです。私がこの考えに漠然と不快に思う理由をはっきりと述べることはできません。

ここにより良い攻撃はありますか?

59
user214290

あなたは元気です!

コンポーネントをリファクタリング可能にするためにできることの多くは、自動回帰テストを作成することです。驚くかもしれませんが、そのようなテストは、入出力の「インターフェース」(そのWordの一般的な意味)を理解している限り、コンポーネントが内部で行うことを完全に理解せずに書かれることがよくあります。これは、クラスだけでなく本格的なレガシーアプリケーションに対して過去に何度か行われ、完全に理解していないものを壊すことを回避するのに役立ちました。

ただし、十分なテストデータを用意し、そのコンポーネントのユーザーの観点からソフトウェアの動作をしっかりと理解しておく必要があります。そうしないと、重要なテストケースが省略されるリスクがあります。

自動テストを実装するのは私見です。リファクタリングを後で開始するのではなく開始するため、小さなステップでリファクタリングを実行し、各ステップを検証できます。リファクタリング自体により、コードが読みやすくなるため、内部について少しずつ理解を深めることができます。したがって、このプロセスの注文ステップは

  1. 「外部から」コードを理解し、
  2. 回帰テストを書く、
  3. コードの内部の理解を深めるリファクタリング
122
Doc Brown

単体テストを作成する重要な理由は、それらがコンポーネントAPIを何らかの形で文書化することです。ここでは、テスト中のコードの目的を理解しないことが本当に問題です。コードカバレッジはもう1つの重要な目標であり、どの実行ブランチが存在し、どのようにトリガーされるかを知らずに達成することは困難です。

ただし、状態をきれいにリセットできる(または毎回新しいテストオブジェクトを作成できる)場合は、「ランダムイントラッシュアウト」タイプのテストを作成して、ほとんどランダムな入力をシステムに送り、出力を観察するだけです。

このようなテストは、失敗した場合に、その理由と深刻さを述べるのが複雑になる可能性があるため、維持するのが困難です。報道は疑わしいかもしれません。しかし、彼らはまだ何もないよりはるかに優れています。そのようなテストが失敗した場合、開発者は最新の変更をより注意深く修正し、うまくいけばそこでバグを見つけることができます。

1
h22