-2

OK、C#には次のクラスがあります。

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass("Hello World");
        myClass.WriteToConsole();
    }
}

class MyClass
{
    private string MyProperty { get; set; }

    public MyClass(string textToEncapsulate)
    {
        MyProperty = textToEncapsulate;
    }

    public void WriteToConsole()
    {
        Console.WriteLine(MyProperty);
    }
}

3つの質問:

  1. ユニットテストとは何ですか?
  2. 上記の例では、単体テストは有益でしょうか?
  3. 上記の例の「ユニットテスト」についてはどうすればよいですか?

ありがとう

4

2 に答える 2

5

1.ユニットテストとは何ですか?

手動テストには時間がかかります。コードのすべての部分が期待どおりに機能していることを確認するために、毎回まったく同じ一連のテストを手動で実行するのは難しい場合があります。完全な製品を手作業でテストする場合、すべてのコードパスをテストすることも非常に困難です。

データベースが利用できない場合、コードの反応をどのようにテストしますか?または、誤ったデータが保存されている場合はどうなりますか?それが正しくなるにはかなりの時間がかかります。

単体テストとは、コードの可能な限り最小の部分のテストを開始することを意味します。そして、これを簡単に実行できるようにするために、プロセスを自動化します。これは、本番コードをテストするテストコードを作成することを意味します。

例えば:

int a = 3;
int b = 5;

Calculator c = new Calculator();
int sum = c.Sum(a, b);

Assert.AreEqual(8, sum);

このテストは、CalculatorクラスのSum関数が正しく機能していることを確認します。

ここで、電卓クラスの内部動作を最適化するとします。コードの変更と最適化を開始します。変更するたびに単体テストを実行し、すべてが成功すると、コードが壊れていないことがわかります。

本番環境で、ユーザーが電卓のバグレポートを送信するとします。最初のステップは、このバグを示す単体テストを作成することです。新しいテストが失敗した後(バグがまだ残っているため!)、バグを修正すると、単体テストが成功し、このバグが二度と戻ってこないことを確信できます。

この安全ハーネスは、単体テストの最大の利点の1つです。

2上記の例では、単体テストは有益でしょうか?3上記の例の「ユニットテスト」についてはどうすればよいですか?

ユニットテストは良い習慣です。コードが機能していることを証明するのに役立ちます。ただし、あなたの例では、コードをテストするのは難しいでしょう。

コンソールへの出力は、簡単にテストできるものではありません。ただし、Console.WriteLineの概念を抽象化すると、コードのテストが容易になります。

ユニットテストの作成は実際には非常に簡単です。問題は、実際にテストできるコードを書くことです。

コードのより適切なテスト可能なバージョンは次のとおりです。

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass(new ConsoleOutputService(), "Hello World");
        myClass.WriteToConsole();
    }
}

public interface IOutputService
{

    void WriteLine(string MyProperty);
}

public class ConsoleOutputService : IOutputService
{
    public void WriteLine(string MyProperty)
    {
        Console.WriteLine(MyProperty);
    }
}

class MyClass
{
    private IOutputService _outputService;
    private string MyProperty { get; set; }

    public MyClass(IOutputService outputService, string textToEncapsulate)
    {
        _outputService = outputService;
        MyProperty = textToEncapsulate;
    }

    public void WriteToConsole()
    {
        _outputService.WriteLine(MyProperty);

    }
}

コンソールへの直接の依存関係をインターフェースに置き換えました。このコードを単体テストするときは、IOutputServiceに偽物を提供して、結果を確認できます。

本当に良い本はxUnitTestPatternsです。単体テストを作成する際の一般的な落とし穴と、それらを回避/修正するためのパターンを示しています。

また、数か月前にテスト可能なコードについて自分でブログを書きました。それはやや高度ですが、おそらくあなたはそれから何かを得ることができます。ご不明な点がございましたら、お気軽にお問い合わせください。

于 2012-06-13T12:32:39.820 に答える
3

提案したクラスは、コンソール上で直接機能するため、それほどテスト可能ではありません。方法を変えると違うでしょうWriteToConsole(TextWriter out);。この場合、TextWriterをモックして、クラスが期待どおりにコンソールに出力することをアサーションすることができます。考え方は、テスト可能なコードを作成する場合、テスト容易性のために作業することでコードがより再利用可能になるため、より良いコードを作成するということです。あなたの場合、単体テストを行うのは少しばかげているように見えますが、単純な動作が機能することを証明するテストを行うと、あなたや他の人が行ったさらなる変更の場合に安全になり、あなたが定義した期待を副作用として変える可能性があります。クラスをテスト可能にするための追加パラメーターとして単純なTextWriterを使用することを提案したことに注意してください。クラスをテスト可能にするために最も簡単な努力をしなければならないというのが私の意見です。TextWriterはモック可能なので、テストの利点を実現します。コード全体を書き直さなくても、通常はそれで十分です。

于 2012-06-13T12:32:06.477 に答える