Meiryo’s blog

やってみて詰まったことを備忘録として残すブログ

【C#】xUnitをインストールして単体テストを行ってみた話

いままでテストは手動で毎回データを入れて
確認をしていたのですが
これはかなり非効率だと感じたため
テストツールを使ったテストを
学ぶことにしました。
この記事はその備忘録です。

使うテストツールにxUnitを選んだ理由

調べてみたらテストツールは
xUnit、NUnit、MSTest・・・と
数種類あることがわかりました。

どれにしようか迷いましたが

  • Qiitaの記事でxUnitとnUnitが人気そうだとわかる
  • いくつかの記事で「なんとなくMSはxUnitを推してそう」
    という推測を見る
  • Xamarinを試そうかなと思っていたところに
    「Xamarinと動くよ」って
    MSのテストの概要ページに書いてあった

これらからxUnitを使うことに決めました。

xUnitのインストール作業

この記事を見て入れていきました。

コードスニペットマーケットプレイスから
インストールできるようになったっぽいです。

拡張機能から「xUnitCodeSnippets」を検索すれば
入れることができます。

テスト環境構築

xUnitのサイトを見に行き
環境を整え・・・
ようと思いましたが
テスト用のプロジェクトで
動作確認する程度のことしか書いていません。

「既存のプロジェクトを
テスト用のプロジェクトでテストする」
ということがしたいので
別のサイトも参考にして進めます。

テスト用プロジェクトの作成

テスト用のプロジェクトを作成します。
どのフレームワークを使っているかで
テンプレートが変わるようです。
今回は.NETCoreを選びました。

既存のプロジェクトの追加

テスト用のプロジェクトが作成されたので
次にこのプロジェクトとテストしたい
既存のプロジェクトを紐付けます。  

そのためにまず既存のプロジェクトを追加します。
(この作業はこちらを参考にしました。)

追加→既存のプロジェクトを選択し
追加したいプロジェクトのcsprojファイルを
選択します。

テスト用プロジェクトに既存プロジェクトを参照させる

追加→プロジェクト参照の追加
で先程追加した既存のプロジェクトを選択します。

テストするコード

先日行われたAtCoderのA問題
解いたものを使おうと思います。

解いた結果が下記になります。
このCalcメソッドをテストしていきます。

namespace Test
{
    using System;
    using System.Collections.Generic;

    public class Test
    {
        public static void Main(string[] args)
        {
            var t = new Test();
            var input = Console.ReadLine().Split(' ');
            var x = int.Parse(input[0]);
            var y = int.Parse(input[1]);
            var z = int.Parse(input[2]);
            Console.WriteLine(t.Calc(x,y,z));
        }

        public int Calc(int x, int y, int z)
        {
            return ((y * z) - 1) / x;
        }
    }
}

テストをやってみようと思ったがドキュメントが無い

先程記載したxUnitのサイト
見ながらいろいろためそうと
思っていたのですが
よく見たらドキュメントが全然無い・・・。
(Githubのissueで論争起きとる)

同じ問題を抱えている人を
Twitterで探したところ、
なんとドキュメントを作成している方を
見つけました。
こちらで見ることができます。
こういう先人の方本当にありがたい。

テストをする

テストコードはこうなりました。

using System;
using Xunit;

namespace XUnitTestTrial
{
    public class UnitTest
    {
        Test.Test t = new Test.Test();

        [Fact]
        public void CalcTest()
        {
            Assert.Equal(199, t.Calc(100, 200, 100));
        }

        [Theory]
        [InlineData(5590, 103, 971, 593)]
        [InlineData(0, 1000, 1, 1)]

        //失敗するデータ
        [InlineData(1, 1000, 1, 1)]
        public void CalcTest2(int answer, int x, int y, int z)
        {
            Assert.Equal(answer, t.Calc(x, y, z));
        }
    }
}

値は問題の入力例と出力例を
それぞれ入れています。

AssertionはEqualを使って
「Calcメソッドに入力例の値を渡して実行し
返ってきた値が
出力例と同じであればOK」という
テストにしました。

下記の画像が実行結果になります。

正常だと緑のチェック
エラーだと赤いバツが付きました。

FactとTheory

Factだと1つのメソッドで1つ、
Theoryだと1つのメソッドで複数のテストが
実行できます。

テストを実行したらエラーが出た

もし実行した時BadImageFormatExceptionが
出たらこの記事を見てみてください。

テストメソッドの命名規則とその他

今回テストメソッドに雑な名前をつけましたが
ベストプラクティスのドキュメントに
どういう名前をつければいいか書いてありますので
見てみてください。

雑感

いままでコード変更したら
手動で入力してテストをしていたので
めちゃくちゃ楽になりました。
かなり良い。これからも使っていきます。

今回最低限のことしか行っていないので
使ってるうちに見つけたこととか
あったら記事を書くと思います。