2010-04-24 18 views
28

Tak, możliwe jest generowanie testów wartości brzegowych dla funkcji takich jak "Sum" lub "Podziel". Pex jest tutaj dobrym narzędziem.Czy narzędzie Pex (generowanie testów) jest naprawdę przydatne?

Ale częściej tworzymy testy zachowań biznesowych. Weźmy przykład z klasycznej książki tdd Becka:

[Test] 
public void ShouldRoundOnCreation() 
{ 
    Money money = new Money(20.678); 
    Assert.AreEqual(20.68,money.Amount); 
    Assert.AreEqual(2068,money.Cents); 
} 

Czy można wygenerować ten test? Nie :) 95% testów w moich projektach sprawdza logikę biznesową i nie można ich wygenerować.

Pex (szczególnie w połączeniu z Moles) może zapewnić 100% pokrycie kodu, ale wysoki wskaźnik pokrycia kodu zestawu testów nigdy nie wskazuje, że kod jest dobrze przetestowany - daje tylko fałszywe zaufanie, że wszystko jest testowane. To bardzo niebezpieczne.

Pytanie brzmi: czy Pex jest naprawdę przydatnym narzędziem?

Odpowiedz

28

Myślę, że mylisz się ze sposobem, w jaki należy używać Pex: zdecydowanie zalecamy użytkownikom pisanie asercji w sparametryzowanych testach jednostkowych.

Jeśli napiszesz twierdzenia, Pex będzie starał się je systematycznie unieważniać - stąd bierze się moc Pex: im więcej piszesz twierdzeń, tym więcej próbuje znaleźć dla ciebie błędów.

Jeśli użyjesz Pex, aby uzyskać pakiet testowy o wysokim zasięgu kodowym bez pisania asercji, otrzymasz tylko to, o co prosiłeś: pokrycie kodu i wyjątki gwarantowanego środowiska wykonawczego. Pex "only" próbuje pokryć gałęzie (1 asercja = 1 gałąź), jeśli nie ma żadnych gałęzi do zakrycia (brak potwierdzenia), nie będzie generować zakłócających przypadków testowych.

Ogólnie, asercje pisania w sparametryzowanych testach jednostkowych są trudniejsze do napisania, ponieważ ... cóż, są bardziej ogólne. Zacznijmy z zachowaniem zaokrągleń: tam jest na pewno związany na której pozwalasz zaokrąglania występuje, powinno to przełożyć naturalnie w parametryzowanego testów jednostkowych:

[PexMethod] 
public void RoundInBounds(double value) 
{ 
    var money = new Money(value); 
    // distance between value and amount should be at most 0.01/2 
    Assert.AreEqual(value, money.Amount, 0.005); 
} 

Istnieje również wiele wzorów, które mogą być używane do pisania te. Na przykład Twoja klasa "Pieniądze" jest prawdopodobnie idempotentna: jeśli dodasz wartość "Kwota" z powrotem do instancji pieniężnej, otrzymasz Kwotę z powrotem. Ten tłumaczyć elegancko do testów jednostkowych parametryzowanego:

[PexMethod] 
public void RoundIsIdempotent(double value) 
{ 
    var first = new Money(value).Amount; 
    var second = new Money(first).Amount; 
    Assert.AreEqual(first, second, 0.0001); 
} 

Należy również zauważyć, że testy jednostkowe parametryzowane zdecydowanie należą do świata TDD. Po prostu napisz najpierw sparametryzowany test jednostkowy, Pex znajdzie błąd, naprawi błąd, Pex znajdzie następny błąd, itd.

Czy to czyni Pex użytecznym narzędziem? Jesteś sędzią.

+0

Aby skrócić historię: 1) Pex nie może sam wygenerować wystarczających testów. 2) Może być używany do generowania parametrów dla testów parametrycznych. Drugi jest przydatny, uzgodniony. Ale co z regresją? Jeśli okaże się, że fragment kodu kończy się niepowodzeniem z parametrem = 123,43, prawdopodobnie chciałbym zapisać gdzieś ten przypadek prawdopodobnie w nunit sparametryzowanym teście. Czy kiedykolwiek próbowałeś mieszać testy sparametryzowane pex i nunit? –

+0

Z ciekawości, dlaczego używasz NUnit, kiedy używasz Visual Studio? – zumalifeguard

+2

Lubię NUnit więcej niż MSTest, ponieważ jest bardziej kompletny.Jednak naprawdę nie mam nic przeciwko MSTest. –

3

Jest kilka rzeczy przydatnych w Pex.

  1. Kod zasięgu. Odłóżmy Pex na chwilę. Ogólnie, zasięg 100% kodu nie musi oznaczać, że masz dobry zasięg kodu. Oznacza to po prostu, że kiedykolwiek wykonywana jest ścieżka, ale program ma przepływ danych, a testowanie kodujące inne, dodatkowe dane wejściowe daje najlepsze "pokrycie testowe", jeśli nie obejmuje kodu. Oto powtarzam twój punkt widzenia. 100% zasięgu kodu niekoniecznie jest dobre, ale możesz powiedzieć z całą pewnością, że pokrycie 25% kodu jest złe, więc w ten sposób zasięg kodu jest użyteczny. Kiedy masz niski zasięg kodu, wiesz na pewno, że masz niski zasięg testu.

    Podczas korzystania Pex, aby uzyskać 100% pokrycia kodu, to nie jest naprawdę pomaga uzyskać lepszy zasięg testowego per se, ale co to robi zrobić, to dać kiedykolwiek kawałek kodu produkcyjnego jakiś test, który może być używany debugger. W rzeczywistości, prezentacja Pex jako konferencji pokazuje zastosowanie Pex w tym właśnie celu. Programista powiedział: "Gee, spójrz na tę metodę w NHibernate. Chciałbym przejść przez to w debugerze, aby zobaczyć, co robi, ale jak mogę nawet wywołać tę metodę przez normalny" punkt wejścia firmy "do Nie wiedząc nic o bibliotece, nie możesz, więc on uruchomił Pex i był w stanie przejść przez kod z różnymi parametrami Ciekawe, Tak, użyteczne, może tak, może nr

  2. Oprócz automatycznie tworzonych testów, Pex jest również przydatny do parametryzowania twoich testów, znacznie lepiej jest tworzyć testy jednostkowe, które są oparte na danych, dlaczego pisać ten sam kod w kółko, z różnymi parametrami, zapisać raz i podać parametry od źródło danych:

  3. Pex jest również przydatny jako prosty krępujące ramy. Jest to prawdopodobnie najłatwiejszy sposób na tworzenie fałszywych obiektów przy użyciu nowego wyrażenia lambda, które jest dużo łatwiejsze do zrozumienia niż skomplikowane framewiry, takie jak RhinoMocks, itp. Moles pozwala również na stosowanie nie tylko interfejsu, ale także konkretnych nie-wirtualnych metod na zajęciach.

  4. Byłbym też ostrożny z warstwą "testowanie w logice biznesowej", zbyt wiele. Możesz łatwo dostać się do Behavioral Driven Development, który nie jest przeznaczony do testów jednostkowych. Tam testujesz pod kątem specyfikacji. Jeśli to wszystko, co zrobiłeś, to jak testowałbyś, powiedzmy, niestandardowe struktury danych itp., Które nie mają wartości biznesowej, ale są bibliotekami wewnętrznymi używanymi w aplikacji.

+0

1) Yas 100% pokrycia niekoniecznie oznacza dobre i dlatego jest niebezpieczne. 2) Za pomocą klasycznych testów można uruchomić kod w debugerze. Ale jeśli masz odpowiednie testy, bardzo rzadko zdarza się, że potrzebujesz debuggera. 3) Nunit obsługuje również testy w trybie przetwarzania danych, jedyna różnica - parametry nie są generowane. 4) Moli można używać oddzielnie od Pex. Jedyną zaletą Molesa przed Rhino lub Moq jest to, że może on tworzyć kody dla połączeń statycznych i kontruktorów (i nie jest to dobre z perspektywy projektu). 5) BDD - jest tylko podzbiorem TDD, zrobionym w nieco inny sposób. –

+0

uważaj, mówiąc, że to niebezpieczne. tylko dlatego, że może być niewłaściwie używane, nie oznacza, że ​​nie może być użyteczne. BDD nie jest podzbiorem TDD - BDD jest na wyższym poziomie, przechwytuje historie użytkowników, zachowanie, gdzie jako testy jednostkowe przechwytuje strukturę i projekt kodu. – zumalifeguard

+0

Nie powiedziałem, że Pex jest bezużyteczny i niebezpieczny, ponieważ może zapewnić 100% pokrycia. Powiedziałem tylko, że 100% zasięgu daje fałszywą pewność siebie. Odnośnie BDD - Czy nie sądzisz, że możliwe jest przechwytywanie historii użytkowników podczas regularnego testu (jednostka, integracja i funkcjonalność)? (http://www.code-magazine.com/article.aspx?quickid=0805061&page=1 ostatni akapit) –

Powiązane problemy