Zwykle mówiąc o standardach kodowania, odnosimy się do kodu samego programu, ale co z testami jednostkowymi? Czy istnieją pewne wytyczne standardów kodowania, które są unikalne dla testów jednostkowych? Czym oni są?
Zwykle mówiąc o standardach kodowania, odnosimy się do kodu samego programu, ale co z testami jednostkowymi? Czy istnieją pewne wytyczne standardów kodowania, które są unikalne dla testów jednostkowych? Czym oni są?
Odpowiedzi:
Z góry głowy mogę wymyślić trzy różnice w stylu kodowania kodu testowego.
W metodzie testowania nazw kieruję się wzorem shouldDoSomethingWhenSomeConditionHolds
.
W teście zwykle stosuje się następujący wzór odstępów:
@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
// Some lines
// of setup code
// go here.
// The action being tested happens after a blank line.
// An assertion follows another blank line.
}
Niektórzy nalegają na tylko jedno stwierdzenie na test, ale nie jest to uniwersalne.
DRY (Don't Repeat Yourself) jest mniej ważne w kodzie testowym niż w kodzie produkcyjnym. Podczas gdy część powtarzanego kodu należy umieścić w metodzie setUp lub klasie testUtils, dążenie do zerowego powtórzenia w kodzie testowym doprowadzi do ściśle powiązanych i nieelastycznych testów, co zniechęca do refaktoryzacji.
Roy Osherove zaleca następujący wzór do nazwania swoich testów:
NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior()
Zobacz http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx
NameOfMethodUnderTestStateUnderTestExpectedBehavior()
;)
Najważniejsze jest, aby pamiętać, że testy jednostkowe są zasadniczo mini-specyfikacjami. Oznacza to, że zawsze należy kłaść nacisk na czytelność.
Po pierwsze, oznacza to, że nazwy muszą jasno komunikować, co jest testowane i co jest potwierdzane.
Po drugie jednak, o czym czasem się zapomina, jest to, że jako specyfikacje powinni robić właśnie to - określając zachowanie. Oznacza to, że testy jednostkowe nie powinny zawierać logiki - lub potencjalnie wpadają w pułapkę powtarzania funkcjonalności programu zamiast testowania go.
Czasami testy będą obejmować obiekty, których konfiguracja jest skomplikowana, powinieneś starać się trzymać tę logikę konfiguracji osobną od testów, używając czegoś takiego jak matka obiektu lub konstruktor danych testowych .
Zakończę kilkoma zaleceniami dotyczącymi książek:
Wzorce testowe xUnit: Refaktoryzacja Kod testowy: Doskonała książka, niektórzy twierdzą, że jest trochę sucha, ale nie sądzę. Wchodzi w wiele szczegółów na temat wielu różnych sposobów organizowania testów i sposobów ich utrzymania. Ważne, jeśli używasz czegoś takiego jak NUnit itp.
Sztuka testowania jednostkowego: z przykładami w .Net : najlepsza książka na temat drobiazgowości pisania i utrzymywania testów. Pomimo tego, że jestem naprawdę nowy, drwiące sekcje są już trochę przestarzałe, ponieważ składnia AAA jest teraz raczej standardem niż tylko innym sposobem na zrobienie tego.
Rosnące oprogramowanie obiektowe oparte na testach : ta książka jest po prostu niesamowita! Zdecydowanie najlepsza książka o testach jednostkowych i jedyna zaawansowana, która stawia testy jednostkowe jako obywatela pierwszej klasy w procesie projektowania. Czytałem to, gdy była to publiczna wersja beta i od tego czasu polecam. Doskonały przykład z prawdziwego świata zastosowany w całej książce. Poleciłbym jednak najpierw przeczytać książkę Roya.
Nie umieszczaj logiki w testach jednostkowych. Załóżmy na przykład, że testujesz metodę dodawania, możesz mieć coś takiego:
void MyTest_SaysHello()
{
string name = "Bob";
string expected = string.Format("Hello, {0}", name);
IMyObjectType myObject = new MyObjectType();
string actual = myObject.SayHello(name);
Assert.AreEqual(expected, actual);
}
W tym konkretnym przypadku prawdopodobnie powtarzasz tę samą logikę, co w teście, więc zasadniczo testujesz „1 + 1 == 1 + 1” zamiast „1 + 1 == 2”, czyli „prawdziwy” test. Tak więc naprawdę chciałbyś, aby Twój kod testowy wyglądał:
void MyTest_SaysHello()
{
string expected = "Hello, Bob";
IMyObjectType myObject = new MyObjectType();
string actual = myObject.SayHello("Bob");
Assert.AreEqual(expected, actual);
}
Długie opisowe nazwy metod. Pamiętaj, że metody testowe nigdy nie są wywoływane z kodu (są one wywoływane przez moduł testujący jednostki, który odkrywa je i wywołuje przez odbicie), więc można szaleć i mieć nazwy metod o długości 50-80 znaków. Konkretna konwencja nazewnictwa (wielbłąd, podkreślenia, „powinien”, „musi”, „kiedy”, „dany” itd.) Nie jest tak naprawdę ważna, o ile nazwa odpowiada na trzy pytania:
Metody testowe powinny być krótkie .
Metody testowe powinny mieć prostą, liniową strukturę . Nie, jeśli lub konstrukcja pętli.
Metody testowe powinny być zgodne ze wzorcem „arrange-act-assert” .
Każdy test powinien przetestować jedną rzecz . Zazwyczaj oznacza to jeden assert na test. Test taki { Do A; Assert B; Assert C; }
powinien zostać podzielony na dwie części: { Do A; Assert B; }
i{ Do A; Assert C; }
Unikaj przypadkowych danych lub rzeczy takich jak „DateTime.Now”
Upewnij się, że wszystkie elementy urządzenia testowego powracają do pierwotnego stanu na koniec testu (np. Przy użyciu rozerwania )
Nawet jeśli bezwzględnie usuniesz powielanie w kodzie produkcyjnym, powielanie kodu w urządzeniach testowych jest znacznie mniejszym problemem.
Nieco podobny do tego, co już wspomniał Farmboy, format nazwy mojej metody
<MethodName>Should<actionPerformed>When<Condition>
na przykład
GetBalanceShouldReturnAccountBalance() {