Udostępnij za pośrednictwem


Generowanie testu

W tradycyjnych testach jednostkowych test składa się z kilku elementów:

Poniżej przedstawiono przykładową strukturę testu:

[Test]
void MyTest() {
    // data
    ArrayList a = new ArrayList();

    // method sequence
    a.Add(5);

    // assertions
    Assert.IsTrue(a.Count==1);
    Assert.AreEqual(a[0], 5);
}

Narzędzie IntelliTest może często automatycznie określać odpowiednie wartości argumentów dla bardziej ogólnych sparametryzowanych testów jednostkowych, które zapewniają sekwencję wywołań metod i asercji.

Generatory testów

Narzędzie IntelliTest generuje przypadki testowe, wybierając sekwencję metod implementacji do wykonania, a następnie generując dane wejściowe dla metod podczas sprawdzania asercji na podstawie danych pochodnych.

Sparametryzowany test jednostkowy bezpośrednio określa sekwencję wywołań metod w jej treści.

Gdy narzędzie IntelliTest musi konstruować obiekty, wywołania konstruktorów i metod fabrycznych zostaną automatycznie dodane do sekwencji zgodnie z potrzebami.

Sparametryzowane testy jednostkowe

Sparametryzowane testy jednostkowe to testy, które przyjmują parametry. W przeciwieństwie do tradycyjnych testów jednostkowych, które są zwykle zamkniętymi metodami, puts przyjmują dowolny zestaw parametrów. Czy to proste? Tak — z tego miejsca narzędzie IntelliTest spróbuje wygenerować (minimalny) zestaw danych wejściowych , które w pełni obejmują kod osiągalny z testu.

PuTs są definiowane przy użyciu atrybutu niestandardowego PexMethod w podobny sposób do MSTest (lub NUnit, xUnit). PuTs to metody wystąpień grupowane logicznie w klasach oznaczonych PexClass. W poniższym przykładzie pokazano prostą aplikację PUT przechowywaną w klasie MyPexTest :

[PexMethod]
void ReplaceFirstChar(string target, char c) {

    string result = StringHelper.ReplaceFirstChar(target, c);

    Assert.AreEqual(result[0], c);
}

gdzie ReplaceFirstChar to metoda, która zastępuje pierwszy znak ciągu:

class StringHelper {
    static string ReplaceFirstChar(string target, char c) {
        if (target == null) throw new ArgumentNullException();
        if (target.Length == 0) throw new ArgumentOutOfRangeException();
        return c + target.Substring(1);
    }
}

W tym teście narzędzie IntelliTest może automatycznie generować dane wejściowe dla put, który obejmuje wiele ścieżek wykonywania przetestowanego kodu. Każde dane wejściowe obejmujące inną ścieżkę wykonywania jest "serializowane" jako test jednostkowy:

[TestMethod, ExpectedException(typeof(ArgumentNullException))]
void ReplaceFirstChar0() {
    this.ReplaceFirstChar(null, 0);
}
...
[TestMethod]
void ReplaceFirstChar10() {
    this.ReplaceFirstChar("a", 'c');
}

Ogólne sparametryzowane testy jednostkowe

Sparametryzowane testy jednostkowe mogą być metodami ogólnymi. W takim przypadku użytkownik musi określić typy używane do tworzenia wystąpienia metody przy użyciu metody PexGenericArguments.

[PexClass]
public partial class ListTest {
    [PexMethod]
    [PexGenericArguments(typeof(int))]
    [PexGenericArguments(typeof(object))]
    public void AddItem<T>(List<T> list, T value)
    { ... }
}

Zezwalanie na wyjątki

Funkcja IntelliTest udostępnia wiele atrybutów weryfikacji, które ułatwiają klasyfikację wyjątków w oczekiwanych wyjątkach i nieoczekiwanych wyjątkach.

Oczekiwane wyjątki generują negatywne przypadki testowe z odpowiednią adnotacją, taką jak ExpectedException(typeof(xxx))), podczas gdy nieoczekiwane wyjątki generują przypadki testowe zakończone niepowodzeniem.

[PexMethod, PexAllowedException(typeof(ArgumentNullException))]
void SomeTest() {...}

Moduły sprawdzania poprawności to:

Testowanie typów wewnętrznych

Narzędzie IntelliTest może "testować" typy wewnętrzne, o ile może je zobaczyć. Aby narzędzie IntelliTest wyświetlało typy, następujący atrybut jest dodawany do projektu produktu lub projektu testowego przez kreatorów intelliTest programu Visual Studio:

[assembly: InternalsVisibleTo("Microsoft.Pex, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]

Założenia i potwierdzenia

Użytkownicy mogą używać założeń i asercji do wyrażania warunków wstępnych (założeń) i pokondycji (asercji) dotyczących ich testów. Gdy narzędzie IntelliTest generuje zestaw wartości parametrów i "eksploruje" kod, może to naruszać założenie testu. W takim przypadku nie wygeneruje testu dla tej ścieżki, ale w trybie dyskretnym go zignoruje.

Asercji to dobrze znana koncepcja w regularnych strukturach testów jednostkowych, więc narzędzie IntelliTest już "rozumie" wbudowane klasy Assert udostępniane przez każdą obsługiwaną platformę testową. Jednak większość struktur nie udostępnia klasy Przyjmij. W takim przypadku intelliTest udostępnia klasę PexAssume . Jeśli nie chcesz używać istniejącej platformy testowej, narzędzie IntelliTest ma również klasę PexAssert .

[PexMethod]
public void Test1(object o) {
    // precondition: o should not be null
    PexAssume.IsNotNull(o);

    ...
}

W szczególności założenie o wartości innej niż null może być zakodowane jako atrybut niestandardowy:

[PexMethod]
public void Test2([PexAssumeNotNull] object o)
// precondition: o should not be null
{
   ...
}

Warunek wstępny

Warunek wstępny metody wyraża warunki, w których metoda powiedzie się.

Zazwyczaj warunek wstępny jest wymuszany przez sprawdzenie parametrów i stanu obiektu oraz zgłoszenie wyjątku ArgumentException lub InvalidOperationException, jeśli zostanie naruszone.

W środowisku IntelliTest warunek wstępny sparametryzowanego testu jednostkowego jest wyrażany za pomocą narzędzia PexAssume.

Warunek końcowy

Po zakończeniu metody wyraża warunki, które powinny być przechowywane podczas i po wykonaniu metody, przy założeniu, że jej warunki wstępne były początkowo prawidłowe.

Zwykle po zakończeniu jest wymuszane przez wywołania metod Assert .

Dzięki funkcji IntelliTest po zakończeniu sparametryzowanego testu jednostkowego wyrażany jest elementem PexAssert.

Niepowodzenia testów

Kiedy wygenerowany przypadek testowy kończy się niepowodzeniem?

  1. Jeśli nie zakończy się on w ramach skonfigurowanych granic ścieżki, jest uważany za błąd, chyba że ustawiono opcję TestExcludePathBoundsExceeded

  2. Jeśli test zgłosi wyjątek PexAssumeFailedException, powiedzie się. Jednak zwykle jest on filtrowany, chyba że parametr TestEmissionFilter jest ustawiony na wartość Wszystkie

  3. Jeśli test narusza asercję, na przykład zgłaszając wyjątek naruszenia asercji w strukturze testów jednostkowych, kończy się niepowodzeniem

Jeśli żaden z powyższych nie generuje decyzji, test powiedzie się, jeśli i tylko wtedy, gdy nie zgłosi wyjątku. Naruszenia asercji są traktowane tak samo jak wyjątki.

Konfigurowanie i usuwanie

W ramach integracji z platformami testowymi narzędzie IntelliTest obsługuje wykrywanie i uruchamianie metod instalacji i usuwania.

Przykład

using Microsoft.Pex.Framework;
using NUnit.Framework;

namespace MyTests
{
    [PexClass]
    [TestFixture]
    public partial class MyTestClass
    {
        [SetUp]
        public void Init()
        {
            // monitored
        }

        [PexMethod]
        public void MyTest(int i)
        {
        }

        [TearDown]
        public void Dispose()
        {
            // monitored
        }
    }
}

Dalsze informacje

Chcesz przesłać opinię?

Opublikuj swoje pomysły i sugestie funkcji w społeczności deweloperów.