Hat MSTest ein Äquivalent zu NUnits TestCase?

107

Ich finde die TestCaseFunktion in NUnit sehr nützlich, um schnell Testparameter anzugeben, ohne für jeden Test eine eigene Methode zu benötigen. Gibt es etwas Ähnliches in MSTest?

 [TestFixture]  
 public class StringFormatUtilsTest  
 {  
     [TestCase("tttt", "")]  
     [TestCase("", "")]  
     [TestCase("t3a4b5", "345")]  
     [TestCase("3&5*", "35")]  
     [TestCase("123", "123")]  
     public void StripNonNumeric(string before, string expected)  
     {  
         string actual = FormatUtils.StripNonNumeric(before);  
         Assert.AreEqual(expected, actual);  
     }  
 }  
tjjjohnson
quelle
Warum benutzt du nicht NUnit?
Mike de Klerk
1
@MikedeKlerk: Nunit ist unglaublich langsam, wenn Sie Entity Framework verwenden ... Es spiegelt anscheinend jedes Mal, wenn Sie einen Test ausführen, alle generierten Klassen wider.
Robert Harvey
Im Allgemeinen bietet NUnit mehr Funktionen als MSTest. Wenn Sie MSTest verwenden, um Ihre Tests mit dem VS Test Explorer ausführen zu können, können Sie dies auch mit NUnit tun, indem Sie die Erweiterung NUnit Test Adapter über NuGet
Stacked
1
Versuchen Sie DataRow(), siehe: blogs.msdn.microsoft.com/devops/2016/06/17/…
Babak

Antworten:

62

Microsoft hat kürzlich "MSTest V2" angekündigt (siehe Blog-Artikel ). Auf diese Weise können Sie das DataRowAttribut -attribute konsistent (Desktop, UWP, ...) verwenden !

 [TestClass]  
 public class StringFormatUtilsTest  
 {  
     [DataTestMethod]  
     [DataRow("tttt", "")]  
     [DataRow("", "")]  
     [DataRow("t3a4b5", "345")]  
     [DataRow("3&5*", "35")]  
     [DataRow("123", "123")]  
     public void StripNonNumeric(string before, string expected)  
     {  
         string actual = FormatUtils.StripNonNumeric(before);  
         Assert.AreEqual(expected, actual);  
     }  
 } 

Auch hier erkennt der Test Explorer von Visual Studio Express diese Tests leider nicht. Aber zumindest die "vollständigen" VS-Versionen unterstützen diese Funktion jetzt!

Um es zu verwenden, installieren Sie einfach die NuGet-Pakete MSTest.TestFramework und MSTest.TestAdapter (beide ab sofort vorab verfügbar ).

Ältere Antwort:

Wenn Sie sich nicht an MSTest halten müssen und es nur verwenden, um die Tests über den Test Explorer ausführen zu können weil Sie nur eine Visual Studio Express Edition haben, dann könnte dies eine Lösung für Sie sein:

Es gibt die VsTestAdapter VSIX-Erweiterung , mit der NUnit-Tests über den Test Explorer ausgeführt werden können. Leider können VS Express-Benutzer keine Erweiterungen installieren ... Aber zum Glück wird der VsTestAdapter auch mit einem einfachen NuGet-Paket geliefert !

Wenn Sie ein VS Express-Benutzer sind, installieren Sie einfach das VsTestAdapter NuGet-Paket und genießen Sie die Ausführung Ihrer NUnit-Tests / Testfälle über den Test Explorer!


Leider ist die oben genannte Aussage nicht wahr. Es ist zwar durchaus möglich, das Paket über eine Express-Edition zu installieren, es ist jedoch nutzlos, da der Test Explorer nicht verwendet werden kann. Zuvor gab es eine Randnotiz zu einer älteren Version des TestAdapters, die von der Beschreibungsseite von 2.0.0 entfernt wurde :

Beachten Sie, dass dies mit VS Express nicht funktioniert

khlr
quelle
4
MSTest "v2" ist jetzt das Standardframework bei Verwendung von VS 2017. Da dies in der neuesten Version von OOTB unterstützt wird, sollten diese Informationen wahrscheinlich ganz oben in der Antwort stehen.
Marc L.
34

Ich weiß, dass dies eine späte Antwort ist, aber hoffentlich hilft sie anderen.

Ich habe überall nach einer eleganten Lösung gesucht und selbst eine geschrieben. Wir verwenden es in über 20 Projekten mit Tausenden von Komponententests und Hunderttausenden von Iterationen. Nie einen Schlag verpasst.

https://github.com/Thwaitesy/MSTestHacks

1) Installieren Sie das NuGet- Paket.

2) Erben Sie Ihre Testklasse von TestBase

public class UnitTest1 : TestBase
{ }

3) Erstellen Sie eine Eigenschaft, ein Feld oder eine Methode, die IEnumerable zurückgibt

[TestClass]
public class UnitTest1 : TestBase
{
    private IEnumerable<int> Stuff
    {
        get
        {
            //This could do anything, get a dynamic list from anywhere....
            return new List<int> { 1, 2, 3 };
        }
    }
}

4) Fügen Sie Ihrer Testmethode das Attribut MSTest DataSource hinzu und verweisen Sie dabei auf den oben genannten IEnumerable-Namen. Dies muss voll qualifiziert sein.

[TestMethod]
[DataSource("Namespace.UnitTest1.Stuff")]
public void TestMethod1()
{
    var number = this.TestContext.GetRuntimeDataSourceObject<int>();

    Assert.IsNotNull(number);
}

Endergebnis: 3 Iterationen wie bei der normalen DataSource :)

using Microsoft.VisualStudio.TestTools.UnitTesting;
using MSTestHacks;

namespace Namespace
{
    [TestClass]
    public class UnitTest1 : TestBase
    {
        private IEnumerable<int> Stuff
        {
            get
            {
                //This could do anything, get a dynamic list from anywhere....
                return new List<int> { 1, 2, 3 };
            }
        }

        [TestMethod]
        [DataSource("Namespace.UnitTest1.Stuff")]
        public void TestMethod1()
        {
            var number = this.TestContext.GetRuntimeDataSourceObject<int>();

            Assert.IsNotNull(number);
        }
    }
}
Thwaitesy
quelle
Würde dies auch mit mehreren Parametern für jeden Fall funktionieren?
Lonefish
Da die zugrunde liegende Bibliothek geändert wurde, funktioniert dies mit MsTest "v2" nicht . Dies ist die Standardeinstellung für VS15 (VS 2017).
Marc L.
3
Ja, wenn Sie MSTest V2 verwenden, gibt es einen neuen Testfallanbieter, der dem von NUnit ähnelt. Daher ist diese Arbeit um 👏
Thwaitesy
Dies scheint in VS 2015 nicht zu funktionieren, die App-Konfigurationsdatei wird nicht dynamisch gefüllt und daher werden die Datenquellen nicht gefunden
Reed
13

Ich weiß, dass dies eine weitere späte Antwort ist, aber in meinem Team, das an die Verwendung des MS Test-Frameworks gebunden ist, haben wir eine Technik entwickelt, die sich nur auf anonyme Typen stützt, um ein Array von Testdaten zu speichern, und auf LINQ, um jede Zeile zu durchlaufen und zu testen. Es erfordert keine zusätzlichen Klassen oder Frameworks und ist in der Regel recht einfach zu lesen und zu verstehen. Es ist auch viel einfacher zu implementieren als datengesteuerte Tests mit externen Dateien oder einer verbundenen Datenbank.

Angenommen, Sie haben eine Erweiterungsmethode wie die folgende:

public static class Extensions
{
    /// <summary>
    /// Get the Qtr with optional offset to add or subtract quarters
    /// </summary>
    public static int GetQuarterNumber(this DateTime parmDate, int offset = 0)
    {
        return (int)Math.Ceiling(parmDate.AddMonths(offset * 3).Month / 3m);
    }
}

Sie können ein Array anonymer Typen verwenden, die mit LINQ kombiniert sind, um Tests wie diesen zu schreiben:

[TestMethod]
public void MonthReturnsProperQuarterWithOffset()
{
    // Arrange
    var values = new[] {
        new { inputDate = new DateTime(2013, 1, 1), offset = 1, expectedQuarter = 2},
        new { inputDate = new DateTime(2013, 1, 1), offset = -1, expectedQuarter = 4},
        new { inputDate = new DateTime(2013, 4, 1), offset = 1, expectedQuarter = 3},
        new { inputDate = new DateTime(2013, 4, 1), offset = -1, expectedQuarter = 1},
        new { inputDate = new DateTime(2013, 7, 1), offset = 1, expectedQuarter = 4},
        new { inputDate = new DateTime(2013, 7, 1), offset = -1, expectedQuarter = 2},
        new { inputDate = new DateTime(2013, 10, 1), offset = 1, expectedQuarter = 1},
        new { inputDate = new DateTime(2013, 10, 1), offset = -1, expectedQuarter = 3}
        // Could add as many rows as you want, or extract to a private method that
        // builds the array of data
    }; 
    values.ToList().ForEach(val => 
    { 
        // Act 
        int actualQuarter = val.inputDate.GetQuarterNumber(val.offset); 
        // Assert 
        Assert.AreEqual(val.expectedQuarter, actualQuarter, 
            "Failed for inputDate={0}, offset={1} and expectedQuarter={2}.", val.inputDate, val.offset, val.expectedQuarter); 
        }); 
    }
}

Bei Verwendung dieser Technik ist es hilfreich, eine formatierte Nachricht zu verwenden, die die Eingabedaten in Assert enthält, um festzustellen, in welcher Zeile der Test fehlschlägt.

Ich habe über diese Lösung mit mehr Hintergrund und Details auf AgileCoder.net gebloggt .

Gary.Ray
quelle
4
Das größte Problem dabei ist, dass wenn ein Fall aus dem Array von Werten heraus fehlschlägt, der gesamte Test fehlschlägt und keine Fälle mehr getestet werden.
Ytoledano
Dadurch entstehen Testfälle, die sich gegenseitig beeinflussen können.
BartoszKP
@BartoszKP Nur wenn das zu testende System Nebenwirkungen hat. In diesem Fall ist dies wahrscheinlich keine optimale Technik.
Gary.Ray
@ Gary.Ray Auch wenn das System noch keine Nebenwirkungen hat . Auch wenn ein Test nicht bestanden wird und ein anderer Entwickler versucht, dies zu beheben, und Stunden damit verschwendet, herauszufinden, ob die Abhängigkeit wichtig ist oder nicht. Dies ist nur etwas, was Sie niemals tun sollten, Punkt.
BartoszKP
Gut genug. +1
Trey Mack
7

Khlr gab eine gute detaillierte Erklärung und anscheinend begann dieser Ansatz in VS2015 Express für Desktop zu funktionieren. Ich habe versucht, den Kommentar zu hinterlassen, aber mein mangelnder Ruf hat es mir nicht erlaubt.

Lassen Sie mich die Lösung hier kopieren:

[TestClass]  
 public class StringFormatUtilsTest  
 {  
     [TestMethod]  
     [DataRow("tttt", "")]  
     [DataRow("", "")]  
     [DataRow("t3a4b5", "345")]  
     [DataRow("3&amp;amp;5*", "35")]  
     [DataRow("123", "123")]  
     public void StripNonNumeric(string before, string expected)  
     {  
         string actual = FormatUtils.StripNonNumeric(before);  
         Assert.AreEqual(expected, actual);  
     }  
 } 

Um es zu verwenden, installieren Sie einfach die NuGet-Pakete MSTest.TestFramework und MSTest.TestAdapter .

Ein Problem ist

Fehler CS0433 Der Typ 'TestClassAttribute' ist sowohl in 'Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version = 10.0.0.0 als auch in' Microsoft.VisualStudio.TestPlatform.TestFramework, Version = 14.0.0.0 vorhanden

Entfernen Sie daher Microsoft.VisualStudio.QualityTools.UnitTestFramework aus den Referenzen des Projekts.

Sie können gerne die ursprüngliche Antwort bearbeiten und diese löschen.

Kunst
quelle
0

MSTest hat das DataSource-Attribut, mit dem Sie ihm eine Datenbanktabelle, CSV, XML usw. zuführen können. Ich habe es verwendet und es funktioniert gut. Ich kenne keine Möglichkeit, die Daten wie oben in Ihrer Frage als Attribute zu platzieren, aber es ist sehr einfach, die externen Datenquellen einzurichten, und Dateien können in das Projekt aufgenommen werden. Ich hatte es eine Stunde nach meinem Start laufen lassen und bin kein Experte für automatisierte Tests.

https://msdn.microsoft.com/en-us/library/ms182527.aspx?f=255&MSPPError=-2147217396 enthält ein vollständiges Lernprogramm, das auf Datenbankeingaben basiert.

http://www.rhyous.com/2015/05/11/row-tests-or-paramerterized-tests-mstest-xml/ enthält ein Tutorial, das auf der Eingabe von XML-Dateien basiert.

CindyH
quelle