Czy istnieje ustalona najlepsza praktyka oddzielania testów jednostkowych i testów integracyjnych w GoLang (zeznawaj)? Mam mieszankę testów jednostkowych (które nie opierają się na żadnych zewnętrznych zasobach i dlatego działają bardzo szybko) i testów integracyjnych (które polegają na jakichkolwiek zasobach zewnętrznych i dlatego działają wolniej). Więc chcę mieć możliwość kontrolowania, czy włączać testy integracji, kiedy mówię go test
.
Wydaje się, że najbardziej prostą techniką byłoby zdefiniowanie flagi zintegrowanej w main:
var runIntegrationTests = flag.Bool("integration", false
, "Run the integration tests (in addition to the unit tests)")
Następnie, aby dodać instrukcję if na początku każdego testu integracji:
if !*runIntegrationTests {
this.T().Skip("To run this test, use: go test -integration")
}
Czy to najlepsze, co mogę zrobić? Przeszukałem dokumentację zeznań, aby sprawdzić, czy jest może jakaś konwencja nazewnictwa lub coś, co zapewnia mi to, ale nic nie znalazłem. Czy coś mi brakuje?
źródło
var integration = flag.Bool("integration", true, "Enable integration testing.")
zmienną jako poza funkcją, zmienna pojawi się w zakresie pakietu, a flaga będzie działać poprawnieOdpowiedzi:
@ Ainar-G sugeruje kilka świetnych wzorców do oddzielnych testów.
Ten zestaw praktyk Go z SoundCloud zaleca używanie tagów kompilacji ( opisanych w sekcji „Ograniczenia kompilacji” pakietu kompilacji ) w celu wybrania testów do uruchomienia:
Podobną opcję można by również przeprowadzić domyślnie uruchamiając testy integracji przy użyciu warunku kompilacji
// +build !unit
, a następnie wyłączyć je na żądanie, uruchamiającgo test -tags=unit
.@adamc komentarze:
Dla każdego, kto próbuje użyć tagów kompilacji, ważne jest, aby
// +build test
komentarz był pierwszym wierszem w pliku i aby po komentarzu umieścić pusty wiersz, w przeciwnym razie-tags
polecenie zignoruje dyrektywę.Ponadto tag używany w komentarzu do kompilacji nie może zawierać myślnika, chociaż znaki podkreślenia są dozwolone. Na przykład
// +build unit-tests
nie zadziała, podczas gdy// +build unit_tests
będzie.źródło
// + build unit
testy jednostkowe i użyć jednostki -tag do uruchamiania testów// +build
komentarz testowy był pierwszą linią w pliku i aby dołączyć pustą linię po komentarzu, w przeciwnym razie-tags
polecenie zignoruje dyrektywę. Ponadto tag używany w komentarzu do kompilacji nie może zawierać myślnika, chociaż znaki podkreślenia są dozwolone. Na przykład,// +build unit-tests
nie zadziała, podczas gdy// +build unit_tests
willgo test -tags=integration ./...
nie działa, ignoruje tagWypracowanie na mój komentarz do @ doskonałą odpowiedź Ainar-G, w ciągu ostatniego roku byłem za pomocą kombinacji
-short
zIntegration
konwencją nazewnictwa, aby osiągnąć to, co najlepsze z obu światów.Testy zgodności jednostek i integracji w tym samym pliku
Budowanie flag wcześniej zmusiło mnie do posiadania wielu plików (
services_test.go
,services_integration_test.go
itp).Zamiast tego weźmy poniższy przykład, gdzie pierwsze dwa to testy jednostkowe, a na końcu mam test integracji:
Zauważ, że ostatni test ma konwencję:
Integration
w nazwie testu.-short
dyrektywą flag.Zasadniczo specyfikacja brzmi: „pisz wszystkie testy normalnie. Jeśli są to testy długotrwałe lub test integracji, postępuj zgodnie z konwencją nazewnictwa i sprawdź, czy
-short
są one miłe dla rówieśników”.Uruchom tylko testy jednostkowe:
zapewnia to ładny zestaw komunikatów, takich jak:
Uruchom tylko testy integracji:
To uruchamia tylko testy integracji. Przydatne do testowania dymu kanarków w produkcji.
Oczywiście wadą tego podejścia jest to, że jeśli ktokolwiek uruchomi się
go test
bez-short
flagi, domyślnie uruchomi wszystkie testy - testy jednostkowe i integracyjne.W rzeczywistości, jeśli Twój projekt jest wystarczająco duży, aby mieć testy jednostkowe i integracyjne, najprawdopodobniej używasz w nim
Makefile
prostego dyrektywygo test -short
. Lub po prostu umieść to w swoimREADME.md
pliku i nazwij to dniem.źródło
import
mój pakiet i przetestować go, co kończy się pokazaniem mi, jak wygląda moje API innym. Następnie podążam za wszelką pozostałą logiką, która musi zostać uwzględniona jako wewnętrzne nazwy pakietów testowych.package services
zawiera test integracji, więc aby przetestować APIfo pakiet jako czarną skrzynkę, nazwijmy go w inny sposóbpackage services_integration_test
, nie da nam to szansy na pracę ze strukturami wewnętrznymi. Dlatego pakiet do testów jednostkowych (dostęp do elementów wewnętrznych) powinien mieć nazwępackage services
. Czy tak jest?Widzę trzy możliwe rozwiązania. Pierwszym jest użycie trybu skróconego do testów jednostkowych. Więc używałbyś
go test -short
z testami jednostkowymi i tym samym, ale bez-short
flagi, aby uruchomić również testy integracji. Biblioteka standardowa korzysta z trybu skróconego, aby pomijać długotrwałe testy lub przyspieszyć ich działanie, udostępniając prostsze dane.Drugim jest użycie konwencji i wywołanie testów albo
TestUnitFoo
lub,TestIntegrationFoo
a następnie użycie-run
flagi testing, aby wskazać, które testy mają zostać wykonane. Więc używałbyśgo test -run 'Unit'
do testów jednostkowych igo test -run 'Integration'
testów integracyjnych.Trzecią opcją jest użycie zmiennej środowiskowej i umieszczenie jej w konfiguracji testów za pomocą
os.Getenv
. Następnie możesz użyć prostegogo test
do testów jednostkowych iFOO_TEST_INTEGRATION=true go test
testów integracyjnych.Osobiście wolałbym to
-short
rozwiązanie, ponieważ jest prostsze i jest używane w standardowej bibliotece, więc wydaje się, że jest to de facto sposób na oddzielenie / uproszczenie długotrwałych testów. Ale rozwiązania-run
ios.Getenv
oferują większą elastyczność (wymagana jest również większa ostrożność, ponieważ używane są wyrażenia regularne-run
).źródło
Tester-Go
programy uruchamiające testy (np. ) wspólne dla IDE (Atom, Sublime itp.) mają wbudowaną opcję uruchamiania z-short
flagą, wraz z-coverage
innymi. w związku z tym w nazwie testu używam kombinacji opcji Integracja, a takżeif testing.Short()
sprawdzeń w ramach tych testów. pozwala mi mieć to, co najlepsze z obu światów: działać w-short
ramach IDE i jawnie uruchamiać tylko testy integracji zgo test -run "Integration"
Ostatnio próbowałem znaleźć rozwiązanie tego samego. To były moje kryteria:
Powyższe rozwiązania (niestandardowa flaga, niestandardowy tag kompilacji, zmienne środowiskowe) tak naprawdę nie spełniały wszystkich powyższych kryteriów, więc po krótkim kopaniu i zabawie wpadłem na takie rozwiązanie:
Wdrożenie jest proste i minimalne. Chociaż wymaga prostej konwencji do testów, ale jest mniej podatny na błędy. Dalszym ulepszeniem może być eksportowanie kodu do funkcji pomocniczej.
Stosowanie
Uruchom testy integracji tylko dla wszystkich pakietów w projekcie:
Uruchom wszystkie testy ( zwykłe i integracyjne):
Wykonuj tylko regularne testy:
To rozwiązanie działa dobrze bez narzędzi, ale plik Makefile lub niektóre aliasy mogą ułatwić użytkownikowi. Można go również łatwo zintegrować z dowolnym IDE, które obsługuje uruchamianie testów go.
Pełny przykład można znaleźć tutaj: https://github.com/sagikazarmark/modern-go-application
źródło