web-dev-qa-db-ja.com

単体テストを作成するときに、何をテストするかをどのように知っていますか?

C#を使用して、ユーザー名、パスワード、アクティブフラグ、名、姓、フルネームなどを持つUserというクラスが必要です。

ユーザーに認証および保存のメソッドが必要です。メソッドのテストを書くだけですか?また、プロパティは.Netのゲッターおよびセッターなので、プロパティのテストについて心配する必要もありますか?

127
Mike Roosa

これに対する多くの優れた回答も私の質問にあります: " Beginning TDD-Challenges?Solutions?Recommendations?

ブログ投稿 (これは私の質問に部分的に触発された)もご覧になることをお勧めします。すなわち:

どこから始めたらいいのかわからない?

  • 新たに始めましょう。新しいコードを作成する場合にのみ、テストの作成を検討してください。これは、古いコードの再作業、または完全に新しい機能です。
  • シンプルに始めましょう。駆け出し、頭をテストフレームワークに回そうとするだけでなく、TDD風にならないでください。 Debug.Assertは正常に機能します。出発点として使用します。プロジェクトを混乱させたり、依存関係を作成したりすることはありません。
  • ポジティブに始めましょう。あなたはあなたの工芸を改善しようとしている、それについて気分が良い。私は、停滞して喜んで、自分自身を改善するために新しいことをしようとしない多くの開発者を見てきました。あなたは正しいことをしている、これを覚えていてください、そして、それはあなたがfromめるのを止めるのを助けるでしょう。
  • チャレンジの準備を始めましょう。テストに入るのは非常に困難です。課題を期待しますが、覚えておいてください-課題を克服することができます。

期待するものだけをテストする

私が最初に始めたとき、私は常に発生する可能性のあるすべての問題を把握しようとしてそこに座っていたので、実際の問題がありました。これは頭​​痛への迅速な方法です。テストは実際のYAGNIプロセスでなければなりません。問題があることがわかっている場合は、そのテストを作成してください。そうでなければ、気にしないでください。

1つだけをテストする

各テストケースでテストできるのは1つだけです。テストケース名に「and」を使用していることに気付いた場合、何か間違ったことをしていることになります。

これが「ゲッターとセッター」から先に進むことができることを意味します:)

130
Rob Cooper

言語ではなくコードをテストします。

次のような単体テスト:

Integer i = new Integer(7);
assert (i.instanceOf(integer));

コンパイラを記述していて、instanceofメソッドが機能しない可能性がゼロでない場合にのみ役立ちます。

強制的に言語に依存できるものをテストしないでください。あなたの場合、私はあなたの認証メソッドと保存メソッドに焦点を合わせます-そして、それらのフィールドのいずれかまたはすべてのnull値を適切に処理できることを確認するテストを書きます。

63
Tim Howland

これによりユニットテストが開始され、とても嬉しくなりました

ユニットテストを開始しました。長い間、それを始めるのは良いことだと思っていましたが、どのように始めるべきか、さらに重要なこととして何をテストするべきか分かりませんでした。

次に、会計プログラムの重要なコードを書き直す必要がありました。この部分は非常に複雑で、多くの異なるシナリオが含まれていました。私が話している部分は、すでに会計システムに入力された販売および/または購入請求書を支払う方法です。

さまざまな支払いオプションがあったため、コーディングを開始する方法を知りませんでした。請求書は100ドルですが、顧客は99ドルしか送金しませんでした。顧客に販売請求書を送ったかもしれませんが、その顧客からも購入しました。彼を300ドルで売りましたが、100ドルで買いました。顧客は、残高を決済するために200ドルを支払うことを期待できます。また、500ドルで販売したが、顧客が250ドルしか支払わなかった場合はどうなりますか?

そのため、あるシナリオは完全に機能するが、他の種類の請求書/支払いの組み合わせでは間違っているという多くの可能性を解決するために、非常に複雑な問題がありました。

これがユニットテストが助けになった場所です

私は(テストコード内で)販売と購入の両方のために請求書のリストを作成するメソッドを書き始めました。次に、実際の支払いを作成する2つ目の方法を作成しました。通常、ユーザーはユーザーインターフェイスからその情報を入力します。

次に、最初のTestMethodを作成し、支払い割引なしで1つの請求書の非常に簡単な支払いをテストしました。銀行支払いがデータベースに保存されると、システム内のすべてのアクションが発生します。ご覧のとおり、請求書を作成し、支払い(銀行取引)を作成し、取引をディスクに保存しました。私の主張では、銀行取引とリンクされた請求書に最終的に正しい番号を入力する必要があります。取引後に支払い回数、支払い金額、割引額、請求書の残高を確認します。

テストが実行された後、データベースにアクセスして、期待したものが存在するかどうかを再確認しました。

テストを作成し、支払い方法(BankHeaderクラスの一部)のコーディングを開始しました。コーディングでは、最初のテストに合格するためのコードだけを気にしました。他のより複雑なシナリオについてはまだ考えていません。

最初のテストを実行し、テストに合格するまで小さなバグを修正しました。

次に、2回目のテストの作成を開始しました。今回は支払い割引を使用します。テストを作成した後、割引をサポートするために支払い方法を変更しました。

支払い割引を使用して正確性をテストする一方で、単純な支払いもテストしました。もちろん、両方のテストに合格する必要があります。

それから、私はより複雑なシナリオに向かって進みました。

1)新しいシナリオを考える

2)そのシナリオのテストを書く

3)その単一のテストを実行して、合格するかどうかを確認します

4)成功しなかった場合、パスするまでコードをデバッグおよび変更します。

5)コードを変更しながら、すべてのテストを実行し続けました

これにより、非常に複雑な支払い方法を作成できました。単体テストなしでは、コーディングを開始する方法がわかりませんでしたが、問題は圧倒的でした。テストでは、単純な方法から始めて、より単純なシナリオが引き続き機能することを保証しながら、段階的に拡張することができました。

ユニットテストを使用することで、数日(または数週間)のコーディングが節約され、メソッドの正確性が多少保証されると確信しています。

後で新しいシナリオを考える場合、テストにそれを追加して、動作するかどうかを確認できます。そうでない場合は、コードを変更できますが、他のシナリオがまだ正しく機能していることを確認してください。これにより、メンテナンスとバグ修正の段階で何日も節約できます。

はい、テストされたコードでも、ユーザーが思いもしなかったことをしたり、実行を妨げたりした場合、バグが残る可能性があります

以下は、支払い方法をテストするために作成したテストの一部です。

public class TestPayments
{
    InvoiceDiaryHeader invoiceHeader = null;
    InvoiceDiaryDetail invoiceDetail = null;
    BankCashDiaryHeader bankHeader = null;
    BankCashDiaryDetail bankDetail = null;



    public InvoiceDiaryHeader CreateSales(string amountIncVat, bool sales, int invoiceNumber, string date)
    {
        ......
        ......
    }

    public BankCashDiaryHeader CreateMultiplePayments(IList<InvoiceDiaryHeader> invoices, int headerNumber, decimal amount, decimal discount)
    {
       ......
       ......
       ......
    }


    [TestMethod]
    public void TestSingleSalesPaymentNoDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 1, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 1, 119.00M, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(119M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(0M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSingleSalesPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 2, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 2, 118.00M, 1M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(1M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    [ExpectedException(typeof(ApplicationException))]
    public void TestDuplicateInvoiceNumber()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("100", true, 2, "01-09-2008"));
        list.Add(CreateSales("200", true, 2, "01-09-2008"));

        bankHeader = CreateMultiplePayments(list, 3, 300, 0);
        bankHeader.Save();
        Assert.Fail("expected an ApplicationException");
    }

    [TestMethod]
    public void TestMultipleSalesPaymentWithPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 11, "01-09-2008"));
        list.Add(CreateSales("400", true, 12, "02-09-2008"));
        list.Add(CreateSales("600", true, 13, "03-09-2008"));
        list.Add(CreateSales("25,40", true, 14, "04-09-2008"));

        bankHeader = CreateMultiplePayments(list, 5, 1144.00M, 0.40M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(4, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118.60M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(400, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(600, bankHeader.BankCashDetails[0].Payments[2].PaymentAmount);
        Assert.AreEqual(25.40M, bankHeader.BankCashDetails[0].Payments[3].PaymentAmount);

        Assert.AreEqual(0.40M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].PaymentDiscount);

        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSettlement()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("300", true, 43, "01-09-2008")); //Sales
        list.Add(CreateSales("100", false, 6453, "02-09-2008")); //Purchase

        bankHeader = CreateMultiplePayments(list, 22, 200, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(2, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(300, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(-100, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
    }
38
eroijen

それらが本当に些細なものであれば、テストを気にしないでください。たとえば、これらがこのように実装されている場合。

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
}

一方、巧妙な操作(ゲッター/セッターでのパスワードの暗号化と復号化など)を行っている場合は、テストを行います。

13
Steve Cooper

ルールは、作成するすべてのロジックをテストする必要があるということです。ゲッターとセッターに特定の機能を実装した場合、テストする価値があると思います。一部のプライベートフィールドにのみ値を割り当てる場合は、気にしないでください。

10
Slavo

この質問は、どのメソッドがテストされ、どのメソッドがテストされないかについて、どこで線を引くのかという質問のようです。

価値の割り当てのセッターとゲッターは、一貫性と将来の成長を念頭に置いて作成されており、将来的にはセッター/ゲッターがより複雑な操作に進化する可能性があると予測しています。一貫性と将来の成長のためにも、これらのメソッドの単体テストを実施することは理にかなっています。

コードの信頼性は、特に機能を追加するために変更を受けている間は、主な目標です。テスト方法論にセッター/ゲッターを含めることでクビになる人はいませんが、最後に気づいた、または思い出せるメソッドが単純なセット/取得ラッパーであることをテストしたい人がいることは確かですが、そうではありませんでした長いケース。

チームの別のメンバーがset/getメソッドを拡張して、テストする必要があるがテストを作成しなかったロジックを含めるようにしたかもしれません。しかし、今、あなたのコードはこれらのメソッドを呼び出しており、それらが変更され、詳細なテストが必要であることを知らず、開発とQAで行うテストは欠陥を引き起こしませんが、リリース初日の実際のビジネスデータはそうしますそれをトリガーします。

2人のチームメイトは、失敗する可能性があるがユニットテストでカバーされていないロジックを含むようにセット/ゲットがモーフィングしたときに、ボールをドロップしてユニットテストに失敗した人について議論します。元々セット/取得を書いたチームメイトは、簡単なセット/取得の初日からテストが実装されていれば、このクリーンから抜け出すのが簡単になります。

私の意見では、些細なものでさえ、単体テストですべてのメソッドをカバーする「無駄な」時間の数分は、道中の頭痛の種とお金の損失/ビジネスの評判と誰かの仕事の損失を節約するかもしれません。

そして、あなたがユニットテストで些細なメソッドをラップしたという事実は、彼らが些細なメソッドを非自明なメソッドに変更し、テストを更新するようにそれらを促すときに、ジュニアチームメイトによって見られるかもしれません。生産に到達することから。

私たちがコーディングする方法と、コードから分かる規律は、他の人を助けることができます。

6
Thomas Carlisle

別の正解。これは、私が信じている、ロン・ジェフリーズから:

動作させるコードのみをテストします。

4
user9397

ゲッターやセッターなど、プライベートフィールドを設定するよりも特別な動作のない、本当に些細なコードは、テストするのはやりすぎです。 3.0では、C#には構文フィールドがあり、コンパイラがプライベートフィールドを処理するため、プログラムする必要はありません。

私は通常、クラスに期待する動作を確認する非常に簡単なテストをたくさん書いています。たとえ2つの数字を追加するような単純なものであっても。単純なテストの作成とコードのいくつかの行の作成を頻繁に切り替えます。その理由は、私が考えていないことを壊すことを恐れずにコードを変更できるからです。

3
Mendelt

すべてをテストする必要があります。現在、ゲッターとセッターがありますが、いつかそれらを多少変更するかもしれません。おそらく検証などを行うためです。今日書いたテストは明日、すべてが正常に機能し続けることを確認するために使用されます。テストを書くとき、「今は些細なことです」などの考慮事項を忘れてください。アジャイルまたはテスト駆動のコンテキストでは、将来のリファクタリングを想定してテストする必要があります。また、極端に長い文字列やその他の「悪い」コンテンツなど、本当に奇妙な値を入力しようとしましたか?まああなたは...あなたのコードが将来どれほどひどく悪用される可能性があると思い込まないでください。

一般に、広範なユーザーテストを作成することは、一方の面で大変です。一方で、アプリケーションの動作方法に関する貴重な洞察を常に提供し、簡単な(そして誤った)仮定を捨てるのに役立ちます(たとえば、ユーザー名の長さは常に1000文字未満です)。

3
Sklivvz

ツールキットまたはオープンソースタイプのプロジェクトで終わる可能性のある単純なモジュールの場合は、些細なゲッターとセッターを含めて可能な限りテストする必要があります。特定のモジュールを作成するときに単体テストを生成することは、非常に簡単で簡単です。ゲッターとセッターの追加は最小限のコードであり、あまり考えずに処理できます。ただし、コードがより大きなシステムに配置されると、この余分な努力により、基本クラスの型の変更など、基礎となるシステムの変更から保護できます。完全な回帰を行うには、すべてをテストすることが最善の方法です。

3
Dirigible

定型コードのテストは時間の無駄ですが、Slavoが言うように、ゲッター/セッターに副作用を追加する場合は、その機能に付随するテストを作成する必要があります。

テスト駆動開発を行う場合は、最初にコントラクト(インターフェイスなど)を作成し、次にテストを作成して、期待される結果/動作を文書化するインターフェイスを実行する必要があります。 Then単体テストのコードに触れることなく、メソッド自体を記述します。最後に、コードカバレッジツールを入手し、テストがコード内のすべてのロジックパスを実行することを確認します。

3
warren_s

一般に、メソッドが特定の値に対してのみ定義されている場合、許容範囲の境界およびoverの値をテストします。言い換えれば、メソッドが行うべきことを実行することを確認してください、それ以上何もしない。これは重要です。失敗するときは、早く失敗したいからです。

継承階層では、必ず [〜#〜] lsp [〜#〜] コンプライアンスをテストしてください。

デフォルトのゲッターとセッターをテストすることは、後で何らかの検証を行う予定がない限り、私にとってはあまり有用ではないようです。

2
Rik

壊れる可能性があると思われる場合は、テストを作成してください。私は通常、セッター/ゲッターをテストしませんが、姓と名を連結するUser.Nameの1つを作成すると言います。彼はテストされたものを変更しました。

2
pmlarocque

標準的な答えは、「壊れる可能性のあるものをすべてテストする」ことです。プロパティが壊れないことが確実な場合は、テストしないでください。

そして、何かが壊れていることが判明したら(バグを見つけたら)、明らかにそれをテストする必要があることを意味します。バグを再現するテストを作成し、失敗するのを確認してから、バグを修正し、テストの合格を確認します。

2
Eric Normand

ゲッターとセッターのユニットテストを作成しても問題はありません。今のところ、彼らは内部でフィールドの取得/設定を行っているだけかもしれませんが、将来的には検証ロジック、またはテストする必要があるプロパティ間の依存関係があるかもしれません。あなたがそれについて考えている間に今それを書くのは簡単で、その時が来たらそれを改造することを覚えています。

2
Bob King

理想的には、クラスを書いているときに単体テストを行ったはずです。これは、テスト駆動開発を使用する際の目的です。各機能ポイントを実装するときにテストを追加し、エッジケースもテストでカバーするようにします。

後でテストを書くのはずっと苦痛ですが、実行可能です。

あなたの立場で私がすることは次のとおりです。

  1. コア機能をテストする基本的なテストセットを作成します。
  2. NCoverを入手して、テストで実行します。この時点で、テストカバレッジはおそらく約50%になります。
  3. 約80%〜90%のカバレッジが得られるまで、エッジケースをカバーするテストを追加し続けます

これにより、回帰に対する優れたバッファーとして機能する単体テストの素晴らしいワーキングセットが得られます。

このアプローチの唯一の問題は、この方法でテスト可能にするために、コードがdesignedでなければならないことです。早い段階でカップリングを間違えた場合、簡単に高いカバレッジを得ることができなくなります。

これが、コードを書く前にテストを書くことが本当に重要な理由です。疎結合のコードを書くことを強制します。

1
Simon Johnson

それは私たちのコードを改善します...期間!

ソフトウェア開発者がテスト駆動開発を行うときに忘れてしまうことの1つは、アクションの背後にある目的です。量産コードが既に配置された後に単体テストが作成されている場合、テストの値は大幅に低下します(ただし、完全に失われるわけではありません)。

単体テストの真の精神では、これらのテストはnotであり、主にコードをさらに「テスト」するためのものです。または、コードカバレッジを90%〜100%向上させます。これらはすべて、最初にテストを書くことのフリンジメリットです。大きな見返りは、TDDの自然なプロセスにより、生産コードの記述がはるかに改善されることです。

この考えをよりよく伝えるために、以下を読むと役立つ場合があります。

ユニットテストの欠陥理論
目的のあるソフトウェア開発

書くこと単体テストが高品質の製品を得るのに役立つと感じる場合、 貨物カルト テスト駆動開発の。

1
Scott Saad

明らかに動作する(定型的な)コードをテストしないでください。したがって、セッターとゲッターが単に「propertyvalue = value」と「return propertyvalue」である場合、テストする意味はありません。

1
erlando

Get/setでさえ、実装方法によっては奇妙な結果になる可能性があるため、メソッドとして扱う必要があります。

これらの各テストでは、プロパティのパラメータセットを指定し、許容されるプロパティと許容されないプロパティの両方を定義して、呼び出しが期待どおりに返されるか失敗することを確認する必要があります。

また、SQLインジェクションの例として、セキュリティの落とし穴を認識し、これらをテストする必要があります。

そのため、プロパティのテストについて心配する必要はありません。

1
CestLaGalere

ゲッターとセッターが単純な操作のみを行う場合にテストするのはばかげていると思います。個人的には、使用パターンをカバーするための複雑な単体テストを書いていません。通常の実行動作と、考えられる限り多くのエラーケースを処理したことを確認するのに十分なテストを記述しようとしています。バグレポートへの応答として、さらに単体テストを作成します。ユニットテストを使用して、コードが要件を満たしていることを確認し、将来の変更を容易にします。何かを壊すとテストが失敗することがわかっているので、コードを変更したいと思っています。

1
Andrei Savu

コードのテストが必要な場所を正しく推測することは可能ですが、この推測をバックアップするにはメトリックスが必要だと一般的に考えています。私の見解では、ユニットテストはコードカバレッジメトリックと連動しています。

多くのテストを含むコードですが、カバレッジが小さい場合は十分にテストされていません。とはいえ、100%のカバレッジを備えているが、境界とエラーのケースをテストしていないコードも素晴らしいものではありません。

高カバレッジ(最小90%)と可変入力データのバランスが必要です。

「ガベージイン」のテストを忘れないでください。

また、単体テストは、失敗をチェックしない限り単体テストではありません。アサートを持たない、または既知の例外でマークされている単体テストは、実行時にコードが停止しないことをテストするだけです!

常に失敗または予期しない/望ましくないデータを報告するようにテストを設計する必要があります!

1
Ray Hayes

GUIインターフェイスの外部でテスト可能なコードを記述しているすべてのテストを作成します。

通常、別の層またはビジネスロジック層内に配置するビジネスロジックを持つ、私が作成するロジック。

その後、何かをするためのテストを書くのは簡単です。

最初のパスでは、「ビジネスロジックレイヤー」で各パブリックメソッドの単体テストを記述します。

このようなクラスがあった場合:

   public class AccountService
    {
        public void DebitAccount(int accountNumber, double amount)
        {

        }

        public void CreditAccount(int accountNumber, double amount)
        {

        }

        public void CloseAccount(int accountNumber)
        {

        }
    }

これらのアクションを実行することを知っているコードを記述する前に最初に行うことは、単体テストの記述を開始することです。

   [TestFixture]
    public class AccountServiceTests
    {
        [Test]
        public void DebitAccountTest()
        {

        }

        [Test]
        public void CreditAccountTest()
        {

        }

        [Test]
        public void CloseAccountTest()
        {

        }
    }

テストを書いて、何かをするために書いたコードを検証します。物事のコレクションを繰り返し処理し、それぞれについて何かを変更する場合は、同じことを実行するテストと実際に発生したアサートを記述します。

Behavoir Driven Development(BDD)という他のアプローチもありますが、それはより複雑であり、ユニットテストのスキルから始めるのに最適な場所ではありません。

したがって、話の教訓は、あなたが心配するかもしれないことを何でもテストして、サイズが小さい特定のものをテストする単体テストを続け、多くのテストが良いことです。

テストを簡単に記述できるように、ビジネスロジックをユーザーインターフェイスレイヤーの外側に置いてください。

TestDriven.Net または ReSharper をお勧めします。どちらもVisual Studioに簡単に統合できます。

1
Dean Poulin

アジャイル開発のコンテキストで単体テストを理解しているので、マイク、はい、ゲッターとセッターをテストする必要があります(公開されていると仮定して)。ユニットテストの全体的な概念は、ソフトウェアユニットをテストすることです。この場合、クラスは ブラックボックス としてテストされます。ゲッターとセッターは外部から見えるため、認証と保存とともにテストする必要があります。

1

AuthenticateメソッドとSaveメソッドがプロパティを使用する場合、テストはプロパティに間接的に触れます。プロパティがデータへのアクセスを提供するだけである限り、明示的なテストは必要ありません(100%のカバレッジが必要な場合を除く)。

1
Tom Walker

ゲッターとセッターをテストします。誰がコードを書いているかによって、ゲッター/セッターメソッドの意味を変える人もいます。 getterメソッドの一部として、変数の初期化やその他の検証を見てきました。この種のことをテストするには、そのコードを明示的にカバーする単体テストが必要です。

1
Peter Bernier

個人的には、「壊れる可能性のあるものをすべてテストします」が、単純なゲッター(またはより良い自動プロパティ)は壊れません。単純なreturnステートメントが失敗することは一度もなかったので、それらのテストはありませんでした。ゲッターに計算または他の形式のステートメントが含まれている場合、それらのテストを確実に追加します。

個人的には、モックオブジェクトフレームワークとして Moq を使用し、オブジェクトが周囲のオブジェクトを本来の方法で呼び出すことを確認します。

1
tronda

クラスのすべてのメソッドの実行をUTでカバーし、メソッドの戻り値を確認する必要があります。これにはゲッターとセッターが含まれます。特にメンバー(プロパティ)が複雑なクラスである場合、初期化中の大容量メモリ割り当て。たとえば、非常に大きな文字列(またはギリシャ語記号のある文字列)を使用してセッターを呼び出し、結果が正しいことを確認します(切り捨てられていない、エンコードが良好など)

適用される単純な整数の場合-整数の代わりにlongを渡すとどうなりますか?それがUT for :)と書く理由です

1
m_pGladiator

クラスのテストでは、次のことを確認する必要があります。

  1. メソッドとプロパティが期待値を返す
  2. 無効な引数が指定されると、適切な例外がスローされます
  3. 特定のメソッドが呼び出されたときに、クラスと他のオブジェクト間の相互作用が期待どおりに発生する

もちろん、ゲッターとセッターに特別なロジックがない場合は、AuthenticateおよびSaveメソッドのテストでそれらをカバーする必要がありますが、そうでない場合は明示的なテストを記述する必要があります

1
Crippledsmurf

AuthenticateメソッドとSaveメソッドに対して複数のテストを作成することをお勧めします。成功事例(すべてのパラメーターが提供され、すべてのスペルが正しいなど)に加えて、さまざまな失敗事例(パラメーターの誤りまたは欠落、該当する場合は利用できないデータベース接続など)のテストを行うことをお勧めします。参照として NUnitを使用したC#での実用的な単体テスト をお勧めします。

他の人が述べたように、ゲッターとセッターの条件付きロジックがない限り、ゲッターとセッターの単体テストは過剰です。

1
Scott Lawrence

プロパティの実際の設定はテストしません。消費者がこれらのプロパティをどのように設定するか、およびそれらがどのように設定されるかについて、私はもっと懸念します。テストでは、リスクとテストの時間/コストを比較検討する必要があります。

1
Bloodhound

可能な限り単体テストを使用して、「すべての重要なコードブロック」をテストする必要があります。

プロパティが些細で、誰かがバグを導入する可能性が低い場合、ユニットテストを行わない方が安全です。

Authenticate()およびSave()メソッドは、テストに適した候補のように見えます。

1
user7015

価値のないコードを書くことは常に悪い考えです。提案されたテストはプロジェクトに価値を追加しません(またはプロジェクトに非常に近いため)。次に、貴重な時間を無駄にして、実際に価値をもたらすコードの作成に費やすことができます。

0
pjesi

2番目のおそらく壊れる可能性のあるものをすべてテストする愚かなテストを書かない。しかし、最も重要な教義はあなたが見つけたものが壊れていることをテストする:何らかのメソッドが動作する場合、テストが失敗するデータセットの概要を説明するテストを記述し、バグを修正してバーが緑色になるのを監視します。また、「境界」データ値(null、0、MAX_INT、空のリストなど)をテストします。

0
Manrico Corazzi

単体テスト、または実際に任意のテストを作成する場合、テスト対象の境界条件を調べることにより、テスト対象を決定します。たとえば、is_primeという関数があります。幸いなことに、その名前が意味することを行い、整数オブジェクトが素数であるかどうかを示します。このため、オブジェクトを使用していると想定しています。次に、既知の範囲の素数および非素数オブジェクトに対して有効な結果が発生したことを確認する必要があります。それがあなたの出発点です。

基本的に、関数、メソッド、プログラム、またはスクリプトで何が起こるべきかを見てから、その同じコードで間違いなくnot起こるべきことを見てください。これがテストの基礎です。コードで)shouldがどうなるかについての知識が増えたら、テストを修正する準備をしてください。

0
Dan

私が見た最高の経験則は、一目ではわからないことをすべてテストすることです。確かに、正しく動作するでしょう。それ以上なら、言語/環境をテストすることになります。

0
user74754