Udostępnij za pośrednictwem


Przewodnik: programowanie oparte na testach przy użyciu Eksploratora testów

Twórz testy jednostkowe, aby pomóc w utrzymaniu prawidłowego działania kodu podczas wprowadzania przyrostowych zmian w kodzie. Istnieje kilka struktur, których można użyć do pisania testów jednostkowych, w tym niektórych opracowanych przez inne firmy. Niektóre struktury testowe są przeznaczone do testowania w różnych językach lub platformach. Eksplorator testów udostępnia jeden interfejs dla testów jednostkowych w dowolnej z tych platform. Aby uzyskać więcej informacji na temat Eksploratora testów, zobacz Uruchamianie testów jednostkowych za pomocą Eksploratora testów i Eksploratora testów — często zadawane pytania.

W tym przewodniku pokazano, jak opracować przetestowaną metodę w języku C# przy użyciu programu Microsoft Test Framework (MSTest). Można go łatwo dostosować do innych języków lub innych struktur testowych, takich jak NUnit. Aby uzyskać więcej informacji, zobacz Instalowanie zewnętrznych frameworków do testów jednostkowych.

Tworzenie testu i generowanie kodu

  1. Utwórz projekt biblioteki klas języka C# dla platformy .NET lub .NET Standard. Ten projekt będzie zawierać kod, który chcemy przetestować. Nadaj projektowi nazwę MyMath.

  2. W tym samym rozwiązaniu dodaj nowy projekt testowy MSTest dla platformy .NET.

    W programie Visual Studio 2019 w wersji 16.9 nazwa szablonu projektu MSTest to Unit Test Project.

    Nadaj projektowi testowe nazwę MathTests.

    Nowy kod i projekty testowe

    Nowy kod i projekty testowe

  3. W projekcie testowym napisz prostą metodę testową, która weryfikuje wynik uzyskany dla określonego danych wejściowych. Dodaj następujący kod do klasy Test1 lub UnitTest1.

    [TestMethod]
    public void BasicRooterTest()
    {
      // Create an instance to test:
      Rooter rooter = new Rooter();
      // Define a test input and output value:
      double expectedResult = 2.0;
      double input = expectedResult * expectedResult;
      // Run the method under test:
      double actualResult = rooter.SquareRoot(input);
      // Verify the result:
      Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 100);
    }
    
  4. Generowanie typu na podstawie kodu testowego.

    1. Umieść kursor na Rooter, a następnie otwórz menu żarówki.

      Wybierz pozycję Generuj nowy typ.

      Szybkie generowanie nowego typu akcji

      Wybierz pozycję Wygeneruj typ "Rooter">Wygeneruj nowy typ.

      Szybkie generowanie nowego typu akcji

    2. W oknie dialogowym Generowanie typu ustaw wartość Project na MyMath, projekt biblioteki klas, a następnie wybierz przycisk OK.

      Okno dialogowe generowania typu w programie Visual Studio 2019

      Okno dialogowe generowania typu w programie Visual Studio 2019

  5. Wygeneruj metodę na podstawie kodu testowego. Umieść kursor na SquareRoot, a następnie z menu żarówki wybierz pozycję Generuj metodę "SquareRoot" lub Generuj metodę "Rooter.SquareRoot".

  6. Uruchom test jednostkowy.

    1. Otwórz Eksploratora testów.

      Aby otworzyć Eksploratora testów z menu Test , wybierz pozycję Eksplorator testów.

      Aby otworzyć Eksploratora testów z menu Test, wybierz pozycję Windows>Eksplorator testów.

    2. W Eksploratorze testów wybierz przycisk Uruchom wszystko , aby uruchomić test.

    Rozwiązanie się kompiluje, a testy są uruchamiane i kończą się niepowodzeniem.

  7. Wybierz nazwę testu.

    Szczegóły testu są wyświetlane w okienku Podsumowanie szczegółów testu .

    Podsumowanie szczegółów testu w Eksploratorze testów

    Podsumowanie szczegółów testu w Eksploratorze testów

  8. Wybierz górny link w sekcji Ślad stosu, aby przejść do lokalizacji, w której test zakończył się niepowodzeniem.

W tym momencie utworzono test i wycinkę, którą można zmodyfikować, tak aby test przebiegł pomyślnie.

Weryfikowanie zmiany kodu

  1. W pliku Class1.cs udoskonal kod SquareRoot:

    public double SquareRoot(double input)
    {
        return input / 2;
    }
    
  2. W Eksploratorze testów wybierz pozycję Uruchom wszystko.

    Rozwiązanie kompiluje się, a test zostanie uruchomiony i zakończy się pomyślnie.

    Eksplorator testów przedstawiający test zaliczony

    Eksplorator testów przedstawiający test zaliczony

Rozszerzanie zakresu danych wejściowych

Aby zwiększyć pewność, że kod działa we wszystkich przypadkach, dodaj testy, które próbują uzyskać szerszy zakres wartości wejściowych.

Wskazówka

Unikaj zmiany istniejących testów, które przeszły. Zamiast tego dodaj nowe testy. Zmień istniejące testy tylko wtedy, gdy zmienią się wymagania użytkownika. Te zasady pomagają upewnić się, że nie utracisz istniejących funkcji podczas pracy nad rozszerzeniem kodu.

  1. W klasie testowej dodaj następujący test, który testuje zakres wartości wejściowych:

    [TestMethod]
    public void RooterValueRange()
    {
        // Create an instance to test.
        Rooter rooter = new Rooter();
    
        // Try a range of values.
        for (double expected = 1e-8; expected < 1e+8; expected *= 3.2)
        {
            RooterOneValue(rooter, expected);
        }
    }
    
    private void RooterOneValue(Rooter rooter, double expectedResult)
    {
        double input = expectedResult * expectedResult;
        double actualResult = rooter.SquareRoot(input);
        Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 1000);
    }
    
  2. W Eksploratorze testów wybierz pozycję Uruchom wszystko.

    Nowy test kończy się niepowodzeniem (chociaż pierwszy test nadal przechodzi). Aby znaleźć punkt awarii, wybierz test zakończony niepowodzeniem, a następnie przyjrzyj się szczegółom w okienku Podsumowanie szczegółów testu .

  3. Sprawdź metodę testową, aby zobaczyć, co może być złe. Zmień kod SquareRoot w następujący sposób:

    public double SquareRoot(double input)
    {
      double result = input;
      double previousResult = -input;
      while (Math.Abs(previousResult - result) > result / 1000)
      {
        previousResult = result;
        result = result - (result * result - input) / (2 * result);
      }
      return result;
    }
    
  4. W Eksploratorze testów wybierz pozycję Uruchom wszystko.

    Oba testy zostały zaliczone.

Dodawanie testów dla wyjątkowych przypadków

  1. Dodaj nowy test dla ujemnych danych wejściowych:

    [TestMethod]
    public void RooterTestNegativeInput()
    {
        Rooter rooter = new Rooter();
        Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1));
    }
    
  2. W Eksploratorze testów wybierz pozycję Uruchom wszystko.

    Nowy test kończy się niepowodzeniem.

    Jeśli testowana metoda powoduje zapętlenie, wybierz Anuluj na pasku narzędzi Eksploratora testów. Test przerywa działanie i kończy się niepowodzeniem.

  3. Napraw SquareRoot kod, dodając następującą if instrukcję na początku metody:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
        ...
    
  4. W Eksploratorze testów wybierz pozycję Uruchom wszystko.

    Wszystkie testy kończą się powodzeniem.

Refaktoryzacja kodu testowego

Refaktoryzuj kod, ale nie zmieniaj testów.

Wskazówka

Refaktoryzacja to zmiana, która ma na celu lepsze lub łatwiejsze zrozumienie kodu. Nie jest ona przeznaczona do zmiany zachowania kodu, dlatego testy nie są zmieniane.

Zalecamy wykonanie kroków refaktoryzacji niezależnie od kroków rozszerzających funkcjonalność. Utrzymywanie testów bez zmian zapewnia pewność, że podczas refaktoryzacji nie zostały przypadkowo wprowadzone usterki.

  1. Zmień wiersz, który jest obliczany result w metodzie SquareRoot w następujący sposób:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
    
        double result = input;
        double previousResult = -input;
        while (Math.Abs(previousResult - result) > result / 1000)
        {
            previousResult = result;
            result = (result + input / result) / 2;
            //was: result = result - (result * result - input) / (2*result);
        }
        return result;
    }
    
  2. Wybierz pozycję Uruchom wszystko i sprawdź, czy wszystkie testy nadal przechodzą pomyślnie.

    Eksplorator testów pokazujący 3 testy zakończone sukcesem

    Eksplorator testów pokazujący 3 testy zakończone sukcesem