Sdílet prostřednictvím


Vytvořte datově řízený jednotkový test

Pomocí architektury Microsoft Unit Test Framework (MSTest) pro spravovaný kód můžete nastavit metodu jednotkového testu pro načtení hodnot ze zdroje dat. Metoda se spouští postupně pro každý řádek ve zdroji dat, což usnadňuje testování různých vstupů pomocí jedné metody.

Test jednotek řízený daty může použít libovolný z následujících typů:

  • vložená data pomocí atributu DataRow
  • data členů pomocí atributu DynamicData
  • od nějakého známého poskytovatele dat pomocí atributu DataSource

Metoda pod testem

Předpokládejme například, že máte:

  1. Řešení označované jako MyBank, které přijímá a zpracovává transakce pro různé typy účtů.

  2. Projekt v MyBank označovaný jako BankDb, který spravuje transakce pro účty.

  3. Třída s názvem Maths v projektu BankDb, která provádí matematické funkce k zajištění, že jakákoli transakce je výhodné pro banku.

  4. Projekt testu jednotek, který se nazývá BankDbTests k otestování chování komponenty BankDb.

  5. Jednotková testovací třída s názvem MathsTests k ověření chování třídy Maths.

Metodu otestujeme v Maths, která pomocí smyčky přidá dvě celá čísla:

public int AddIntegers(int first, int second)
{
    int sum = first;
    for (int i = 0; i < second; i++)
    {
        sum += 1;
    }

    return sum;
}

Testovací metoda

Vložený test řízený daty

Pro vložené testy msTest používá DataRow k určení hodnot používaných testem řízeným daty. Test v tomto příkladu se postupně spustí pro každý řádek dat.

[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});
}

Test řízený daty členů

MSTest používá atribut DynamicData k určení názvu, typu a definování typu (ve výchozím nastavení se používá aktuální typ) člena, který poskytne data používaná testem řízeným daty.

Poznámka

Před MSTest 3.8 měl výčet DynamicDataSourceType dva členy, Property a Method. Výchozí hodnota byla Property. Počínaje MSTest 3.8 se do výčtu přidá nový člen AutoDetect a je výchozí hodnota. Takže už nemusíte zadávat DynamicDataSourceType.

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});
}

Pomocí vlastnosti DynamicDataDisplayName atributu DynamicData je také možné přepsat výchozí vygenerovaný zobrazovaný název. Podpis metody zobrazovaného názvu musí být public static string a musí přijímat dva parametry, první typ MethodInfo a druhý typ 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))]

Test řízený daty poskytovatele zdroje

Vytvoření testu jednotek řízeného zdrojem dat zahrnuje následující kroky:

  1. Vytvořte zdroj dat obsahující hodnoty, které používáte v testovací metodě. Zdrojem dat může být libovolný typ zaregistrovaný na počítači, který test spouští.

  2. Do testovací třídy přidejte veřejnou TestContext vlastnost typu TestContext.

  3. Vytvoření metody testování jednotek

  4. Přidejte do něj atribut DataSourceAttribute.

  5. Pomocí vlastnosti DataRow indexeru načtěte hodnoty, které používáte v testu.

Vytvoření zdroje dat

Pokud chcete otestovat AddIntegers metodu, vytvořte zdroj dat, který určuje rozsah hodnot parametrů a součet, který očekáváte, že se vrátí. V tomto příkladu vytvoříme databázi Sql Compact s názvem MathsData a tabulku s názvem AddIntegersData, která obsahuje následující názvy a hodnoty sloupců.

FirstNumber SecondNumber Součet
0 1 1
1 1 2
2 -3 -1

Přidání testContextu do testovací třídy

Architektura testování jednotek vytvoří objekt TestContext pro uložení informací o zdroji dat pro test řízený daty. Framework pak nastaví tento objekt jako hodnotu vlastnosti TestContext, kterou vytvoříte.

public TestContext TestContext { get; set; }

V testovací metodě přistupujete k datům prostřednictvím indexerové vlastnosti DataRow objektu TestContext.

Poznámka

.NET Core nepodporuje atribut DataSource. Pokud se pokusíte získat přístup k testovacím datům tímto způsobem v projektu testování jednotek .NET Core, UPW nebo WinUI, zobrazí se chyba podobná "TestContext" neobsahuje definici pro DataRow a nebyla nalezena žádná přístupná metoda rozšíření DataRow, která přijímá první argument typu TestContext (chybí direktiva using nebo odkaz na sestavení?).

Napsání testovací metody

Testovací metoda pro AddIntegers je poměrně jednoduchá. Pro každý řádek ve zdroji dat volejte AddIntegers s hodnotami ve sloupcích FirstNumber a SecondNumber jako parametry a ověřte, zda se návratová hodnota shoduje s hodnotou ve sloupci Sum.

[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});
}

Specifikujte atribut DataSourceAttribute

Atribut DataSource určuje připojovací řetězec pro zdroj dat a název tabulky, kterou používáte v testovací metodě. Přesné informace v připojovacím řetězci se liší v závislosti na tom, jaký druh zdroje dat používáte. V tomto příkladu jsme použili databázi SqlServerCe.

[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0;Data Source=C:\Data\MathsData.sdf", "AddIntegersData")]

Opatrnost

Připojovací řetězec může obsahovat citlivá data (například heslo). Připojovací řetězec je uložen v prostém textu ve zdrojovém kódu a v kompilovaném sestavení. Omezte přístup ke zdrojovému kódu a sestavení, abyste ochránili tyto citlivé informace.

Atribut DataSource má tři konstruktory.

[DataSource(dataSourceSettingName)]

Konstruktor s jedním parametrem používá informace o připojení uložené v souboru app.config pro řešení. dataSourceSettingsName je název elementu Xml v konfiguračním souboru, který určuje informace o připojení.

Použití souboru app.config umožňuje změnit umístění zdroje dat, aniž byste museli provádět změny samotného testu jednotek. Informace o tom, jak vytvořit a použít soubor app.config, najdete v tématu Návod: Definování zdroje dat pomocí konfiguračního souboru

[DataSource(connectionString, tableName)]

Konstruktor DataSource se dvěma parametry určuje připojovací řetězec pro zdroj dat a název tabulky, která obsahuje data pro testovací metodu.

Připojovací řetězce závisí na typu typu zdroje dat, ale měl by obsahovat prvek Provider, který určuje invariantní název zprostředkovatele dat.

[DataSource(
    dataProvider,
    connectionString,
    tableName,
    dataAccessMethod
    )]

Použití TestContext.DataRow pro přístup k datům

Pokud chcete získat přístup k datům v tabulce AddIntegersData, použijte indexer TestContext.DataRow. DataRow je objekt DataRow, takže načtěte hodnoty sloupců podle indexu nebo názvů sloupců. Vzhledem k tomu, že se hodnoty vrátí jako objekty, převeďte je na odpovídající typ:

int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);

Spuštění testu a zobrazení výsledků

Po dokončení psaní testovací metody sestavte testovací projekt. Testovací metoda se zobrazí v průzkumníku testů ve skupině Nespoušovat testy. Při spuštění, psaní a opětovném spuštění testů Průzkumníka testů zobrazí výsledky ve skupinách neúspěšných testů, úspěšné testya Nespustit testy. Pokud chcete spustit všechny testy, můžete zvolit Spustit všechny, nebo zvolit Spustit a zvolit podmnožinu testů, které se mají spustit.

Panel výsledků testů v horní části Průzkumníka testů je animovaný při spuštění testu. Na konci testovacího spuštění bude pruh zelený, pokud byly všechny testy úspěšné nebo červené, pokud některý z testů selhal. Souhrn testovacího běhu se zobrazí v podokně podrobností ve spodní části okna Průzkumníka testů. Výběrem testu zobrazíte podrobnosti testu v dolním podokně.

Poznámka

Pro každý řádek dat existuje výsledek a také jeden souhrnný výsledek. Pokud test prošel na každém řádku dat, zobrazí se souhrnné zobrazení jako Úspěšné. Pokud test na libovolném řádku dat selhal, zobrazí se souhrnný výsledek jako neúspěšné.

Pokud jste v našem příkladu spustili některou z metod AddIntegers_FromDataRowTest, AddIntegers_FromDynamicDataTest nebo AddIntegers_FromDataSourceTest, panel výsledků se změní na červenou a testovací metoda se přesune do neúspěšných testů. Test řízený daty selže, pokud selže některá z iterovaných metod ze zdroje dat. Když zvolíte neúspěšný test řízený daty v okně Průzkumníka testů, zobrazí se v podokně podrobností výsledky každé iterace identifikované indexem datového řádku. V našem příkladu se zdá, že algoritmus AddIntegers nezpracuje správně záporné hodnoty.

Podaří-li se opravit testovanou metodu a test je znovu spuštěn, panel výsledků se změní na zelenou a testovací metoda se přesune do skupiny Úspěšné testy.