Udostępnij za pośrednictwem


Generowanie danych wejściowych przy użyciu dynamicznego wykonywania symbolicznego

Narzędzie IntelliTest generuje dane wejściowe dla sparametryzowanych testów jednostkowych, analizując warunki gałęzi w programie. Dane wejściowe testowe są wybierane na podstawie tego, czy mogą wyzwalać nowe zachowania rozgałęziania programu. Analiza jest procesem przyrostowym. Uściśli predykat q: I -> {true, false} na formalnych parametrach Iwejściowych testu . q reprezentuje zestaw zachowań zaobserwowanych już przez narzędzie IntelliTest. Początkowo , q := falseponieważ nic nie zostało jeszcze zaobserwowane.

Kroki pętli to:

  1. Narzędzie IntelliTest określa dane wejściowei, takie jak q(i)=false użycie modułu rozwiązywania ograniczeń. W trakcie budowy dane wejściowe i przejdą ścieżkę wykonania, która nie jest wcześniej widoczna. Początkowo oznacza to, że i może to być dowolne dane wejściowe, ponieważ nie odnaleziono jeszcze żadnej ścieżki wykonywania.

  2. Narzędzie IntelliTest wykonuje test z wybranymi danymi wejściowymi ii monitoruje wykonywanie testu i testowany program.

  3. Podczas wykonywania program przyjmuje określoną ścieżkę, która jest określana przez wszystkie gałęzie warunkowe programu. Zestaw wszystkich warunków określających wykonanie jest nazywany warunkiem ścieżki zapisanym jako predykat p: I -> {true, false} formalnych parametrów wejściowych. Narzędzie IntelliTest oblicza reprezentację tego predykatu.

  4. Zestawy q := (q or p)IntelliTest . Innymi słowy, rejestruje fakt, że widział ścieżkę reprezentowaną przez pelement .

  5. Przejdź do kroku 1.

Narzędzie do rozwiązywania ograniczeń intelliTest może obsługiwać wartości wszystkich typów, które mogą występować w programach platformy .NET:

IntelliTest filtruje dane wejściowe naruszające określone założenia.

Oprócz natychmiastowych danych wejściowych (argumentów do sparametryzowanych testów jednostkowych) test może rysować dalsze wartości wejściowe z klasy statycznej PexChoose . Opcje określają również zachowanie sparametryzowanych makiety.

Narzędzie do rozwiązywania ograniczeń

Narzędzie IntelliTest używa modułu rozwiązywania ograniczeń w celu określenia odpowiednich wartości wejściowych testu i testowego programu.

Narzędzie IntelliTest używa modułu rozwiązywania ograniczeń Z3 .

Dynamiczne pokrycie kodu

Jako efekt uboczny monitorowania środowiska uruchomieniowego intelliTest zbiera dynamiczne dane pokrycia kodu. Jest to nazywane dynamicznym , ponieważ narzędzie IntelliTest wie tylko o kodzie, który został wykonany, dlatego nie może nadawać wartości bezwzględnych pokrycia w taki sam sposób, jak zwykle inne narzędzie pokrycia.

Na przykład gdy funkcja IntelliTest zgłasza pokrycie dynamiczne jako bloki podstawowe 5/10, oznacza to, że ujęto pięć bloków z dziesięciu, gdzie całkowita liczba bloków we wszystkich metodach, które zostały osiągnięte do tej pory przez analizę (w przeciwieństwie do wszystkich metod, które istnieją w zestawie testowanym) wynosi dziesięć. W dalszej części analizy, w miarę odnajdywanie bardziej osiągalnych metod, może wzrosnąć zarówno licznik (5 w tym przykładzie), jak i mianownik (10).

Wartości całkowite i zmiennoprzecinkowe

Moduł rozwiązywania ograniczeń intelliTest określa wartości danych wejściowych testowych typów pierwotnych, takich jak bajt, liczba zmiennoprzecinkowa i inne, aby wyzwolić różne ścieżki wykonywania dla testu i programu w ramach testu.

Obiekty

Narzędzie IntelliTest może tworzyć wystąpienia istniejących klas platformy .NET lub za pomocą narzędzia IntelliTest automatycznie tworzyć makiety obiektów implementujących określony interfejs i zachowywać się w różny sposób w zależności od użycia.

Tworzenie wystąpień istniejących klas

Jaki jest problem?

Narzędzie IntelliTest monitoruje wykonane instrukcje, gdy uruchamia test i program w ramach testu. W szczególności monitoruje cały dostęp do pól. Następnie używa modułu rozwiązywania ograniczeń do określania nowych danych wejściowych testowych, w tym obiektów i ich wartości pól, tak aby test i program w ramach testu działały w inny interesujący sposób.

Oznacza to, że narzędzie IntelliTest musi tworzyć obiekty niektórych typów i ustawiać ich wartości pól. Jeśli klasa jest widoczna i ma widoczny konstruktor domyślny, narzędzie IntelliTest może utworzyć wystąpienie klasy. Jeśli wszystkie pola klasy są widoczne, narzędzie IntelliTest może automatycznie ustawić pola.

Jeśli typ nie jest widoczny lub pola nie są widoczne, narzędzie IntelliTest potrzebuje pomocy w tworzeniu obiektów i dostarczaniu ich do interesujących stanów w celu osiągnięcia maksymalnego pokrycia kodu. Narzędzie IntelliTest może użyć odbicia w celu utworzenia i zainicjowania wystąpień w dowolny sposób, ale zwykle nie jest to pożądane, ponieważ może spowodować przełączenie obiektu do stanu, który nigdy nie może wystąpić podczas normalnego wykonywania programu. Zamiast tego narzędzie IntelliTest opiera się na wskazówkach od użytkownika.

Widoczność

Platforma .NET ma rozbudowany model widoczności: typy, metody, pola i inne elementy członkowskie mogą być prywatne, publiczne, wewnętrzne i inne.

Gdy narzędzie IntelliTest generuje testy, podejmie próbę wykonania tylko akcji (takich jak wywoływanie konstruktorów, metod i pól ustawień), które są legalne w odniesieniu do reguł widoczności platformy .NET z poziomu kontekstu wygenerowanych testów.

Reguły są następujące:

  • Widoczność wewnętrznych elementów członkowskich

    • IntelliTest zakłada, że wygenerowane testy będą miały dostęp do wewnętrznych elementów członkowskich, które były widoczne dla otaczającej klasy PexClass. Platforma .NET ma atrybut InternalsVisibleToAttribute , aby rozszerzyć widoczność elementów wewnętrznych na inne zestawy.
  • Widoczność prywatnych i rodzinnych (chronionych w języku C#) członków PexClass

    • Narzędzie IntelliTest zawsze umieszcza wygenerowane testy bezpośrednio w PexClass lub w podklasie. W związku z tym intelliTest zakłada, że może używać wszystkich widocznych członków rodziny (chronionych w języku C#).
    • Jeśli wygenerowane testy są umieszczane bezpośrednio w PexClass (zwykle przy użyciu klas częściowych), intelliTest zakłada, że może również używać wszystkich prywatnych elementów członkowskich PexClass.
  • Widoczność publicznych członków

Sparametryzowane makiety

Jak przetestować metodę, która ma parametr typu interfejsu? A może klasy nie zapieczętowanej? Narzędzie IntelliTest nie wie, które implementacje będą później używane w przypadku wywołania tej metody. I być może nawet nie ma rzeczywistej implementacji dostępnej w czasie testowania.

Konwencjonalną odpowiedzią jest użycie pozornych obiektów z wyraźnym zachowaniem.

Obiekt makiety implementuje interfejs (lub rozszerza klasę, która nie jest zapieczętowana). Nie reprezentuje on rzeczywistej implementacji, ale tylko skrót umożliwiający wykonywanie testów przy użyciu makiety obiektu. Jego zachowanie jest definiowane ręcznie w ramach każdego przypadku testowego, w którym jest używany. Istnieje wiele narzędzi, które ułatwiają definiowanie makiety obiektów i ich oczekiwanego zachowania, ale to zachowanie musi być nadal definiowane ręcznie.

Zamiast trwale zakodowanych wartości w obiektach makiety, narzędzie IntelliTest może wygenerować wartości. Podobnie jak w przypadku sparametryzowanego testowania jednostkowego, narzędzie IntelliTest umożliwia również sparametryzowane makiety.

Parametryzowane makiety mają dwa różne tryby wykonywania:

  • wybór: podczas eksplorowania kodu sparametryzowane makiety są źródłem dodatkowych danych wejściowych testów, a narzędzie IntelliTest spróbuje wybrać interesujące wartości
  • powtórzenie: podczas wykonywania wcześniej wygenerowanego testu sparametryzowane makiety zachowują się jak wycinki z zachowaniem (innymi słowy, wstępnie zdefiniowane zachowanie).

Użyj metody PexChoose , aby uzyskać wartości sparametryzowanych makiety.

Struktury

Rozumowanie intelliTest dotyczące wartości struktury jest podobne do sposobu, w jaki zajmuje się obiektami.

Tablice i ciągi

Narzędzie IntelliTest monitoruje wykonane instrukcje w miarę uruchamiania testu i testowanego programu. W szczególności obserwuje, kiedy program zależy od długości ciągu lub tablicy (oraz dolnej granicy i długości tablicy wielowymiarowej). Obserwuje również, jak program używa różnych elementów ciągu lub tablicy. Następnie używa modułu rozwiązywania ograniczeń, aby określić, które długości i wartości elementów mogą spowodować, że test i program testowy zachowują się w ciekawy sposób.

Narzędzie IntelliTest próbuje zminimalizować rozmiar tablic i ciągów wymaganych do wyzwolenia interesujących zachowań programu.

Uzyskiwanie dodatkowych danych wejściowych

Klasa statyczna PexChoose może służyć do uzyskiwania dodatkowych danych wejściowych do testu i może służyć do implementowania sparametryzowanych makiety.

Chcesz przesłać opinię?

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