Udostępnij za pośrednictwem


Tworzenie testu jednostkowego opartego na danych

Możesz użyć struktury testów jednostkowych firmy Microsoft (MSTest) dla kodu zarządzanego, aby skonfigurować metodę testu jednostkowego w celu pobrania wartości ze źródła danych. Metoda jest uruchamiana kolejno dla każdego wiersza w źródle danych, co ułatwia testowanie różnych danych wejściowych przy użyciu jednej metody.

Test jednostkowy oparty na danych może używać dowolnego z następujących typów:

  • wbudowane dane przy użyciu atrybutu DataRow
  • dane składowe przy użyciu atrybutu DynamicData
  • od znanego dostawcy źródła przy użyciu atrybutu DataSource

Metoda testowa

Załóżmy na przykład, że masz:

  1. Rozwiązanie o nazwie MyBank , które akceptuje i przetwarza transakcje dla różnych typów kont.

  2. Projekt o MyBank nazwie BankDb , który zarządza transakcjami dla kont.

  3. Klasa wywoływana Maths w projekcie BankDb , która wykonuje funkcje matematyczne, aby upewnić się, że każda transakcja jest korzystna dla banku.

  4. Projekt testu jednostkowego wywoływany BankDbTests w celu przetestowania zachowania BankDb składnika.

  5. Klasa testu jednostkowego wywoływana MathsTests w celu zweryfikowania Maths zachowania klasy.

Przetestujemy metodę, która Maths dodaje dwie liczby całkowite przy użyciu pętli:

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

    return sum;
}

Testowa metoda testu

Wbudowany test oparty na danych

W przypadku testów wbudowanych narzędzie MSTest używa DataRow metody do określania wartości używanych przez test oparty na danych. Test w tym przykładzie jest uruchamiany kolejno dla każdego wiersza danych.

[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 oparty na danych składowych

Narzędzie MSTest używa DynamicData atrybutu do określenia nazwy, rodzaju (właściwości, wartości domyślnej lub metody) i definiowania typu (domyślnie jest używany bieżący typ) elementu członkowskiego, który zapewni dane używane przez test oparty na danych.

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

Można również zastąpić domyślną wygenerowaną nazwę wyświetlaną przy użyciu DynamicDataDisplayName właściwości atrybutu DynamicData . Sygnatura metody nazwy wyświetlanej musi być public static string i zaakceptować dwa parametry, pierwszy typ MethodInfo i drugi typu 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 oparty na danych dostawcy źródła

Tworzenie testu jednostkowego opartego na źródle danych obejmuje następujące kroki:

  1. Utwórz źródło danych zawierające wartości używane w metodzie testowej. Źródło danych może być dowolnym typem zarejestrowanym na maszynie, na których jest uruchamiany test.

  2. Dodaj właściwość publiczną TestContext typu TestContext do klasy testowej.

  3. Tworzenie metody testu jednostkowego

  4. DataSourceAttribute Dodaj do niego atrybut.

  5. Użyj właściwości indeksatora DataRow , aby pobrać wartości używane w teście.

Utwórz źródło danych

Aby przetestować metodę AddIntegers , utwórz źródło danych, które określa zakres wartości parametrów i sumę, która ma zostać zwrócona. W tym przykładzie utworzymy bazę danych Sql Compact o nazwie i tabelę o nazwie MathsData AddIntegersData zawierającą następujące nazwy i wartości kolumn

Numer pierwszy Numer drugiego Sum
0 1 1
1 1 2
2 –3 -1

Dodawanie obiektu TestContext do klasy testowej

Struktura testów jednostkowych tworzy TestContext obiekt do przechowywania informacji o źródle danych na potrzeby testu opartego na danych. Następnie platforma ustawia ten obiekt jako wartość tworzonej TestContext właściwości.

public TestContext TestContext { get; set; }

W metodzie testowej uzyskujesz dostęp do danych za pośrednictwem DataRow właściwości indeksatora klasy TestContext.

Uwaga

Platforma .NET Core nie obsługuje atrybutu DataSource . Jeśli spróbujesz uzyskać dostęp do danych testowych w ten sposób w projekcie testów jednostkowych platformy .NET Core, platformy UWP lub WinUI, zostanie wyświetlony błąd podobny do "TestContext" nie zawiera definicji elementu "DataRow" i nie można odnaleźć dostępnej metody rozszerzenia "DataRow" akceptującej pierwszy argument typu "TestContext" (czy brakuje dyrektywy using lub odwołania do zestawu?).

Pisanie metody testowej

Metoda testowa dla AddIntegers metody jest dość prosta. Dla każdego wiersza w źródle danych wywołaj wartości AddIntegers kolumn FirstNumber i SecondNumber jako parametry, a następnie sprawdź wartość zwracaną względem wartości kolumny 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});
}

Określanie elementu DataSourceAttribute

Atrybut DataSource określa parametry połączenia dla źródła danych i nazwę tabeli używanej w metodzie testowej. Dokładne informacje w parametry połączenia różnią się w zależności od rodzaju używanego źródła danych. W tym przykładzie użyliśmy bazy danych SqlServerCe.

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

Uwaga

Parametry połączenia może zawierać poufne dane (na przykład hasło). Parametry połączenia jest przechowywany w postaci zwykłego tekstu w kodzie źródłowym i w skompilowanym zestawie. Ogranicz dostęp do kodu źródłowego i zestawu, aby chronić te poufne informacje.

Atrybut DataSource ma trzy konstruktory.

[DataSource(dataSourceSettingName)]

Konstruktor z jednym parametrem używa informacji o połączeniu przechowywanych w pliku app.config rozwiązania. DataSourceSettingsName to nazwa elementu Xml w pliku konfiguracji, który określa informacje o połączeniu.

Użycie pliku app.config umożliwia zmianę lokalizacji źródła danych bez wprowadzania zmian w samym teście jednostkowym. Aby uzyskać informacje o sposobie tworzenia i używania pliku app.config , zobacz Przewodnik: używanie pliku konfiguracji do definiowania źródła danych

[DataSource(connectionString, tableName)]

Konstruktor z dwoma DataSource parametrami określa parametry połączenia dla źródła danych i nazwę tabeli zawierającej dane dla metody testowej.

Parametry połączenia zależy od typu źródła danych, ale powinien zawierać element Dostawcy, który określa niezmienną nazwę dostawcy danych.

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

Uzyskiwanie dostępu do danych przy użyciu pliku TestContext.DataRow

Aby uzyskać dostęp do danych w AddIntegersData tabeli, użyj indeksatora TestContext.DataRow . DataRow jest obiektem DataRow , więc pobieraj wartości kolumn według nazw indeksów lub kolumn. Ponieważ wartości są zwracane jako obiekty, przekonwertuj je na odpowiedni typ:

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

Uruchamianie testu i wyświetlanie wyników

Po zakończeniu pisania metody testowej skompiluj projekt testowy. Metoda testowa jest wyświetlana w Eksploratorze testów w grupie Nie uruchamiaj testów . Podczas uruchamiania, zapisywania i ponownego uruchamiania testów Eksplorator testów wyświetla wyniki w grupach testów niepowodzeniem, testów z powodzeniem i nieuruchomionych testów. Możesz wybrać pozycję Uruchom wszystko , aby uruchomić wszystkie testy, lub wybrać pozycję Uruchom , aby wybrać podzestaw testów do uruchomienia.

Pasek wyników testu w górnej części Eksploratora testów jest animowany podczas uruchamiania testu. Na końcu przebiegu testu pasek będzie zielony, jeśli wszystkie testy przeszły lub czerwony, jeśli którykolwiek z testów zakończył się niepowodzeniem. Podsumowanie przebiegu testu jest wyświetlane w okienku szczegółów w dolnej części okna Eksplorator testów. Wybierz test, aby wyświetlić szczegóły tego testu w dolnym okienku.

Uwaga

Istnieje wynik dla każdego wiersza danych, a także jeden wynik podsumowania. Jeśli test zakończył się powodzeniem w każdym wierszu danych, przebieg podsumowania jest wyświetlany jako Przekazany. Jeśli test zakończył się niepowodzeniem w dowolnym wierszu danych, przebieg podsumowania jest wyświetlany jako Niepowodzenie.

Jeśli w naszym przykładzie AddIntegers_FromDataRowTesturuchomiono dowolną metodę lub AddIntegers_FromDataSourceTest , AddIntegers_FromDynamicDataTest pasek wyników zmieni kolor na czerwony, a metoda testowa zostanie przeniesiona do testów niepowodzeniem. Test oparty na danych kończy się niepowodzeniem, jeśli którakolwiek z iterated metod ze źródła danych zakończy się niepowodzeniem. Po wybraniu testu opartego na danych, który zakończył się niepowodzeniem w oknie Eksplorator testów, w okienku szczegółów zostaną wyświetlone wyniki każdej iteracji identyfikowanej przez indeks wiersza danych. W naszym przykładzie wydaje się, że AddIntegers algorytm nie obsługuje poprawnie wartości ujemnych.

Gdy metoda w ramach testu zostanie poprawiona i ponowne uruchomienie testu, pasek wyników zmieni kolor na zielony, a metoda testowa zostanie przeniesiona do grupy Test z powodzeniem.