Podcast Dev Story: Czym jest Clean Code?

Ukazał się odcinek podcastu Dev Story (devstory.pl), gdzie z gospodarzem, Jarkiem Jarzębowskim, dyskutuję o czystym kodzie. Rozmowa trwa 20 minut, można ją przesłuchać m.in. na Apple Podcasts i Spotify.

Wśród poruszonych tematów między innymi jak przez ponad 10 lat kariery może zmienić się stosunek do reguł od Wujka Boba, utrzymywania testów, code review.

ArchUnit: zapomnij o architekturze, to elastyczny i inteligentny linter

ArchUnit staje się coraz częściej polecanym narzędziem. Tyle że moim zdaniem ludzie skupiają się na zbyt wąskim zastosowaniu. Winę ponosi jak myślę oficjalna strona, która upiera się, że to biblioteka do sprawdzania architektury systemów napisanych w Javie/JVM i straszy diagramami UML. Plus nazwa jest jaka jest, skojarzenia są nieuniknione. Stąd artykuły uczące ArchUnita tłuką do znudzenia przykłady typu wykrywanie cykli zależności i liczenie warstw. Nie mówię, że to zupełnie nieważne rzeczy, ale są bardziej życiowe problemy – a ArchUnit potrafi wykryć znacznie więcej, niż pokazują typowe tutoriale. Warto go poznać, nawet jeśli nie interesuje cię „testowanie architektury”.

ArchUnit pozwala za pomocą fluent API pisać narzucane na kod reguły, które działają szybko i dają jasne komunikaty błędu. Rozumie typy, co jest jego przewagą nad prostymi linterami typu CheckStyle lub ktlint. Operuje na kodzie bajtowym, więc może działać zarówno z Javą, jak i Kotlinem czy Scalą.

Można w ten sposób narzucać spójny sposób pisania („każdy kontroler musi mieć słowo Controller w nazwie”). Być może ważniejsza jest możliwość zabezpieczania się przed niepoprawnym korzystaniem z zewnętrznych bibliotek. Przykladowo, złe użycie adnotacji frameworku JUnit spowoduje, że kod testu zamiast chronić przed regresją nie będzie nigdy odpalony. Podobne pułapki czyhają w wielu bibliotekach i warto się przed nimi zabezpieczyć.

This article is also available in English.

Czytaj dalej „ArchUnit: zapomnij o architekturze, to elastyczny i inteligentny linter”

JUnit 5: DynamicTest i czytelne testy o jasnej strukturze

Jedną z najlepszych zmian wprowadzonych przez wersję 5 JUnita są według mnie testy dynamiczne. Można z ich pomocą pisać testy parametryzowane. Jednak DynamicTest/TestFactory to coś więcej niż skopiowanie funkcjonalności znanej z TestNG czy Spocka. Siłą mechanizmu z JUnita jest, że mamy pełną programistyczną kontrolę nad produkowaniem przypadków testowych. Wcale nie trzeba o dynamicznym teście myśleć jako o liście czy tabelce danych. Niżej pokażę, jak ten mechanizm może dać krótszy i łatwiejszy do zrozumienia kod testowy. Jest w stanie pogrupować powiązane testy w lepszy sposób niż zagnieżdżony test @Nested.

Czytaj dalej „JUnit 5: DynamicTest i czytelne testy o jasnej strukturze”

Fast Reactor Tests With Virtual Time

„Wirtualny czas” przydaje się przy pisaniu testów asynchronicznego kodu, gdzie po jakimś czasie coś ma się zdarzyć albo właśnie zdarzyć się nie powinno. W tym podejściu unikamy czekania w samym teście i sztucznie przyspieszamy bieg wydarzeń. Pokazuję, jak to robić z biblioteką reaktywną Reactor, która dostarcza wbudowane narzędzie do obsługi wirtualnego czasu, StepVerifier.

Artykuł po angielsku — zapraszam na Medium*.

* wejście z tego specjalnego linku nie zmniejszy waszego miesięcznego limitu darmowych artykułów w serwisie

Mutation testing: Too good to be true?

Widziałem w sieci artykuły ogłaszające, że code coverage umarł i nadszedł czas testowania mutacyjnego. ThoughtWorks po przerwie wraca do polecania w swoim raporcie Technology Radar narzędzia Pitest, które implementuje testowanie mutacyjne dla JVM. Postanowiłem przyjrzeć się, czy to podejście to faktycznie epokowa zmiana w podejściu do pisania testów jednostkowych. Będzie o czasie działania, zawartości raportów, skuteczności wyłapywania problemów, konfiguracji, obsłudze Kotlina. Artykuł po angielsku — zapraszam na Medium*.

* wejście z tego specjalnego linku nie zmniejszy waszego miesięcznego limitu darmowych artykułów w serwisie

Fast and stable MongoDB-based tests in Spring

Tradycyjne uruchamianie testowego MongoDB przez Flapdoodle Embedded Mongo kontra nowoczesne podejście z Testcontainers. Krótko o kontekstach w testach Springa przy okazji potwornego zużycia zasobów przez Flapdoodle. Mierzenie obciążenia systemu narzędziem sar i o użyteczności starego dobrego gnuplota. Artykuł po angielsku — zapraszam na Medium*.

* wejście z tego specjalnego linku nie zmniejszy waszego miesięcznego limitu darmowych artykułów w serwisie

Dzielenie się testowymi klasami pomocniczymi w Gradle’u

Czasem mamy przypadek, że piszemy test jednostkowy jakiejś klasy i okazuje się, że część kodu testowego może być przydatna w innych częściach naszego projektu. Jak udostępnić ten kod, żeby był widoczny zarówno w testach aktualnego projektu, jak i w testach projektów od niego zależnych? Gradle od wersji 5.6 udostępnia dla tego celu plugin java-test-fixtures.

Czytaj dalej „Dzielenie się testowymi klasami pomocniczymi w Gradle’u”

Testy kontraktowe: Pact bez Pact Brokera

pact-jvm to jeden z dwóch wiodących frameworków do pisania testów kontraktowych dla Javy i JVM. Problemem na wejściu może być znalezienie sposobu na dzielenie się kontraktami: oficjalnie polecanym rozwiązaniem jest serwer Pact Broker, napisany w Rubym. Postawienie serwera trochę ułatwia dostępność obrazu dockerowego, ale wciąż całość wymaga nieco zabawy. Jeśli chcemy na szybko sprawdzić, czy Pact nam się podoba, wolelibyśmy opcję wymagającą minimalnego nakładu pracy.

Tu pojawia się możliwość rzadko wspominana w tutorialach Pacta: wymiana kontraktów przez repozytorium Mavena, nawet takie lokalnie na dysku. Nie potrzebujemy niczego poza narzędziami, które i tak mamy programując w Javie.

Czytaj dalej „Testy kontraktowe: Pact bez Pact Brokera”

ExpectedException i pułapki łapania wyjątków w testach

Pisząc testy we frameworku JUnit 4 mamy kilka opcji na zapisanie warunku, że testowany kod powinien rzucić wyjątkiem. Wymieniając najprostsze, niewymagające dodatkowych bibliotek:

  1. dodanie atrybutu „expected” do adnotacji na metodzie testowej: @Test(expected = IllegalStateException.class)
  2. otoczenie kodu blokiem try-catch
  3. użycie reguły ExpectedException

Pierwsza opcja wymaga najmniej pisania, ale jest mało elastyczna: nie jesteśmy w stanie zapewnić niczego o wyjątku, jedynie jego klasę. Gdyby przyszła potrzeba upewnienia się, jaki jest komunikat wyjątku, metodę testową trzeba całkowicie przepisać, zmieniając podejście na któreś z opisanych niżej.

Czytaj dalej „ExpectedException i pułapki łapania wyjątków w testach”
Creative Commons License
Except where otherwise noted, the content by Piotr Kubowicz is licensed under a Creative Commons Attribution 4.0 International License.