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

そのシステムの予想される動作に対するソフトウェアシステムの動作の確認。

10
ユニットテストアプリケーションロジックと不信な言語構成要素の境界線はどこですか?
次のような関数を考えてみましょう。 function savePeople(dataStore, people) { people.forEach(person => dataStore.savePerson(person)); } 次のように使用できます。 myDataStore = new Store('some connection string', 'password'); myPeople = ['Joe', 'Maggie', 'John']; savePeople(myDataStore, myPeople); 独自の単体テストがあるか、ベンダーが提供していると仮定しましょうStore。いずれにせよ、私たちは信頼していStoreます。さらに、エラー処理(たとえば、データベースの切断エラーなど)はの責任ではないと仮定しましょうsavePeople。実際、ストア自体が魔法のようなデータベースであり、何らかのエラーが発生する可能性はないと仮定しましょう。 これらの仮定を考えると、問題は次のとおりです。 savePeople()単体テストする必要がありますか、それとも組み込みのforEach言語構成のテストに相当しますか? もちろん、モックdataStoreを渡し、dataStore.savePerson()各人に1回呼び出されることをアサートすることもできます。このようなテストは実装の変更に対するセキュリティを提供するという議論を確かに行うことができます。たとえば、forEach従来のforループや他の反復方法に置き換えることを決めた場合です。そのため、テストは完全に簡単ではありません。そしてそれでもひどく近いようです... より実りの多い別の例を次に示します。他のオブジェクトや機能を調整する以外の何もしない機能を考えてください。例えば: function bakeCookies(dough, pan, oven) { panWithRawCookies = pan.add(dough); oven.addPan(panWithRawCookies); oven.bakeCookies(); oven.removePan(); } このような機能は、どのようにユニットテストされるべきでしょうか?私は単純にモックていないユニットテストのいずれかの種類を想像するのは難しいdough、panとovenして、メソッドがそれらに呼ばれていると主張します。しかし、そのようなテストは、関数の正確な実装を複製する以上のことはしていません。 意味のあるブラックボックスの方法で関数をテストできないことは、関数自体の設計上の欠陥を示していますか?もしそうなら、どのように改善できますか? bakeCookies例の動機となる質問をさらに明確にするために、より現実的なシナリオを追加します。これは、テストを追加してレガシーコードをリファクタリングしようとしたときに遭遇したシナリオです。 ユーザーが新しいアカウントを作成するとき、いくつかのことを行う必要があります:1)新しいユーザーレコードをデータベースに作成する必要がある2)ウェルカムメールを送信する必要がある3)ユーザーのIPアドレスを詐欺のために記録する必要がある目的。 そこで、すべての「新規ユーザー」ステップを結び付けるメソッドを作成します。 function createNewUser(validatedUserData, emailService, dataStore) …

6
単体テストの実行順序を強制するのは悪い習慣ですか?
複数のサブモジュールで構成されるプロジェクトのテストを書いています。作成した各テストケースは互いに独立して実行され、テスト間ですべてのデータをクリアします。 テストは独立して実行されますが、場合によっては複数のサブモジュールが必要になるため、実行順序の強制を検討しています。たとえば、サブモジュールがデータを生成し、別のサブモジュールがデータに対してクエリを実行しています。データを生成するサブモジュールにエラーが含まれている場合、サブモジュール自体が正常に機能していても、クエリサブモジュールのテストも失敗します。 私がテストしている主な機能は、最初のサブモジュールからのみデータを取得するブラックボックスリモートサーバーへの接続であるため、ダミーデータを操作することはできません。 この場合、テストの実行順序を強制してもいいですか、それとも悪い習慣ですか?このセットアップには臭いがあるように感じますが、より良い方法は見つかりません。 編集:質問は、1つのテストが別のテストのセットアップである場合のテストの構成方法からですか?「前の」テストはセットアップではなく、セットアップを実行するコードをテストするためです。

27
開発者に自分の作業をテストさせる/させない理由
製品が生産される前の最後のステップとして開発者が自分の作品をテストできるようにするのは悪い考えである理由についていくつかの議論を集めたいと思います。 、ほとんどの人が他のことで忙しすぎて、プログラムのその部分に別の人を慣れさせる時間がないという議論は要約されました-それは非常に専門的なソフトウェアです)。 この場合のテスト計画はありますが(常にではありませんが)、テストされた変更を行わなかった人が実際に最終テストを行うことを非常に支持しています。ですから、次回議論する際に持ち出せる議論の良いしっかりしたリストを提供していただけないかとお願いしています。または、特にテストする正式なテストケースがある場合にこれが完全に問題ないと考える場合に、反論を提供するために。

8
広範囲にモックせずにユニットテストをどのように正確に記述する必要がありますか?
私が理解しているように、ユニットテストのポイントは、コードのユニットを単独でテストすることです。この意味は: コードベースの他の場所にある無関係なコードの変更によって壊れてはなりません。 統合テスト(ヒープで破損する可能性がある)とは対照的に、テストされたユニットのバグによって破損するユニットテストは1つだけです。 これはすべて、テストされたユニットのすべての外部依存関係をモックアウトする必要があることを意味します。そして、ネットワーク、ファイルシステム、データベースなどの「外部レイヤー」だけでなく、すべての外部依存関係を意味します。 これは、事実上すべての単体テストがモックする必要があるという論理的な結論につながります。一方、モックに関するGoogleの簡単な検索では、「モッキングはコードのにおい」であると主張する記事が数多くあり、ほとんど(完全にではありませんが)回避する必要があります。 さて、質問へ。 ユニットテストはどのように適切に書かれるべきですか? それらと統合テストの間の境界線は正確にどこにありますか? アップデート1 次の擬似コードを検討してください。 class Person { constructor(calculator) {} calculate(a, b) { const sum = this.calculator.add(a, b); // do some other stuff with the `sum` } } 依存関係Person.calculateをモックせずにメソッドをテストするテストCalculator(Calculator「外の世界」にアクセスしない軽量クラスであることを考えると)は、単体テストと見なすことができますか?

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を渡すことを可能にします。私の同僚は、これが良い習慣だとは思いませんでした。 良い一般的な慣行とは何ですか?

9
ソフトウェアのテスト中に、ユーザーがソフトウェアに対してこのような愚かなアクションを実行しないと想定できますか?
例:Webアプリケーションでフォームの機能テストを実行しているときに、異なる種類のランダムな入力値を入力してフィールドをテストします。 一般に、Webアプリケーションのユーザーとして、フィールドにランダムな値を実際に入力することはありません。 このような問題が本番環境で発生する可能性がはるかに低い場合、バグにつながる可能性のある/そうでない可能性のあるすべてのテストケースを組み込むことの使用は何ですか? 注:上記の例はサンプルケースにすぎません。このような問題は、あらゆる種類の機能/モジュールで発生する可能性があります。 この質問は、標準的な慣行が続くかどうか、または製品、ドメイン、その他すべての要因に完全に依存するかどうかを知るためだけに行っています。

17
診断して修正する前にすべての欠陥を再現することを主張するのは合理的ですか?
私はソフトウェア製品会社で働いています。当社の製品を実装する大企業のお客様がおり、サポートを提供しています。たとえば、不具合がある場合は、パッチなどを提供します。つまり、かなり典型的なセットアップです。 最近、製品のクラスター化された実装での同時データベースアクセスに関係するログファイルでお客様が発見した例外に関してチケットが発行され、私に割り当てられました。したがって、このバグの発生には、この顧客固有の構成が重要になる可能性があります。顧客から得たのは、ログファイルだけです。 私がチームに提案したアプローチは、顧客と同様の構成設定でバグを再現し、同等のログを取得することでした。ただし、バグを再現する必要はありません。過度に時間がかかり、VM上のサーバークラスターをシミュレートする必要があるため、彼らは私のアプローチに同意しません。私のチームは、単純に「コードをたどって」スレッドおよび/またはトランザクションに対して安全でないコードがどこにあるかを確認し、単純なローカル開発で動作する変更を行うことを提案します。バグの起源。 私にとっては、目に見える形の顕在化(実行時の再現)ではなく、抽象的な設計図(プログラムコード)で作業するのは難しいようです。そのため、一般的な質問をしたいと思いました。 すべての欠陥を再現し、それを診断および修正する前にデバッグすることを主張するのは合理的ですか? または: 私が上級開発者であれば、アプリケーションを実行したり、さまざまなユースケースシナリオを実際にテストしたり、ステップスルーしたりするのではなく、マルチスレッドコードを読んで、すべてのユースケースシナリオでそれが何をするかについての心構図を作成できるはずです行ごとにコード?または、私はそのような作業環境を要求するのに貧弱な開発者ですか? sissisのデバッグはありますか? 私の意見では、インシデントチケットに対応して提出された修正は、可能な限り元の環境に近くなるようにシミュレートされた環境でテストする必要があります。それが本当に問題を解決することを他にどのように知ることができますか?それは、エアバッグが実際に機能することを実証するためにダミーで衝突試験することなく、車両の新しいモデルをリリースするようなものです。 最後になりますが、私に同意する場合: 私のアプローチが合理的で、保守的で、より防弾であることをチームに納得させるために、チームとどのように話し合うべきですか?

16
TDDが役に立たなかったときに、コードの論理的な間違いを避ける方法は?
私は最近、イベントがどれくらい古いかを人間に優しい方法で示す小さなコードを書いていました。たとえば、イベントが「3週間前」または「1か月前」または「昨日」に発生したことを示すことができます。 要件は比較的明確であり、これはテスト駆動開発に最適なケースでした。テストを1つずつ作成し、各テストに合格するコードを実装しましたが、すべてが完全に機能するように見えました。本番でバグが現れるまで。 関連するコードは次のとおりです。 now = datetime.datetime.utcnow() today = now.date() if event_date.date() == today: return "Today" yesterday = today - datetime.timedelta(1) if event_date.date() == yesterday: return "Yesterday" delta = (now - event_date).days if delta < 7: return _number_to_text(delta) + " days ago" if delta < 30: weeks = math.floor(delta / 7) …

11
パスカバレッジはすべてのバグの発見を保証しますか?
プログラムを通るすべてのパスがテストされる場合、それはすべてのバグを見つけることを保証しますか? そうでない場合は、なぜですか?プログラムフローのあらゆる可能な組み合わせを通過し、問題が存在する場合はそれを見つけられないのはどうしてですか。 「すべてのバグ」が見つかる可能性があることをお勧めしますが、おそらくパスカバレッジが実用的ではないため(組み合わせであるため)、これまで経験したことがないためでしょうか。 注:この記事では、私が考えているカバレッジタイプの概要を簡単に説明します。

19
コンパイラはどうしてそんなに信頼できるのでしょうか?
コンパイラは、その正確性が与えられているかのように日常的に使用しますが、コンパイラもプログラムであり、潜在的にバグを含む可能性があります。私はいつもこの絶対的な堅牢性について疑問に思っていました。コンパイラ自体のバグに遭遇したことはありますか?コンパイラ自体に問題があることをどのように認識しましたか? ...そして、どのようにしてコンパイラを非常に信頼できるものにしますか?

7
テスト容易性を設計する際に静的ユーティリティクラスを処理する方法
TDDを使用して開発されたほとんどの部分で、テスト可能なシステムを設計しようとしています。現在、次の問題を解決しようとしています。 さまざまな場所で、ImageIOやURLEncoder(標準Java APIの両方)などの静的ヘルパーメソッド、および大部分が静的メソッド(Apache Commonsライブラリなど)で構成されるその他のさまざまなライブラリを使用する必要があります。しかし、このような静的ヘルパークラスを使用するメソッドをテストすることは非常に困難です。 この問題を解決するためのアイデアがいくつかあります。 静的クラス(PowerMockなど)をモックできるモックフレームワークを使用します。これは最も簡単な解決策かもしれませんが、どういうわけかあきらめたように感じます。 これらのすべての静的ユーティリティの周りにインスタンス化可能なラッパークラスを作成して、それらを使用するクラスに注入できるようにします。これは比較的クリーンなソリューションのように聞こえますが、これらのラッパークラスを大量に作成することになると思います。 これらの静的ヘルパークラスへのすべての呼び出しをオーバーライド可能な関数に抽出し、実際にテストするクラスのサブクラスをテストします。 しかし、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
開発者もテスターとして行動する必要がありますか?[閉まっている]
私たちは3人の開発者、1人のデザイナー、スクラムマスター、およびプロダクトオーナーのスクラムチームです。ただし、チームには公式のテスターはいません。私たちに常にある問題は、アプリケーションをテストし、それらのテストに合格してバグを削除することが、PBI(製品バックログアイテム)が完了したと見なす基準の1つとして定義されていることです。 しかし問題は、アプリケーション(実装された3人の開発者と1人の設計者)がどれだけアプリケーションをテストしようとしても、いくつかのバグが見られず、利害関係者へのプレゼンテーション(マーフィーの法則)を台無しにすることです。 改善策として、新しいテスターを雇うことをお勧めします。仕事をしている人はテストであり、テストのみです。公式のプロテスター。 ただし、問題は、スクラムマスターと利害関係者が開発者(または設計者)もテスターである必要があると考えていることです。 彼らは正しいですか?開発者(デザイナーも)もテスターに​​すべきですか?
60 testing  scrum 

2
目的がわからないコードのテストを書く
私は最近、ブラックボックスのリファクタリングを完了しました。テストする方法がわからないので、チェックインできません。 高レベルでは、クラスBから値を取得する初期化を含むクラスがあります。クラスBが「空」の場合、適切なデフォルトが生成されます。クラスBを同じデフォルトに初期化するメソッドにこの部分を抽出しました。 どちらのクラスの目的/コンテキスト、またはそれらがどのように使用されるかについてはまだ解明していません。そのため、空のクラスBからオブジェクトを初期化することはできませんし、正しい値を持っている/正しいことを行っていることを確認してください。 私の最善のアイデアは、元のコードを実行し、初期化されたメンバーに応じてパブリックメソッドの結果をハードコードし、それに対して新しいコードをテストすることです。この考えに漠然と不快感を覚える理由を明確に述べることはできません。 ここにはより良い攻撃がありますか?

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