3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[C#] テストデータファイルをテストケースごとにディレクトリ分けして管理する

Posted at

[C#] テストデータファイルをテストケースごとにディレクトリ分けして管理する

C#でUnitTest(MSTest)を書いていると、テスト用のデータファイルが必要な場合がある。
(画像を読み込んでなにかするとか、ヒアドキュメントで書くのは厳しいサイズのJSONがあるとか)

テストケースごとに必要なファイルが異なるので、"テストクラス/テストケース"という名前のディレクトリに分けて管理することにした。
(DeploymentItemAttributeはいまいち便利さが分からない…)

テストデータはVisualStudioから簡単に表示したいので、プロジェクトに登録し、ビルド時にデータファイルとして出力フォルダにコピーするよう設定した。
image.png

テストの実装側ではこうした。

[TestClass]
public class SomeTestClass {

  [TestMethod]
  public void SomeTest(){
    // テストクラスやテストメソッドのリネームに追随できるよう、nameofを使ってパスを定義
    var testDataDir = Path.Combine(nameof(SomeTestClass), nameof(SomeTest)); // <- テストケースごとに書きかえる必要がある

    // ディレクトリ内のテストデータを読んでテストする
    var imgPath = Path.Combine(testDataDir, "foo.png");
  }

}

問題

nameof(SomeTestClass)のところを書き換えるのがとても面倒くさい。

対策

こんなクラスを作った。

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Diagnostics;
using System.Linq;

internal class TestHelper
{
    /// <summary>
    /// テストデータ格納ディレクトリへのパスを取得する。
    /// </summary>
    /// <returns>テストデータ格納ディレクトリへのパス。</returns>
    public static string GetTestDataDir()
    {
        var testMethodStackFrame = new StackTrace()
            .GetFrames()
            .First(x => Attribute.GetCustomAttribute(x.GetMethod(), typeof(TestMethodAttribute)) != null);
        if (testMethodStackFrame == null) throw new InvalidOperationException("This method must be called from a test method with the TestMethodAttribute attribute.");
        var testMethod = testMethodStackFrame.GetMethod();
        return $@"TestData\{testMethod.ReflectedType.Name}\{testMethod.Name}";
    }
}

なにこれ

この関数を呼び出すと、以下が行われる。

  1. スタックトレースをたどって、TestMethod属性がついてるメソッド(= テストケース)を探す
  2. メソッド名とそのメソッドが定義されているクラス名を取得する
  3. "TestClass\TestMethod"形式のパス文字列を生成して返す

結果

全テストケースで、以下をコピペするだけで、対応ディレクトリを取得できるようになった。

var testDataDir = TestHelper.GetTestDataDir();

ほか

テストフレームワークがNUnitの場合は、TestMethodAttributeをTestAttributeに変えればそのまま動くはず。

3
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?