MSTestで複数のパラメーターを使用してテストメソッドを実行する方法


140

NUnitには、次のような値と呼ばれる機能があります。

[Test]
public void MyTest(
    [Values(1,2,3)] int x,
    [Values("A","B")] string s)
{
    // ...
}

つまり、テストメソッドは6回実行されます。

MyTest(1, "A")
MyTest(1, "B")
MyTest(2, "A")
MyTest(2, "B")
MyTest(3, "A")
MyTest(3, "B")

現在、MSTestを使用していますが、複数のパラメーターを使用して同じテストを実行できるように、これに相当するものはありますか?

[TestMethod]
public void Mytest()
{
    // ...
}

stackoverflow.com/a/19536942/52277の回答に記載されているように、MSTestHacksを使用できます。
Michael Freidgeim、2016年


@MichaelFreidgeimこの質問は、提案されたターゲットよりも優れた回答です
Rob

1
@ロブ:私見、最も適切な答え-MSTestHacks- MSTestでRowTestする方法?この質問には欠落しています。
Michael Freidgeim、2016年

おそらく@MichaelFreidgeim、機能は今3年半(のために存在しているように見えるけれどもstackoverflow.com/questions/9021881/...
ロブ

回答:


46

残念ながらMSTestではサポートされていません。どうやら拡張性モデルがあり、自分で実装できます。別のオプションは、データ駆動型テストを使用することです。

私の個人的な意見は、NUnitに固執することです...

編集:Visual Studio 2012の更新1以降、MSTestには同様の機能があります。以下の@McAdenの回答を参照してください。


私たちはNUnitコードを生成するSeleniumを使用しているので、代わりにNUnitを使用するように切り替えました:)
The Light

4
Visual Studio 2012 Update 1でも同様のことが可能であることがわかりました。この回答を検討している人の将来の検討のために参考にしてください。
McAden

@McAden説明付きのリンクはありますか?
jeroenh

6
私は以下の例と私のブログ投稿へのリンクを使用して回答を示しました。必要な属性と、テストエクスプローラーでケースを区別する属性の "DisplayName"プロパティについても説明しています。10月のCTPのアナウンスでも言及されました(現在は公式リリースです)blogs.msdn.com/b/visualstudioalm/archive/2012/10/26/…このSOの質問に情報を追加しました。それを探すのにかなりの時間を費やしました。うまくいけば、誰かが時間を節約できるでしょう。
McAden

167

編集4:2016年6月17日、MSTest V2でこれが完了したように見えますhttps : //blogs.msdn.microsoft.com/visualstudioalm/2016/06/17/taking-the-mstest-framework-forward-with-mstest- v2 /

元の回答

1週間ほど前のVisual Studio 2012 Update 1では、同様のことが可能になりました。

[DataTestMethod]
[DataRow(12,3,4)]
[DataRow(12,2,6)]
[DataRow(12,4,3)]
public void DivideTest(int n, int d, int q)
{
  Assert.AreEqual( q, n / d );
}

編集:これはWinRT / Metroのユニットテストプロジェクト内でのみ利用できるようです。バマー

編集2:以下は、Visual Studio内の「定義に移動」を使用して見つかったメタデータです。

#region Assembly Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll, v11.0.0.0
// C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\MSTestFramework\11.0\References\CommonConfiguration\neutral\Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll
#endregion

using System;

namespace Microsoft.VisualStudio.TestPlatform.UnitTestFramework
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class DataTestMethodAttribute : TestMethodAttribute
    {
        public DataTestMethodAttribute();

        public override TestResult[] Execute(ITestMethod testMethod);
    }
}

編集3:この問題はVisual StudioのUserVoiceフォーラムで取り上げられました。最終更新の状態:

開始済み・Visual StudioチームADMIN Visual Studioチーム(製品チーム、Microsoft Visual Studio)が応答しました・2016年4月25日フィードバックをありがとう 私たちはこれに取り組み始めました。

Pratap Lakshman Visual Studio

https://visualstudio.uservoice.com/forums/330519-team-services/suggestions/3865310-allow-use-of-datatestmethod-datarow-in-all-unit


4
Windowsの携帯電話は今のVisual Studio 2012のアップデート2(現在、CTP 4)で、またサポートされています
ペドロ・ラマ

8
アップデート1がありますが、DataTestMethodとDataRowが認識されません。これらの属性はどのライブラリにありますか?
DevDave 2013年

3
DataTestMethodに関する公式の情報源はありますか?それはどの名前空間にあり、どのアセンブリですか?
Igor Lankin 2013

2
UnitTestFramework.dllがコンピューターにインストールされていることを確認し、手動で参照した後、データ行を含む[DataTestMethod]属性を使用してメソッドを記述できましたが、Visual Studio 2012.3のテストエクスプローラーでメソッドを見つけることができません。
Josh DeLong 2013

5
コンピューター上のファイルパス「C:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v8.0 \ ExtensionSDKs \ MSTestFramework \ 11.0 \ References \ CommonConfiguration \ neutral \ Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll」に移動しましたそしてファイルはそこにありました。だから私は私の基本的な単体テストプロジェクトでそれを参照しました。JustDecompileでDLLを開くと、ライブラリにはmscorlib、System、およびSystem.Coreへの参照のみがあることがわかります。これはWindowsストアプロジェクトではありません。
Josh DeLong 2013

34

この機能は現在プレリリース版で、VS 2015で動作します。

例えば:

[TestClass]
public class UnitTest1
{
    [DataTestMethod]
    [DataRow(1, 2, 2)]
    [DataRow(2, 3, 5)]
    [DataRow(3, 5, 8)]
    public void AdditionTest(int a, int b, int result)
    {
        Assert.AreEqual(result, a + b);
    }
}

これが正解です。言う必要はないことに留意されたい[DataTestMethod]使用に【のDataRow(stackoverflow.com/a/59162403/2540235
mattavatar

11

誰も言及していないため、NUnitのValue(またはTestCase)属性とまったく同じではありませんが、MSTestにはDataSource属性があるため、同様のことができます。NUnitの機能ほど単純ではありませんが、データベースまたはXMLファイルに接続できますが、機能します。


7

MSTestにはDataSourceと呼ばれる強力な属性があり、これを使用して、要求どおりにデータ駆動型テストを実行できます。テストデータはXML、CSV、またはデータベースで作成できます。ここにあなたを導くいくつかのリンクがあります

http://visualstudiomagazine.com/articles/2009/09/15/unit-testing-with-vsts2008-part-3.aspx http://msdn.microsoft.com/en-us/library/ms182527.aspx
http: //msdn.microsoft.com/en-us/library/ms243192.aspx

これがお役に立てば幸いです。


6

実装は非常に簡単です。TestContextプロパティとを使用する必要がありTestPropertyAttributeます。

public TestContext TestContext { get; set; }
private List<string> GetProperties()
{
    return TestContext.Properties
        .Cast<KeyValuePair<string, object>>()
        .Where(_ => _.Key.StartsWith("par"))
        .Select(_ => _.Value as string)
        .ToList();
}

//usage
[TestMethod]
[TestProperty("par1", "http://getbootstrap.com/components/")]
[TestProperty("par2", "http://www.wsj.com/europe")]
public void SomeTest()
{
    var pars = GetProperties();
    //...
}

編集:

TestContextプロパティへのアクセスを簡略化し、いくつかのテストケースがあるように動作するように、いくつかの拡張メソッドを用意しました。ここで簡単なテストプロパティを処理する例を参照してください。

[TestMethod]
[TestProperty("fileName1", @".\test_file1")]
[TestProperty("fileName2", @".\test_file2")]
[TestProperty("fileName3", @".\test_file3")]
public void TestMethod3()
{
    TestContext.GetMany<string>("fileName").ForEach(fileName =>
    {
        //Arrange
        var f = new FileInfo(fileName);

        //Act
        var isExists = f.Exists;

        //Asssert
        Assert.IsFalse(isExists);
    });
}

複雑なテストオブジェクトを作成する例:

[TestMethod]
//Case 1
[TestProperty(nameof(FileDescriptor.FileVersionId), "673C9C2D-A29E-4ACC-90D4-67C52FBA84E4")]
//...
public void TestMethod2()
{
    //Arrange
    TestContext.For<FileDescriptor>().Fill(fi => fi.FileVersionId).Fill(fi => fi.Extension).Fill(fi => fi.Name).Fill(fi => fi.CreatedOn, new CultureInfo("en-US", false)).Fill(fi => fi.AccessPolicy)
        .ForEach(fileInfo =>
        {
            //Act
            var fileInfoString = fileInfo.ToString();

            //Assert
            Assert.AreEqual($"Id: {fileInfo.FileVersionId}; Ext: {fileInfo.Extension}; Name: {fileInfo.Name}; Created: {fileInfo.CreatedOn}; AccessPolicy: {fileInfo.AccessPolicy};", fileInfoString);
        });
}

詳細については、拡張メソッドサンプルのセットをご覧ください。


2
このアプローチは機能しますが、パラメーターのセットごとに個別のテストケースを作成しません。
usr4896260

TestProperty値としてより複雑なもの(例: "0-100")を使用して、テスト本体で解析および処理できます。
Andrey Burykin

4

もちろん、このスレッドでは説明されていない別の方法があります。つまり、TestMethodを含むクラスを継承する方法です。次の例では、1つのTestMethodのみが定義されていますが、2つのテストケースが作成されています。

Visual Studio 2012では、TestExplorerに2つのテストを作成します。

  1. DemoTest_B10_A5.test
  2. DemoTest_A12_B4.test

    public class Demo
    {
        int a, b;
    
        public Demo(int _a, int _b)
        {
            this.a = _a;
            this.b = _b;
        }
    
        public int Sum()
        {
            return this.a + this.b;
        }
    }
    
    public abstract class DemoTestBase
    {
        Demo objUnderTest;
        int expectedSum;
    
        public DemoTestBase(int _a, int _b, int _expectedSum)
        {
            objUnderTest = new Demo(_a, _b);
            this.expectedSum = _expectedSum;
        }
    
        [TestMethod]
        public void test()
        {
            Assert.AreEqual(this.expectedSum, this.objUnderTest.Sum());
        }
    }
    
    [TestClass]
    public class DemoTest_A12_B4 : DemoTestBase
    {
        public DemoTest_A12_B4() : base(12, 4, 16) { }
    }
    
    public abstract class DemoTest_B10_Base : DemoTestBase
    {
        public DemoTest_B10_Base(int _a) : base(_a, 10, _a + 10) { }
    }
    
    [TestClass]
    public class DemoTest_B10_A5 : DemoTest_B10_Base
    {
        public DemoTest_B10_A5() : base(5) { }
    }


3

The DataRowAttributeをVisual Studio 2015で動作させることができませんでした。

[TestClass]
public class Tests
{
    private Foo _toTest;

    [TestInitialize]
    public void Setup()
    {
        this._toTest = new Foo();       
    }

    [TestMethod]
    public void ATest()
    {
        this.Perform_ATest(1, 1, 2);
        this.Setup();

        this.Perform_ATest(100, 200, 300);
        this.Setup();

        this.Perform_ATest(817001, 212, 817213);
        this.Setup();

    }

    private void Perform_ATest(int a, int b, int expected)
    {
        //Obviously this would be way more complex...

        Assert.IsTrue(this._toTest.Add(a,b) == expected);    
    }
}

public class Foo
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

ここでの実際の解決策は、NUnitを使用することです(この特定のインスタンスのようにMSTestで立ち往生している場合を除きます)。


3
いずれかのテストコールが分割される時間を節約するために、各テストコールを個別のテストに分割する必要があります。(誰もが知っていることですが)
シルバー

はい、もちろん。実際には、その方法で行われます。この場合、私は単純にするためにそれを単に示していました
ブランドン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.