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です。単体テストを作成する際の一般的な落とし穴と、それらを回避/修正するためのパターンを示しています。
また、数か月前にテスト可能なコードについて自分でブログを書きました。それはやや高度ですが、おそらくあなたはそれから何かを得ることができます。ご不明な点がございましたら、お気軽にお問い合わせください。