タグ付けされた質問 「unit-testing」

ユニットテストは、ソースコードの個々のユニットをテストして、それらが使用に適しているかどうかを判断する方法です。

11
テスト目的でコードを厳密に変更するのは悪い習慣ですか?
私はプログラマーの同僚と、テスト可能なものにするためだけに作業中のコードを変更するのが良いか悪いかについて議論しています(例えば、単体テストを介して)。 私の意見では、オブジェクト指向とソフトウェアエンジニアリングの優れた実践を維持することの範囲内で(「すべてを公開する」などではなく)OKです。 私の同僚の意見は、テスト目的でのみコードを修正するのは間違っているというものです。 単純な例として、一部のコンポーネント(C#で記述された)で使用される次のコードを考えてください。 public void DoSomethingOnAllTypes() { var types = Assembly.GetExecutingAssembly().GetTypes(); foreach (var currentType in types) { // do something with this type (e.g: read it's attributes, process, etc). } } 私は、このコードを修正して、実際の作業を行う別のメソッドを呼び出すことを提案しました。 public void DoSomething(Assembly asm) { // not relying on Assembly.GetExecutingAssembly() anymore... } このメソッドは、作業するAssemblyオブジェクトを取り込んで、テストを実行するために独自のAssemblyを渡すことを可能にします。私の同僚は、これが良い習慣だとは思いませんでした。 良い一般的な慣行とは何ですか?

10
完全なリファクタリングの時間がないときに、レガシーコードのテストを書くことは理にかなっていますか?
私は通常、「Legacy Cod eで効果的に作業する」という本のアドバイスに従うようにしています。依存関係を壊し、コードの一部を@VisibleForTesting public staticメソッドと新しいクラスに移動して、コード(または少なくともその一部)をテスト可能にします。そして、新しい関数を変更または追加するときに何も壊さないことを確認するテストを作成します。 同僚は、私はこれをすべきではないと言っています。彼の推論: 元のコードはそもそも適切に動作しない可能性があります。また、開発者もテストを理解して変更する必要があるため、テストを作成すると将来の修正や変更が難しくなります。 何らかのロジック(〜12行、2〜3 if / elseブロックなど)を備えたGUIコードの場合、テストは簡単ではないので、テストを行う価値はありません。 同様の悪いパターンは、コードベースの他の部分にも存在する可能性があります(私はまだ見ていませんが、かなり新しいです)。1つの大きなリファクタリングですべてを簡単にクリーンアップできます。ロジックを抽出すると、この将来の可能性が損なわれる可能性があります。 完全なリファクタリングの時間がない場合、テスト可能な部分を抽出してテストを書くことを避けるべきですか?これに不利な点はありますか?

7
既存のコードのテストを書く
比較的大きなプログラム(C#で900k SLOCなど)があり、すべてが十分にコメント/文書化され、適切に組織化され、適切に機能しているとします。コードベース全体は、もはや会社にいない単一の上級開発者によって作成されました。すべてのコードはそのままテスト可能であり、IoCが全体で使用されます(ユニットテストを作成しなかった奇妙な理由を除く)。今、あなたの会社はコードを分岐させ、変更がコア機能を壊すときを検出するために単体テストを追加したいと考えています。 テストの追加は良いアイデアですか? もしそうなら、どのようにしてこのようなものから始めるのでしょうか? 編集 わかりました、それで私は反対の結論に対して良い議論をする答えを期待していませんでした。とにかく問題は私の手に負えないかもしれません。私も「重複した質問」を読みましたが、一般的なコンセンサスは「テストを書くのは良い」ということです...ええ、しかしこの特定のケースではあまり役に立ちません。 レガシーシステムのテストを書くことをここで考えているのは私だけではないと思います。どれだけの時間を費やし、新しいテストが問題をキャッチする回数(および、そうでない回数)のメトリックを保持します。私は戻って来て、私の結果でこれから1年かそこらを更新します。 結論 そのため、正統性に似た既存のコードに単体テストを追加することは基本的に不可能です。コードが動作すると、テストを赤信号/緑信号にすることは明らかにできません。通常、テストする必要がある動作が明確ではなく、どこから始めればよいか、完了したら明確ではありません。本当にこの質問をすることでさえ、そもそもテストを書くことの主要なポイントを見逃しています。ほとんどの場合、意図した機能を解読してユニットテストを遡及的に追加するよりも、TDDを使用してコードを書き直す方が実際に簡単であることがわかりました。問題を修正したり、新しい機能を追加したりするのは別の話であり、ユニットテストを追加するときだと思います(以下で指摘するように)。最終的には、ほとんどのコードが書き直され、多くの場合、予想よりも早くなります。

7
単体テストとテスト駆動開発の違い
説明を読むことで、TDDテストでは関数を記述する前に行われ、ユニットテストでは後に行われることを理解しています。 これが主な違いですか、それとも2つの用語を比較することすらできませんか。おそらく、ユニットテストはTDDに統合された部分です。

7
単体テストの代わりに受け入れテストと統合テストを使用するだけで十分ですか?
この質問の簡単な紹介。私は現在TDDと最近BDDを1年以上使用しています。私は、モックなどの手法を使用して、テストをより効率的に記述します。最近、私は自分のために小さなお金管理プログラムを書くための個人的なプロジェクトを始めました。レガシーコードがなかったため、TDDから始めるのに最適なプロジェクトでした。残念ながら、TDDの喜びはあまり経験しませんでした。それは私の楽しみを台無しにし、プロジェクトをあきらめました。 なにが問題だったの?さて、TDDのようなアプローチを使用して、テスト/要件がプログラムの設計を進化させました。問題は、テストの作成/リファクタリングに関して、開発時間の半分以上がかかっていたことです。したがって、リファクタリングして多くのテストに書き込む必要があるため、最終的にはこれ以上機能を実装したくありませんでした。 職場では、レガシーコードがたくさんあります。ここでは、統合テストと受け入れテストを増やし、単体テストを減らしていきます。ほとんどのバグは受け入れテストと統合テストによって検出されるため、これは悪いアプローチではないようです。 私の考えは、最終的には単体テストよりも多くの統合テストと受け入れテストを書くことができるということでした。バグを検出するために言ったように、単体テストは統合/受け入れテストよりも優れていません。単体テストも設計に適しています。私はそれらの多くを書いていたので、私のクラスは常にテストしやすいように設計されています。さらに、テスト/要件が設計をガイドできるようにするアプローチは、ほとんどの場合、より良い設計につながります。単体テストの最後の利点は、高速であることです。ユニットテストとほぼ同じ速度で実行できることを知るために、十分な統合テストを作成しました。 ウェブを調べた後、私の考えによく似たアイデアがあちこちであることがわかりました。この考えをどう思いますか? 編集 質問には、デザインは良かったが、次の要件のために大規模なリファクタリングが必要な例の1つに答えました。 最初は、特定のコマンドを実行するためのいくつかの要件がありました。拡張可能なコマンドパーサーを作成しました。これは、ある種のコマンドプロンプトからコマンドを解析し、モデル上で正しいものを呼び出しました。結果は、ビューモデルクラスで表されました。 ここには何も問題はありませんでした。すべてのクラスは互いに独立しており、新しいコマンドを簡単に追加し、新しいデータを表示できました。 次の要件は、すべてのコマンドに独自のビュー表現(コマンドの結果の何らかのプレビュー)が必要であることです。新しい要件に対してより良い設計を実現するために、プログラムを再設計しました。 これは、すべてのコマンドに独自のビューモデルがあり、したがって独自のプレビューがあるためです。 問題は、コマンドパーサーがコマンドのトークンベースの解析を使用するように変更され、コマンドを実行する機能が削除されたことです。すべてのコマンドには独自のビューモデルがあり、データビューモデルは、表示する必要があるデータを知っている現在のコマンドビューモデルのみを知っています。 この時点で私が知りたかったのは、新しいデザインが既存の要件を満たさなかった場合のみです。受け入れテストを変更する必要はありませんでした。ほぼすべての単体テストをリファクタリングまたは削除する必要がありましたが、これは膨大な作業の山でした。 ここで見せたかったのは、開発中によく発生する一般的な状況です。古いデザインでも新しいデザインでも問題はありませんでした。要件に応じて自然に変更されただけでした。私がどう理解したか、これはTDDの利点の1つであり、デザインが進化します。 結論 すべての答えと議論をありがとう。この議論の要約として、次のプロジェクトでテストするアプローチを考えました。 まず、いつものように何かを実装する前に、すべてのテストを作成します。 要件については、最初にプログラム全体をテストする受け入れテストをいくつか作成します。次に、要件を実装する必要があるコンポーネントの統合テストをいくつか作成します。この要件を実装するために別のコンポーネントと密接に連携するコンポーネントがある場合、両方のコンポーネントが一緒にテストされる統合テストも作成します。最後になりましたが、アルゴリズムまたは他のクラスを高い順列(シリアライザーなど)で記述する必要がある場合は、この特定のクラスの単体テストを記述します。他のすべてのクラスはテストされませんが、単体テストが行​​われます。 バグについては、プロセスを簡素化できます。通常、バグは1つまたは2つのコンポーネントによって引き起こされます。この場合、バグをテストするコンポーネントの統合テストを1つ作成します。アルゴリズムに関連する場合は、ユニットテストのみを記述します。バグが発生したコンポーネントを簡単に検出できない場合、受け入れテストを作成してバグを特定します。これは例外です。

10
すべてのメソッドをテストする必要がありますか?
それで今日、チームメイトとユニットテストについて話しました。全体が始まったのは、彼が「ねえ、そのクラスのテストはどこにありますか、1つしか見えないのですか?」クラス全体がマネージャー(または、そのように呼び出したい場合はサービス)であり、ほとんどすべてのメソッドが単にものをDAOに委任しているため、次のようになりました。 SomeClass getSomething(parameters) { return myDao.findSomethingBySomething(parameters); } ロジックを持たない種類のボイラープレート(または、少なくともロジックのような単純な委任を考慮していない)ですが、ほとんどの場合(レイヤー分離など)に便利なボイラープレートです。そして、ユニットテストを行うかどうかについてかなり長い議論がありました(DAOの完全なユニットテストを行ったことは言及する価値があると思います)。彼の主な議論は、TDDではないこと(明らかに)、誰かがこのメソッドが何をするかを確認するためにテストを見たいと思うかもしれない(それがどのようにもっと明白になる可能性があるのか​​わかりません)、または将来誰かが変更したいかもしれないということです実装し、それに新しい(または「より多く」のような)ロジックを追加します(この場合、誰かが単純にそのロジックをテストする必要があると思います)。 しかし、これは私に考えさせられました。最高のテストカバレッジ%を目指して努力する必要がありますか?それとも、それは単に芸術のための芸術ですか?私は、次のようなテストの背後にある理由をまったく見ていません。 ゲッターとセッター(実際に何らかのロジックがある場合を除く) 「定型」コード 明らかに、このようなメソッド(モックを使用)のテストには1分もかかりませんが、それでも時間の無駄であり、CIごとに1ミリ秒長くなると思います。 コードのすべての(または彼ができる限り)行をテストする必要がある理由について、合理的/「可燃性でない」理由はありますか?

9
「良い」単体テストを書く方法は?
このスレッドをきっかけに、私は(再び)プロジェクトでユニットテストを最終的に使用することを考えています。そこのいくつかのポスターは、「テストは良いテストだとすれば、テストはクールだ」と言っています。私の今の質問:「良い」テストとは何ですか? 私のアプリケーションでは、主な部分は多くの場合、大量の観測データに応じた何らかの数値解析であり、このデータをモデル化するために使用できるフィット関数になります。可能な入力と結果の数が多すぎてすべてのケースをテストすることができないため、これらのメソッドのテストを構築することは特に困難であることがわかりました。この種の方法の「良い」テストに特に興味があります。

7
コードカバレッジは未使用のメソッドを強調しています-どうすればよいですか?
私は、既存のJavaプロジェクトのコードカバレッジを増やすように依頼されました。 コードカバレッジツール(EclEmma)が、どこからも呼び出されないメソッドを強調していることに気付きました。 私の最初の反応は、これらのメソッドの単体テストを書くことではなく、ラインマネージャー/チームにそれらを強調し、これらの機能がそもそもなぜあるのかを尋ねることです。 最善のアプローチは何でしょうか?それらの単体テストを作成するか、それらがなぜ存在するのか疑問に思いますか?

5
スタブとすべてを公開する単体テストのポイントはありますか?
「適切な」方法でユニットテストを行う場合、つまり、すべてのパブリックコールをスタブ化し、プリセット値またはモックを返す場合、実際には何もテストしていないように感じます。文字通り、コードを見て、パブリックメソッドを通るロジックのフローに基づいて例を作成しています。そして、実装が変更されるたびに、それらのテストを行って変更する必要があります。これは、(中期でも長期でも)何か有用なことを達成しているとは感じません。また、統合テスト(非幸福なパスを含む)も行いますが、テスト時間が長くなることはあまり気にしません。それらで、私は実際に回帰をテストしているように感じます。なぜなら、それらは複数をキャッチしたからです。一方、ユニットテストは、パブリックメソッドの実装が変更されたことを示しています。 単体テストは広大なトピックであり、私はここで何かを理解していないと感じています。単体テストと統合テストの決定的な利点は何ですか(時間のオーバーヘッドを除く)。

11
数値が意味をなさない場合、単体テストでマジックナンバーを使用できますか?
単体テストでは、コードに任意の値をスローして、その機能を確認することがよくあります。たとえば、foo(1, 2, 3)17を返すことになっていることがわかっている場合、次のように記述できます。 assertEqual(foo(1, 2, 3), 17) これらの数値は純粋に任意であり、より広い意味を持ちません(たとえば、境界条件ではありませんが、これらについてもテストします)。私はこれらの数字の良い名前を思い付くのに苦労するだろうし、そのような何かを書くことconst int TWO = 2;は明らかに役に立たない。このようなテストを書いても大丈夫ですか?それとも定数に数値を含める必要がありますか? されているすべてのマジックナンバーは同じを作成しましたか?、文脈から意味が明らかな場合、マジックナンバーはOKであることがわかりましたが、この場合、実際にはナンバーはまったく意味を持ちません。

9
リファクタリングする前に単体テストを書く方法は?
「リファクタリング時にユニットテストをどのように機能させ続けるのですか?」などの同様の行に沿って質問に対するいくつかの回答を読みました。私の場合、私たちが持っているいくつかの標準をレビューし、それに合わせるプロジェクトを与えられたという点で、シナリオはわずかに異なります。現在、プロジェクトのテストはまったくありません! サービスレイヤーにDAOタイプのコードを混在させないなど、改善できたと思われる多くのことを特定しました。 リファクタリングする前に、既存のコードのテストを書くことは良い考えのように思えました。私に見える問題は、リファクタリングを行うと、特定のロジックが実行される場所を変更しているため、これらのテストが壊れ、テストが以前の構造を念頭に置いて書かれていることです(依存関係のモックなど) 私の場合、手続きを進める最善の方法は何でしょうか?私はリファクタリングされたコードの周りにテストを書きたいと思っていますが、望みの振る舞いを変える可能性のあるものを間違ってリファクタリングするリスクがあることを知っています。 これがリファクタリングであろうとリデザインであろうと、これらの用語の修正を理解できてうれしいです。現在、次のリファクタリングの定義に取り組んでいます。「リファクタリングでは、定義により、ソフトウェアの動作は変更されません方法を変えることができます。」だから、私はソフトウェアが何をするかを変えていません。 同様に、再設計と考えられるメソッドのシグネチャを変更する場合の議論を見ることができます。 簡単な例を示します MyDocumentService.java (現在) public class MyDocumentService { ... public List<Document> findAllDocuments() { DataResultSet rs = documentDAO.findAllDocuments(); List<Document> documents = new ArrayList<>(); for(DataObject do: rs.getRows()) { //get row data create new document add it to //documents list } return documents; } } MyDocumentService.java (何でもリファクタリング/再設計) public …

7
ユニットテストには依存性注入が不可欠ですか?
単体テストに依存性注入(DI)の使用は不可欠ですか? テストできるようにコードを分離する別の方法は考えられません。また、私が今まで見たすべての例では、このパターンを使用しています。それは唯一の実行可能なオプションであるか、または他の選択肢があるからでしょうか?

16
TDDを行うときにすべてのテストを一度に書いてみませんか?
TDDの赤-緑-リファクタリングサイクルは十分に確立され、受け入れられています。失敗した単体テストを1つ作成し、できるだけ単純に合格させます。クラスに対して失敗する多数の単体テストを記述し、それらすべてを一度に合格させることに対するこのアプローチの利点は何ですか。 テストスイートは、リファクタリング段階で誤ったコードを記述したり、ミスを犯したりすることからあなたを保護します。クラス(またはモジュール)のすべてのテストを「ブレインダンプ」の形式として最初に記述して、予想されるすべての動作を一度に書き留めることが簡単な場合があります。

5
テスト可能なコードを促進する設計原則とは何ですか?(テスト可能なコードの設計とテストによる設計の推進)
私が取り組んでいるプロジェクトのほとんどは、開発と単体テストを分離して考えているため、後のインスタンスで単体テストを書くのは悪夢です。私の目的は、高レベルおよび低レベルの設計フェーズ自体の間にテストを念頭に置くことです。 テスト可能なコードを促進する明確に定義された設計原則があるかどうかを知りたい。私が最近理解するようになったそのような原則の1つは、依存性注入と制御の反転による依存性反転です。 SOLIDとして知られているものがあることを読みました。SOLIDの原則に従うと間接的に簡単にテストできるコードになるかどうかを理解したいですか?そうでない場合、テスト可能なコードを促進する明確に定義された設計原則はありますか? テスト駆動開発と呼ばれるものがあることを認識しています。ただし、テストを通じて設計を推進するよりも、設計段階でテストを念頭に置いてコードを設計することにもっと興味があります。これが理にかなっていることを願っています。 このトピックに関連するもう1つの質問は、既存の製品/プロジェクトをリファクタリングし、各モジュールのユニットテストケースを作成できるようにするためにコードとデザインを変更してもよいかどうかです。

4
TDD-アウトサイドインとインサイドアウト
アプリケーションをOutside Inで構築することとTDDを使用してInside Outで構築することの違いは何ですか? これらはTDDとユニットテストについて読んだ本です: テスト駆動開発:例による テスト駆動開発:実用ガイド:実用ガイドMicrosoftでの 高品質PHPフレームワークとアプリケーションの開発のための実世界ソリューション NET xUnitテストパターン:テストコード のリファクタリングユニットテストの技術:.Net Growing Object-Oriented Softwareでの例、テストによるガイド ---> JAVAは私の主要言語ではないため、これを理解するのは非常に困難でした:) それらのほぼすべてがTDDの基本と単体テストを一般的に説明しましたが、アプリケーションを構築するさまざまな方法についてはほとんど言及しませんでした。 もう1つ気づいたのは、これらの書籍のほとんど(すべてではないにしても)が、アプリケーションの作成時に設計段階を無視していることです。彼らは、テストケースを迅速に記述し、設計を単独で出現させることに重点を置いています。 しかし、私は人々がTDDにアプローチする方法を議論したxUnitテストパターンのパラグラフに出会いました。Outside InとInside Outの 2つの学校があります。 悲しいことに、この本はこの点について詳しく説明していません。これら2つのケースの主な違いは何かを知りたいです。 それらのそれぞれをいつ使用する必要がありますか? 握りやすいTDD初心者には? 各方法の欠点は何ですか? このトピックを具体的に説明している資料はありますか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.