Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Met gegevensgestuurde tests kunt u dezelfde testmethode uitvoeren met meerdere sets invoergegevens. In plaats van afzonderlijke testmethoden te schrijven voor elke testcase, definieert u uw testlogica eenmaal en levert u verschillende invoer via kenmerken of externe gegevensbronnen.
Overzicht
MSTest biedt verschillende kenmerken voor gegevensgestuurde tests:
| Attribute | Gebruiksituatie | Ideaal voor |
|---|---|---|
DataRow |
Inline-testgegevens | Eenvoudige, statische testcases |
DynamicData |
Gegevens uit methoden, eigenschappen of velden | Complexe of berekende testgegevens |
DataSource |
Externe gegevensbestanden of -databases | Verouderde scenario's met externe gegevensbronnen |
MSTest biedt ook de volgende typen voor het uitbreiden van gegevensgestuurde scenario's:
-
TestDataRow<T>: Een retourtype voorITestDataSourceimplementaties (inclusiefDynamicData) waarmee metagegevensondersteuning wordt toegevoegd, zoals weergavenamen, categorieën en het negeren van berichten voor afzonderlijke testcases. -
ITestDataSource: Een interface die u op een aangepast kenmerk kunt implementeren om volledig aangepaste gegevensbronkenmerken te maken.
Aanbeveling
Gebruik het opensource Combinatorial.MSTest NuGet-pakket voor combinaties (alle combinaties van meerdere parametersets testen). Dit door de community onderhouden pakket is beschikbaar op GitHub , maar wordt niet onderhouden door Microsoft.
DataRowAttribute
Hiermee DataRowAttribute kunt u dezelfde testmethode uitvoeren met meerdere verschillende invoerwaarden. Pas een of meerdere DataRow kenmerken toe op een testmethode en combineer deze met de TestMethodAttribute.
Het aantal en de typen argumenten moeten exact overeenkomen met de handtekening van de testmethode.
Aanbeveling
Gerelateerde analyses:
-
MSTEST0014 valideert dat
DataRowargumenten overeenkomen met de handtekening van de testmethode. -
MSTEST0042 detecteert dubbele
DataRowvermeldingen die dezelfde testcase meerdere keren zouden uitvoeren.
Basaal gebruik
[TestClass]
public class CalculatorTests
{
[TestMethod]
[DataRow(1, 2, 3)]
[DataRow(0, 0, 0)]
[DataRow(-1, 1, 0)]
[DataRow(100, 200, 300)]
public void Add_ReturnsCorrectSum(int a, int b, int expected)
{
var calculator = new Calculator();
Assert.AreEqual(expected, calculator.Add(a, b));
}
}
Ondersteunde argumenttypen
DataRow ondersteunt verschillende argumenttypen, waaronder primitieven, tekenreeksen, matrices en null-waarden:
[TestClass]
public class DataRowExamples
{
[TestMethod]
[DataRow(1, "message", true, 2.0)]
public void TestWithMixedTypes(int i, string s, bool b, float f)
{
// Test with different primitive types
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" })]
public void TestWithArray(string[] lines)
{
Assert.AreEqual(2, lines.Length);
}
[TestMethod]
[DataRow(null)]
public void TestWithNull(object o)
{
Assert.IsNull(o);
}
[TestMethod]
[DataRow(new string[] { "a", "b" }, new string[] { "c", "d" })]
public void TestWithMultipleArrays(string[] input, string[] expected)
{
// Starting with MSTest v3, two arrays don't need wrapping
}
}
Parameters gebruiken voor variabele argumenten
Gebruik het params trefwoord om een variabel aantal argumenten te accepteren:
[TestClass]
public class ParamsExample
{
[TestMethod]
[DataRow(1, 2, 3, 4)]
[DataRow(10, 20)]
[DataRow(5)]
public void TestWithParams(params int[] values)
{
Assert.IsTrue(values.Length > 0);
}
}
Aangepaste weergavenamen
Stel de DisplayName eigenschap in om aan te passen hoe testcases worden weergegeven in Test Explorer:
[TestClass]
public class DisplayNameExample
{
[TestMethod]
[DataRow(1, 2, DisplayName = "Functional Case FC100.1")]
[DataRow(3, 4, DisplayName = "Edge case: small numbers")]
public void TestMethod(int i, int j)
{
Assert.IsTrue(i < j);
}
}
Aanbeveling
Voor meer controle over testmetagegevens kunt u Overwegen TestDataRow<T> te gebruiken met DynamicData.
TestDataRow<T> ondersteunt weergavenamen, testcategorieën en negeerberichten voor afzonderlijke testcases.
Specifieke testcases negeren
Vanaf MSTest v3.8 gebruikt u de IgnoreMessage eigenschap om specifieke gegevensrijen over te slaan:
[TestClass]
public class IgnoreDataRowExample
{
[TestMethod]
[DataRow(1, 2)]
[DataRow(3, 4, IgnoreMessage = "Temporarily disabled - bug #123")]
[DataRow(5, 6)]
public void TestMethod(int i, int j)
{
// Only the first and third data rows run
// The second is skipped with the provided message
}
}
DynamicDataAttribute
Hiermee DynamicDataAttribute kunt u testgegevens opgeven uit methoden, eigenschappen of velden. Gebruik dit kenmerk wanneer testgegevens complex zijn, dynamisch worden berekend of te uitgebreid zijn voor inlinekenmerken DataRow .
Ondersteunde gegevensbrontypen
De gegevensbron kan elk IEnumerable<T> retourneren waarbij T een van de typen is die in de volgende tabel worden vermeld. Alle verzamelingen die IEnumerable<T> implementeren, waaronder List<T>, arrays zoals T[], of aangepaste verzameltypen. Kies op basis van uw behoeften:
| Resultaattype | Typeveiligheid | Ondersteuning voor metagegevens | Ideaal voor |
|---|---|---|---|
ValueTuple (bijvoorbeeld, (int, string)) |
Compileertijd | Nee. | De meeste scenario's: eenvoudige syntaxis met volledige typecontrole |
Tuple<...> |
Compileertijd | Nee. | Wanneer u niet kunt gebruiken ValueTuple |
TestDataRow<T> |
Compileertijd | Yes | Testcases die weergavenamen, categorieën of negeren van berichten nodig hebben |
object[] |
Alleen de runtime | Nee. | Verouderde code: vermijden voor nieuwe tests |
Aanbeveling
Gebruik voor nieuwe testgegevensmethoden ValueTuple voor eenvoudige gevallen of TestDataRow<T> wanneer u metagegevens nodig hebt. Vermijd object[] omdat het geen controle van het type tijdens compileertijd biedt en runtimefouten kan veroorzaken vanwege typeverschillen.
Gegevensbronnen
De gegevensbron kan een methode, eigenschap of veld zijn. Alle drie zijn uitwisselbaar: kies op basis van uw voorkeur:
[TestClass]
public class DynamicDataExample
{
// Method - best for computed or yielded data
public static IEnumerable<(int Value, string Name)> GetTestData()
{
yield return (1, "first");
yield return (2, "second");
}
// Property - concise for static data
public static IEnumerable<(int Value, string Name)> TestDataProperty =>
[
(1, "first"),
(2, "second")
];
// Field - simplest for static data
public static IEnumerable<(int Value, string Name)> TestDataField =
[
(1, "first"),
(2, "second")
];
[TestMethod]
[DynamicData(nameof(GetTestData))]
public void TestWithMethod(int value, string name)
{
Assert.IsTrue(value > 0);
}
[TestMethod]
[DynamicData(nameof(TestDataProperty))]
public void TestWithProperty(int value, string name)
{
Assert.IsTrue(value > 0);
}
[TestMethod]
[DynamicData(nameof(TestDataField))]
public void TestWithField(int value, string name)
{
Assert.IsTrue(value > 0);
}
}
Opmerking
Methoden, eigenschappen en velden van gegevensbronnen moeten public static zijn en een IEnumerable<T> van een ondersteund type retourneren.
Aanbeveling
Gerelateerde analyse: MSTEST0018 valideert of de gegevensbron bestaat, toegankelijk is en de juiste handtekening heeft.
Gegevensbron uit een andere klasse
Geef een andere klasse op met behulp van de typeparameter:
public class TestDataProvider
{
public static IEnumerable<(int, string)> GetTestData()
{
yield return (1, "first");
yield return (2, "second");
}
}
[TestClass]
public class DynamicDataExternalExample
{
[TestMethod]
[DynamicData(nameof(TestDataProvider.GetTestData), typeof(TestDataProvider))]
public void TestMethod(int value1, string value2)
{
Assert.IsTrue(value1 > 0);
}
}
Aangepaste weergavenamen
Weergavenamen van testcases aanpassen met behulp van de DynamicDataDisplayName eigenschap:
using System.Reflection;
[TestClass]
public class DynamicDataDisplayNameExample
{
[TestMethod]
[DynamicData(nameof(GetTestData), DynamicDataDisplayName = nameof(GetDisplayName))]
public void TestMethod(int value1, string value2)
{
Assert.IsTrue(value1 > 0);
}
public static IEnumerable<(int, string)> GetTestData()
{
yield return (1, "first");
yield return (2, "second");
}
public static string GetDisplayName(MethodInfo methodInfo, object[] data)
{
return $"{methodInfo.Name} with value {data[0]} and '{data[1]}'";
}
}
Opmerking
De weergavenaammethode moet zijn public static, retourneert een stringen accepteert twee parameters: MethodInfo en object[].
Aanbeveling
Voor een eenvoudigere benadering van aangepaste weergavenamen kunt u Overwegen TestDataRow<T> te gebruiken met de DisplayName eigenschap ervan in plaats van een afzonderlijke methode.
Alle testcases van een gegevensbron negeren
Vanaf MSTest v3.8 kunt u met IgnoreMessage alle testcases overslaan.
[TestClass]
public class IgnoreDynamicDataExample
{
[TestMethod]
[DynamicData(nameof(GetTestData), IgnoreMessage = "Feature not ready")]
public void TestMethod(int value1, string value2)
{
// All test cases from GetTestData are skipped
}
public static IEnumerable<(int, string)> GetTestData()
{
yield return (1, "first");
yield return (2, "second");
}
}
Aanbeveling
Als u afzonderlijke testcases wilt negeren, gebruikt u TestDataRow<T> met de IgnoreMessage eigenschap. Zie de sectie TestDataRow<T> .
TestDataRow
De TestDataRow<T> klasse biedt verbeterde controle over testgegevens in gegevensgestuurde tests. Gebruik IEnumerable<T> als het retourtype van uw gegevensbron TestDataRow<T> om het volgende op te geven:
- Aangepaste weergavenamen: Stel een unieke weergavenaam per testcase in met behulp van de DisplayName eigenschap.
- Testcategorieën: voeg metagegevens toe aan afzonderlijke testcases met behulp van de TestCategories eigenschap.
- Berichten negeren: sla specifieke testcases over met redenen die de IgnoreMessage eigenschap gebruiken.
- Typeveilige gegevens: gebruik generics voor sterk getypte testgegevens.
Basaal gebruik
[TestClass]
public class TestDataRowExample
{
[TestMethod]
[DynamicData(nameof(GetTestDataRows))]
public void TestMethod(int value1, string value2)
{
Assert.IsTrue(value1 > 0);
}
public static IEnumerable<TestDataRow<(int, string)>> GetTestDataRows()
{
yield return new TestDataRow<(int, string)>((1, "first"))
{
DisplayName = "Test Case 1: Basic scenario",
};
yield return new TestDataRow<(int, string)>((2, "second"))
{
DisplayName = "Test Case 2: Edge case",
TestCategories = ["HighPriority", "Critical"],
};
yield return new TestDataRow<(int, string)>((3, "third"))
{
IgnoreMessage = "Not yet implemented",
};
}
}
DataSourceAttribute
Opmerking
DataSource is alleen beschikbaar in .NET Framework. Voor .NET (Core)-projecten gebruikt u DataRow of DynamicData in plaats van.
Hiermee DataSourceAttribute worden tests verbonden met externe gegevensbronnen, zoals CSV-bestanden, XML-bestanden of databases.
Zie voor gedetailleerde informatie:
- Een gegevensgestuurde eenheidstest maken
- Een configuratiebestand gebruiken om een gegevensbron te definiëren
ITestDataSource
Met de ITestDataSource interface kunt u volledig aangepaste gegevensbronkenmerken maken. Implementeer deze interface wanneer u gedrag nodig hebt dat de ingebouwde kenmerken niet ondersteunen, zoals het genereren van testgegevens op basis van omgevingsvariabelen, configuratiebestanden of andere runtimevoorwaarden.
Interfaceleden
De interface definieert twee methoden:
| Methode | Purpose |
|---|---|
GetData(MethodInfo) |
Retourneert testgegevens als IEnumerable<object?[]> |
GetDisplayName(MethodInfo, object?[]?) |
Retourneert de weergavenaam voor een testcase |
Een aangepast gegevensbronkenmerk maken
Als u een aangepaste gegevensbron wilt maken, definieert u een kenmerkklasse die wordt overgenomen van Attribute en implementeert ITestDataSource:
using System.Globalization;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyDataSourceAttribute : Attribute, ITestDataSource
{
public IEnumerable<object?[]> GetData(MethodInfo methodInfo)
{
// Return test data based on your custom logic
yield return [1, "first"];
yield return [2, "second"];
yield return [3, "third"];
}
public string? GetDisplayName(MethodInfo methodInfo, object?[]? data)
{
return data is null
? null
: string.Format(CultureInfo.CurrentCulture, "{0} ({1})", methodInfo.Name, string.Join(",", data));
}
}
[TestClass]
public class CustomDataSourceExample
{
[TestMethod]
[MyDataSource]
public void TestWithCustomDataSource(int value, string name)
{
Assert.IsTrue(value > 0);
Assert.IsNotNull(name);
}
}
Praktijkvoorbeeld: testgegevens op basis van omgeving
In dit voorbeeld ziet u een aangepast kenmerk dat testgegevens genereert op basis van doelframeworks, filteren op basis van het besturingssysteem:
using System.Globalization;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method)]
public class TargetFrameworkDataAttribute : Attribute, ITestDataSource
{
private readonly string[] _frameworks;
public TargetFrameworkDataAttribute(params string[] frameworks)
{
_frameworks = frameworks;
}
public IEnumerable<object?[]> GetData(MethodInfo methodInfo)
{
bool isWindows = OperatingSystem.IsWindows();
foreach (string framework in _frameworks)
{
// Skip .NET Framework on non-Windows platforms
if (!isWindows && framework.StartsWith("net4", StringComparison.Ordinal))
{
continue;
}
yield return [framework];
}
}
public string? GetDisplayName(MethodInfo methodInfo, object?[]? data)
{
return data is null
? null
: string.Format(CultureInfo.CurrentCulture, "{0} ({1})", methodInfo.Name, data[0]);
}
}
[TestClass]
public class CrossPlatformTests
{
[TestMethod]
[TargetFrameworkData("net48", "net8.0", "net9.0")]
public void TestOnMultipleFrameworks(string targetFramework)
{
// Test runs once per applicable framework
Assert.IsNotNull(targetFramework);
}
}
Aanbeveling
Voor eenvoudige gevallen waarin u alleen weergavenamen moet aanpassen of metagegevens moet toevoegen, kunt u overwegen TestDataRow<T> te gebruiken in DynamicData plaats van te implementeren ITestDataSource. Reserveer aangepaste ITestDataSource implementaties voor scenario's waarvoor dynamische filtering of complexe logica voor het genereren van gegevens is vereist.
Strategie uitvouwen
Gegevensgestuurde testkenmerken ondersteunen de TestDataSourceUnfoldingStrategy eigenschap, waarmee wordt bepaald hoe testcases worden weergegeven in testverkenner en TRX-resultaten. Deze eigenschap bepaalt ook of u afzonderlijke testcases onafhankelijk kunt uitvoeren.
Beschikbare strategieën
| Strategie | Gedrag |
|---|---|
Auto (standaard) |
MSTest bepaalt het uitvouwen van de beste strategie |
Unfold |
Alle testcases worden uitgevouwen en afzonderlijk weergegeven |
Fold |
Alle testcases worden samengebracht tot één testknooppunt |
Wanneer de strategie moet worden gewijzigd
Voor de meeste scenario's biedt het standaardgedrag Auto de beste balans. U kunt deze instelling alleen wijzigen wanneer u specifieke vereisten hebt:
- Niet-deterministische gegevensbronnen
- Bekende beperkingen of fouten in MSTest
- Prestatieproblemen met veel testcases
Voorbeeld van gebruik
[TestClass]
public class UnfoldingExample
{
[TestMethod(UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold)] // That's the default behavior
[DataRow(1, "one")]
[DataRow(2, "two")]
[DataRow(3, "three")]
public void TestMethodWithUnfolding(int value, string text)
{
// Each test case appears individually in Test Explorer
}
[TestMethod(UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)]
[DataRow(1, "one")]
[DataRow(2, "two")]
[DataRow(3, "three")]
public void TestMethodWithFolding(int value, string text)
{
// All test cases appear as a single collapsed node
}
}
Beste praktijken
Kies het juiste kenmerk: Gebruik
DataRowdit voor eenvoudige, inlinegegevens. GebruikenDynamicDatavoor complexe of berekende gegevens.Geef uw testcases een naam: gebruik
DisplayNamedeze om testfouten gemakkelijker te identificeren.Gegevensbronnen dicht houden: definieer indien mogelijk gegevensbronnen in dezelfde klasse voor betere onderhoudbaarheid.
Gebruik zinvolle gegevens: kies testgegevens die edge-cases en grensvoorwaarden uitvoeren.
Considereer combinatorieel testen: gebruik het Combinatorial.MSTest pakket voor het testen van parametercombinaties.