Een gegevensgestuurde eenheidstest maken
U kunt het Microsoft Unit Test Framework (MSTest) voor beheerde code gebruiken om een eenheidstestmethode in te stellen om waarden op te halen uit een gegevensbron. De methode wordt achtereenvolgens uitgevoerd voor elke rij in de gegevensbron, waardoor u eenvoudig verschillende invoer kunt testen met behulp van één methode.
Een gegevensgestuurde eenheidstest kan een van de volgende typen gebruiken:
- inline data met behulp van het kenmerk
DataRow
- lidgegevens met behulp van het kenmerk
DynamicData
- van een bekende bronprovider met behulp van het kenmerk
DataSource
De methode onder test
Laten we er bijvoorbeeld van uitgaan dat u het volgende hebt:
Een oplossing genaamd
MyBank
die transacties accepteert en verwerkt voor verschillende soorten accounts.Een project in
MyBank
genaamdBankDb
waarmee de transacties voor accounts worden beheerd.Een klasse genaamd
Maths
in hetBankDb
project dat de wiskundige functies uitvoert om ervoor te zorgen dat elke transactie voordelig is voor de bank.Een eenheidstestproject met de naam
BankDbTests
om het gedrag van hetBankDb
-onderdeel te testen.Een eenheidstestklasse met de naam
MathsTests
om het gedrag van deMaths
-klasse te controleren.
We testen een methode in Maths
waarmee twee gehele getallen worden toegevoegd met behulp van een lus:
public int AddIntegers(int first, int second)
{
int sum = first;
for (int i = 0; i < second; i++)
{
sum += 1;
}
return sum;
}
Test testmethode
Inline gegevensgestuurde test
Voor inlinetests gebruikt MSTest DataRow
om waarden op te geven die worden gebruikt door de gegevensgestuurde test. De test in dit voorbeeld wordt achtereenvolgens uitgevoerd voor elke gegevensrij.
[TestMethod]
[DataRow(1, 1, 2)]
[DataRow(2, 2, 4)]
[DataRow(3, 3, 6)]
[DataRow(0, 0, 1)] // The test run with this row fails
public void AddIntegers_FromDataRowTest(int x, int y, int expected)
{
var target = new Maths();
int actual = target.AddIntegers(x, y);
Assert.AreEqual(expected, actual,
"x:<{0}> y:<{1}>",
new object[] {x, y});
}
Lidgegevensgestuurde test
MSTest gebruikt het DynamicData
-attribuut om de naam, het soort en het definitieve type van het lid dat de gegevens levert op te geven, waarbij standaard het huidige type wordt gebruikt voor de gegevensgestuurde test.
Notitie
Vóór MSTest 3.8 had de opsomming DynamicDataSourceType
twee leden, Property
en Method
. De standaardwaarde is Property
. Vanaf MSTest 3.8 wordt een nieuw lid AutoDetect
toegevoegd aan de opsomming en is dit de standaardinstelling. U hoeft dus niet langer DynamicDataSourceType
op te geven.
public static IEnumerable<object[]> AdditionData
{
get
{
return new[]
{
new object[] { 1, 1, 2 },
new object[] { 2, 2, 4 },
new object[] { 3, 3, 6 },
new object[] { 0, 0, 1 }, // The test run with this row fails
};
}
}
[TestMethod]
[DynamicData(nameof(AdditionData))]
public void AddIntegers_FromDynamicDataTest(int x, int y, int expected)
{
var target = new Maths();
int actual = target.AddIntegers(x, y);
Assert.AreEqual(expected, actual,
"x:<{0}> y:<{1}>",
new object[] {x, y});
}
Het is ook mogelijk om de standaard gegenereerde weergavenaam te overschrijven met behulp van de eigenschap DynamicDataDisplayName
van het kenmerk DynamicData
. De handtekening van de weergavenaammethode moet public static string
zijn en accepteert twee parameters, de eerste van type MethodInfo
en de tweede van type object[]
.
public static string GetCustomDynamicDataDisplayName(MethodInfo methodInfo, object[] data)
{
return string.Format("DynamicDataTestMethod {0} with {1} parameters", methodInfo.Name, data.Length);
}
[DynamicData(nameof(AdditionData), DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))]
Gegevensgestuurde test van bronprovider
Het maken van een gegevensbrongestuurde eenheidstest omvat de volgende stappen:
Maak een gegevensbron die de waarden bevat die u in de testmethode gebruikt. De gegevensbron kan elk type zijn dat is geregistreerd op de computer waarop de test wordt uitgevoerd.
Voeg een openbare
TestContext
eigenschap van het type TestContext toe aan de testklasse.Een eenheidstestmethode maken
Voeg er een DataSourceAttribute-kenmerk aan toe.
Gebruik de eigenschap DataRow indexeerfunctie om de waarden op te halen die u in een test gebruikt.
Een gegevensbron maken
Als u de methode AddIntegers
wilt testen, maakt u een gegevensbron die een bereik met waarden voor de parameters opgeeft en de som die u verwacht te retourneren. In dit voorbeeld maken we een Sql Compact-database met de naam MathsData
en een tabel met de naam AddIntegersData
die de volgende kolomnamen en -waarden bevat
FirstNumber | TweedeNummer | Som |
---|---|---|
0 | 1 | 1 |
1 | 1 | 2 |
2 | -3 | -1 |
Een TestContext toevoegen aan de testklasse
Het testframework voor eenheden maakt een TestContext
object voor het opslaan van de gegevensbrongegevens voor een gegevensgestuurde test. Het framework stelt dit object vervolgens in als de waarde van de eigenschap TestContext
die u maakt.
public TestContext TestContext { get; set; }
In uw testmethode opent u de gegevens via de DataRow
-indexeereigenschap van de TestContext
.
Notitie
.NET Core biedt geen ondersteuning voor het kenmerk DataSource. Als u op deze manier toegang probeert te krijgen tot testgegevens in een .NET Core-, UWP- of WinUI-eenheidstestproject, ziet u een fout die lijkt op 'TestContext' geen definitie bevat voor 'DataRow' en geen toegankelijke extensiemethode 'DataRow' die een eerste argument van het type TestContext accepteert (ontbreekt u een using-instructie of een assemblyverwijzing?)".
De testmethode schrijven
De testmethode voor AddIntegers
is redelijk eenvoudig. Roep voor elke rij in de gegevensbron AddIntegers
aan met de FirstNumber en SecondNumber kolomwaarden als parameters en controleer de retourwaarde op basis van Som kolomwaarde:
[TestMethod]
[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0; Data Source=C:\Data\MathsData.sdf;", "Numbers")]
public void AddIntegers_FromDataSourceTest()
{
var target = new Maths();
// Access the data
int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);
int y = Convert.ToInt32(TestContext.DataRow["SecondNumber"]);
int expected = Convert.ToInt32(TestContext.DataRow["Sum"]);
int actual = target.AddIntegers(x, y);
Assert.AreEqual(expected, actual,
"x:<{0}> y:<{1}>",
new object[] {x, y});
}
De DataSourceAttribute opgeven
Het kenmerk DataSource
geeft de verbindingsreeks op voor de gegevensbron en de naam van de tabel die u in de testmethode gebruikt. De exacte informatie in de verbindingsreeks verschilt, afhankelijk van het type gegevensbron dat u gebruikt. In dit voorbeeld hebben we een SqlServerCe-database gebruikt.
[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0;Data Source=C:\Data\MathsData.sdf", "AddIntegersData")]
Voorzichtigheid
De verbindingsreeks kan gevoelige gegevens bevatten (bijvoorbeeld een wachtwoord). De verbindingsreeks wordt opgeslagen in tekst zonder opmaak in broncode en in de gecompileerde assembly. Beperk de toegang tot de broncode en assembly om deze gevoelige informatie te beveiligen.
Het kenmerk DataSource heeft drie constructors.
[DataSource(dataSourceSettingName)]
Een constructor met één parameter maakt gebruik van verbindingsgegevens die zijn opgeslagen in het app.config-bestand voor de oplossing. De dataSourceSettingsName is de naam van het XML-element in het configuratiebestand waarmee de verbindingsgegevens worden opgegeven.
Met behulp van een app.config-bestand kunt u de locatie van de gegevensbron wijzigen zonder dat u wijzigingen aanbrengt in de eenheidstest zelf. Zie walkthrough voor informatie over het maken en gebruiken van een app.config-bestand: Een configuratiebestand gebruiken om een gegevensbron te definiëren
[DataSource(connectionString, tableName)]
De DataSource
constructor met twee parameters geeft de verbindingsreeks voor de gegevensbron en de naam van de tabel die de gegevens voor de testmethode bevat.
De verbindingsreeksen zijn afhankelijk van het type gegevensbron, maar moet een providerelement bevatten dat de invariante naam van de gegevensprovider aangeeft.
[DataSource(
dataProvider,
connectionString,
tableName,
dataAccessMethod
)]
TestContext.DataRow gebruiken om toegang te krijgen tot de gegevens
Gebruik de indexeerfunctie voor AddIntegersData
om toegang te krijgen tot de gegevens in de TestContext.DataRow
tabel.
DataRow
is een DataRow-object, dus haal kolomwaarden op basis van index- of kolomnamen op. Omdat de waarden worden geretourneerd als objecten, converteert u deze naar het juiste type:
int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);
De test uitvoeren en resultaten weergeven
Wanneer u klaar bent met het schrijven van een testmethode, bouwt u het testproject. De testmethode wordt weergegeven in Test Explorer- in de groep Geen tests uitvoeren. Terwijl u uw tests uitvoert, schrijft en opnieuw uitvoert, worden in Test Explorer de resultaten weergegeven in groepen Mislukte tests, geslaagde testsen Niet-uitgevoerde tests. U kunt Alle uitvoeren kiezen om al uw tests uit te voeren of Uitvoeren kiezen om een subset met tests te kiezen die u wilt uitvoeren.
De testresultatenbalk boven aan Test Explorer- wordt geanimeerd terwijl de test wordt uitgevoerd. Aan het einde van de testuitvoering is de balk groen als alle tests zijn geslaagd of rood als een van de tests is mislukt. Een samenvatting van de testuitvoering wordt weergegeven in het detailvenster onder aan het Test Explorer-venster. Selecteer een test om de details van die test in het onderste deelvenster weer te geven.
Notitie
Er is een resultaat voor elke rij met gegevens en ook één samenvattingsresultaat. Als de test voor elke rij met gegevens is geslaagd, wordt het overzicht weergegeven als Geslaagd. Als de test is mislukt in een gegevenrij, wordt de samenvatting weergegeven als Mislukt.
Als u een van de AddIntegers_FromDataRowTest
, AddIntegers_FromDynamicDataTest
of AddIntegers_FromDataSourceTest
in ons voorbeeld hebt uitgevoerd, wordt de resultatenbalk rood en wordt de testmethode verplaatst naar de Mislukte tests. Een gegevensgestuurde test mislukt als een van de itereerde methoden van de gegevensbron mislukt. Wanneer u een mislukte gegevensgestuurde test kiest in het venster Test Explorer, worden in het detailvenster de resultaten weergegeven van elke iteratie die wordt geïdentificeerd door de gegevensrijindex. In ons voorbeeld blijkt dat het algoritme AddIntegers
negatieve waarden niet correct verwerkt.
Wanneer de testmethode wordt gecorrigeerd en de test opnieuw wordt uitgevoerd, wordt de resultatenbalk groen en wordt de testmethode verplaatst naar de groep Geslaagde test.
Verwante inhoud
- Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute
- Microsoft.VisualStudio.TestTools.UnitTesting.TestContext
- Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DataRow
- Microsoft.VisualStudio.TestTools.UnitTesting.Assert
- eenheid uw code testen
- Eenheidstests uitvoeren met Test Explorer
- eenheidstests schrijven voor .NET met het Microsoft Unit Test Framework