SlideShare a Scribd company logo
Code Quality Keepers
opowieści z pola bitwy o jakość kodu
Rafał Głowiński, Bartosz Walacik
Confitura 2015
O nas
Rafał Głowiński
@GlowinskiRafal
Bartosz Walacik
@BartoszWalacik
http://javers.org
O czym będziemy mówić
Pytania:
→ Jak dbać o jakość kodu w zespole? Code review?
→ A co jeśli mamy 40+ zespołów?
→ Jak zadbać o jakość na poziomie całej organizacji?
O czym będziemy mówić
Opowiemy:
→ Po co CQK?
→ Jak zdefiniować kryteria jakości i ocenić kod różnych zespołów
→ Jak robimy prawdopodobnie największe Code Review w Polsce
→ Co udało nam się znaleźć: “perełki”, typowe błędy
→ A także… co udało nam się osiągnąć
→ 40+ zespołów (dev + infra)
Zespoły w Allegro
→ 4 miasta (Poznań, Toruń, Warszawa, Kraków)
→ Często doświadczenie głównie w PHP
→ Większość pisze i utrzymuje mikrousługi na JVM
Jak powstało CQK i po co?
Pierwszy skład zespołu CQK:
→ doświadczeni inżynierowie
→ zaangażowani w community
→ autorytet nie hierarchia
→ kilka osób myślących podobnie, startup
Jak powstało CQK i po co?
Pierwszy Cel:
Przejrzeć i ocenić (w miarę) obiektywnie cały kod
Pierwsze review:
→ 1 dzień w 1 salce
→ kilkadziesiąt projektów do przejrzenia
→ 15 minut na projekt (!)
→ totalna partyzantka
Jak powstało CQK i po co?
Wnioski z pierwszego review:
→ 15 min na projekt to za mało
→ potrzebna jest metodyka i organizacja
→ koncentracja na wybranych aspektach
Nowe Cele:
→ Cel 1: podnoszenie jakości kodu w całej organizacji
poprzez review, feedback i mentoring
→ Cel 2: wkład do ocen technicznych zespołów
Jak pracujemy
→ Zaczęliśmy od garstki osób, teraz jest nas więcej
→ Co kwartał zmieniamy metodykę review
→ Merytoryczny feedback
→ Przejście na tryb “push”
Metodyka review: pierwszy kwartał
“Wrażenia artystyczne”
(15 min na projekt…)
Metodyka review: drugi kwartał
Duże i częste naruszenia podstawowych zasad
Są błędy, ale generalnie jest ok
Jest dobrze!
Magic Servlet Antipattern is Back:
→ logika biznesowa/dostęp do repozytorium w kontrolerze
→ nieprawidłowe wykorzystanie frameworków (np. ręczne
mapowanie wyjątków na kodu HTTP)
Metodyka review: drugi kwartał
Zwięzłość i czytelność testów:
→ struktura testów, prawidłowe wykorzystanie bibliotek
→ co testują testy
→ mocks (overmocking, mockowanie nie swoich klas)
Szkolenia: trzeci kwartał
→ Naming i omówienie bytów w testach (Stub, Mock, Spy)
→ Spock: Data Driven, wyjątki, asercje, Groovy
→ (*) JUnit: Mockito, AssertJ, JUnitParams, catch-exception
→ Overmocking + verify = betonowy kod
→ Testy integracyjne: bazy danych, REST
Zwięzłość i czytelność testów cd.
Metodyka review: aktualnie
Model domenowy:
→ klasy modelu
→ organizacja pakietów
→ powiązanie z bibliotekami / infrastrukturą
Metodyka review: aktualnie
Model domenowy:
brak modelu domenowego: mutowalne & anemiczne POJO
operujące na nich klasy Service
Metodyka review: aktualnie
Model domenowy:
kod jest podzielony horyzontalnie
domena powiązana z infrastrukturą (zapytania do baz
danych, skomplikowane logowanie/monitoring, itp.)
widać starania odejścia od anemiczności modelu
(rozsądne podejście do mutowalności, obiekty zyskują
funkcjonalności)
Metodyka review: aktualnie
Model domenowy:
ładny model domenowy zgodny z OOP
struktura pakietów zorientowana domenowo
domena jest wyraźnie odseparowana od infrastruktury
podział pakietowy zgodnie z wytycznymi np. Hexagonal
Architecture
Eksperyment: review kodu JS
Opowiemy o tym za rok ;)
Główna działalność CQK
Tworzenie feedbacków dla zespołów
→ Zespół zgłasza do feedbacku projekt lub PR
→ Przeciętny projekt ma ~10KLOC
Co to jest feedback
Kilkustronicowy dokument na WIKI, lista punktów, np:
dobre testy integracyjne (np BlacklistEndpointIntegrationSpec.groovy)
SalesRegulationsFilterTest.java - do testu tego rodzaju prostych funkcji używajcie
podejścia data-driven test
Klasa Pdf.java mogłyby być immutable, czyli zamiast:
Pdf pdf = new Pdf();
pdf .setContent(documentContent);
lepiej
Pdf pdf = new Pdf (documentContent);
długa implementacja equals() w BlacklistRequest.java. Łatwo się pomylić w takim
kodzie. Czy ten equals() jest do czegoś potrzebny?
Fazy życia feedbacku: koszt os./h
I. Review kodu + spisanie 2-3
II. Weryfikacja 1-2
III. Publikacja i uwagi od zespołu 1
IV. Przepracowanie w zespole 0
Jak powstaje feedback
Faza I. Review kodu + spisanie uwag
→ Keeper klonuje repo i ogląda kod
→ Nie uruchamiamy tooli do statycznej analizy
→ Keeper tworzy dokument feedbacku i proponuje ocenę
Jak powstaje feedback
Faza II. Weryfikacja
→ Drugi Keeper przegląda feedback (kontrola merytoryczna)
→ Przy rozbieżnościach - uzgadniamy w ramach CQK
→ Kontrola czy feedback jest friendly
→ Drugi Keeper często dopisuje swoje uwagi
→ Approve
Jak powstaje feedback
Faza III. Publikacja i uwagi od zespołu
→ Feedback jest przekazywany do zespołu
→ Zachęcamy zespół do ustosunkowania się do feedback’u
Czy modyfikujemy feedback?
→ Świadome i uzasadnione naruszenia reguł
→ My czegoś nie zrozumieliśmy (brak kontekstu)
Jak powstaje feedback
Faza IV. Przepracowanie feedbacku w zespole
Mamy nadzieję, że zespół przekona się do naszych uwag i
propozycji
Jak powstaje feedback
Co znaleźliśmy - big picture
Co znaleźliśmy - big picture
Główne grzechy:
→ TDD - Test Driven Development
→ Anemic Domain Model
Co znaleźliśmy - big picture
TDD - problemy:
→ Overmocking
→ Mocking What-You-Don’t-Own
→ Testy są kopią implementacji
→ Za mało testów integracyjnych
→ Testy pisane pod Coverage
→ Testy bez wartości dokumentacyjnej
→ Testowanie implementacji a nie funkcjonalności
Co znaleźliśmy - big picture
Anemic Domain Model
→ Anemiczne, mutowalne Encje
→ Settery i gettery rządzą
→ Programowanie proceduralne nie obiektowe
→ Często w ogóle brak wydzielonego Modelu Domenowego
Co znaleźliśmy - big picture
Test unitowy prostego konstruktora
Co znaleźliśmy - ‘perełki’
public class ClientException extends RuntimeException {
static final long serialVersionUID = -712897190232112939L;
public ClientException(String message) {
super(message);
}
public ClientException(String message, Throwable cause) {
super(message, cause);
}
}
src
@Test
public void shouldSetMessageAndCauseInConstructor() {
//given
String exceptedMessage = "Very bad exception";
Exception expectedCauseException = new Exception("This is cause exception");
//when
ClientException exception = new ClientException(exceptedMessage, expectedCauseException);
String message = exception.getMessage();
Throwable causeException = exception.getCause();
//then
assertEquals(exceptedMessage, message);
assertEquals(expectedCauseException, causeException);
}
test
Nie testuj unitowo prostych konstruktorów oraz
metod
CQK radzi
Test unitowy Serwisu-przelotki
Co znaleźliśmy - ‘perełki’
public class SaleRegulationsService {
public List<SaleRegulations> findRegulations(String userId, Long timestamp) {
List<SaleRegulations> results;
if (timestamp == null) {
results = salesRegulationsRepository.findOneByUserId(userId);
} else {
results = salesRegulationsRepository.findByUserId(userId);
}
return results;
}
...
}
src
@Test
public void shouldReturnMoreResultsWhenTimestampIsGiven() {
// given
SaleRegulationsService saleRegulationsService =new SaleRegulationsService(salesRegulationsRepository,
eventProducer);
SaleRegulations saleRegulations1 =new SaleRegulations(USER_ID, SALE_REGULATIONS_TEXT, TIMESTAMP);
SaleRegulations saleRegulations2 =new SaleRegulations(USER_ID, SALE_REGULATIONS_TEXT_VERSION_2, TIMESTAMP2);
List<SaleRegulations> results =new ArrayList<>();
results.add(saleRegulations1);
results.add(saleRegulations2);
when(salesRegulationsRepository.findByUserId(USER_ID)).thenReturn(results);
// when
List<SaleRegulations> regulations = saleRegulationsService.findRegulations(USER_ID, TIMESTAMP);
// then
assertThat(regulations.size()).isEqualTo(2);
assertThat(regulations.get(0)).isEqualTo(saleRegulations1);
...
test
Nie testuj unitowo metod typu przelotka.
Testuj integracyjnie, używając Embedded (lub Fake) DB
CQK radzi
Overmocking
Co znaleźliśmy - ‘perełki’
@RunWith(MockitoJUnitRunner. class)
public class CreateEndpointTest {
@Mock
private RefundsSoapBindingStub npRefundService;
@Mock
private RefundsClient refundsClient;
@Mock
private PayuOrders payuOrders;
@Mock
private SignatureFactory signatureFactory;
@Mock
private RefundInfo refundInfoMock;
...
test
unikaj Mocków z verify(), to betonowanie kodu
CQK radzi
Konkurs Allegro
Kod: 5mSG5t
Najczęstsze błędy
Wstrzykiwanie zależności: pola vs konstruktor:
→ Jasna deklaracja kolaboratorów
→ Rozróżnienie opcjonalnych zależności
→ Łatwiejsza konstrukcja obiektów w testach
Najczęstsze błędy
Niemutowalność:
“Classes should be immutable unless there's a very good
reason to make them mutable....If a class cannot be made
immutable, limit its mutability as much as possible.”
Joshua Bloch, Effective Java
Najczęstsze błędy
Mockowanie nie swoich rzeczy:
(a.k.a: Don’t mock what you don’t own)
→ zmiany poza naszą kontrolą
→ podwójnie kosztowne (test / prod)
→ przekonaliśmy zespoły do zewnętrznego review
→ konwencja: should + given/when/then
→ przekonaliśmy większość zespołów do Spocka
→ zespoły piszą coraz lepsze testy integracyjne
→ Overmockingu mniej
→ zdecydowanie widać poprawę ogólnej jakości kodu
Sukcesy
→ review w ramach jednego zespołu często nie wystarcza
→ potrzeba systematyczności - jednorazowy zryw to za mało
→ otwartość na feedback
→ cierpliwość - efekty nie przyjdą od razu
Wnioski
Q/A?
Znajdziesz nas:
Blog: allegrotech.io
Twitter: @allegrotechblog
pracuj z nami
kariera.allegro.pl

More Related Content

What's hot

Rundeck & Ansible
Rundeck & AnsibleRundeck & Ansible
Rundeck & Ansible
Maciej Lasyk
 
Infrastructure As Code
Infrastructure As CodeInfrastructure As Code
Infrastructure As Code
Kamil Grabowski
 
Technologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT coreTechnologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT core
Sages
 
Swoole w PHP. Czy to ma sens?
Swoole w PHP. Czy to ma sens?Swoole w PHP. Czy to ma sens?
Swoole w PHP. Czy to ma sens?
The Software House
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
kraqa
 
Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.
Semihalf
 
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDKZłam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
Semihalf
 
Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6
The Software House
 
Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.
Semihalf
 
Testowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStackTestowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStack
The Software House
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
Natalia Stanko
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
The Software House
 
Info meet pomiary wydajności
Info meet pomiary wydajnościInfo meet pomiary wydajności
Info meet pomiary wydajnościmagda3695
 
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwAsynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Luke Adamczewski
 
Testowanie EDW czyli projekt piekło - Bartłomiej Nikiel
Testowanie EDW czyli projekt piekło - Bartłomiej NikielTestowanie EDW czyli projekt piekło - Bartłomiej Nikiel
Testowanie EDW czyli projekt piekło - Bartłomiej Nikiel
kraqa
 
Ansible - Automatyzacja zadań IT
Ansible - Automatyzacja zadań ITAnsible - Automatyzacja zadań IT
Ansible - Automatyzacja zadań IT
Kamil Grabowski
 
Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...
Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...
Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...
Kainos Polska
 
GlusterFS
GlusterFSGlusterFS

What's hot (18)

Rundeck & Ansible
Rundeck & AnsibleRundeck & Ansible
Rundeck & Ansible
 
Infrastructure As Code
Infrastructure As CodeInfrastructure As Code
Infrastructure As Code
 
Technologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT coreTechnologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT core
 
Swoole w PHP. Czy to ma sens?
Swoole w PHP. Czy to ma sens?Swoole w PHP. Czy to ma sens?
Swoole w PHP. Czy to ma sens?
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
 
Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.
 
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDKZłam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
 
Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6
 
Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.
 
Testowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStackTestowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStack
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
 
Info meet pomiary wydajności
Info meet pomiary wydajnościInfo meet pomiary wydajności
Info meet pomiary wydajności
 
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwAsynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
 
Testowanie EDW czyli projekt piekło - Bartłomiej Nikiel
Testowanie EDW czyli projekt piekło - Bartłomiej NikielTestowanie EDW czyli projekt piekło - Bartłomiej Nikiel
Testowanie EDW czyli projekt piekło - Bartłomiej Nikiel
 
Ansible - Automatyzacja zadań IT
Ansible - Automatyzacja zadań ITAnsible - Automatyzacja zadań IT
Ansible - Automatyzacja zadań IT
 
Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...
Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...
Kainos Tech Space #1 : DevOps : Artur Senk - Jenkins, najważniejsze narzędzie...
 
GlusterFS
GlusterFSGlusterFS
GlusterFS
 

Viewers also liked

[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów
[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów
[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistówMichał Bartyzel
 
[Pl] conversation patterns for software professionals
[Pl] conversation patterns for software professionals[Pl] conversation patterns for software professionals
[Pl] conversation patterns for software professionals
Michał Bartyzel
 
[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...
[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...
[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...
Michał Bartyzel
 
Bdd @tommykaczmarek
Bdd @tommykaczmarekBdd @tommykaczmarek
Bdd @tommykaczmarek
tommykaczmarek
 
[33rd] x driven-y niczego nie zmienią
[33rd] x driven-y niczego nie zmienią[33rd] x driven-y niczego nie zmienią
[33rd] x driven-y niczego nie zmienią
Michał Bartyzel
 
Confitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotneConfitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotne
allegro.tech
 
Dobre praktyki na kursie kolizyjnym
Dobre praktyki na kursie kolizyjnymDobre praktyki na kursie kolizyjnym
Dobre praktyki na kursie kolizyjnym
Szymon Homa
 

Viewers also liked (7)

[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów
[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów
[4 developers] Jak zniszczyć swój kod - podstawy lingwistyki dla programistów
 
[Pl] conversation patterns for software professionals
[Pl] conversation patterns for software professionals[Pl] conversation patterns for software professionals
[Pl] conversation patterns for software professionals
 
[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...
[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...
[Confitura 2013] Nie ma jednej słusznej drogi - różne podejścia do architektu...
 
Bdd @tommykaczmarek
Bdd @tommykaczmarekBdd @tommykaczmarek
Bdd @tommykaczmarek
 
[33rd] x driven-y niczego nie zmienią
[33rd] x driven-y niczego nie zmienią[33rd] x driven-y niczego nie zmienią
[33rd] x driven-y niczego nie zmienią
 
Confitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotneConfitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotne
 
Dobre praktyki na kursie kolizyjnym
Dobre praktyki na kursie kolizyjnymDobre praktyki na kursie kolizyjnym
Dobre praktyki na kursie kolizyjnym
 

Similar to Confitura 2015 - Code Quality Keepers @ Allegro

[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...
[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...
[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...
Future Processing
 
university day 1
university day 1university day 1
university day 1
Sławomir Borowiec
 
Więcej testów/mniej kodu - Michał Gaworski, kraQA 13
Więcej testów/mniej kodu - Michał Gaworski, kraQA 13Więcej testów/mniej kodu - Michał Gaworski, kraQA 13
Więcej testów/mniej kodu - Michał Gaworski, kraQA 13
kraqa
 
Produkcja aplikacji internetowych
Produkcja aplikacji internetowychProdukcja aplikacji internetowych
Produkcja aplikacji internetowych
Tomasz Borowski
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatyczny
qbeuek
 
4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...
4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...
4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...
PROIDEA
 
Poznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven DevelopmentPoznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven Developmentbartlomiej.szafko
 
4Developers 2018: Unit testing - introduction (Marek Kawczyński)
4Developers 2018: Unit testing - introduction (Marek Kawczyński)4Developers 2018: Unit testing - introduction (Marek Kawczyński)
4Developers 2018: Unit testing - introduction (Marek Kawczyński)
PROIDEA
 
[PL] Jak programować aby nie zwariować?
[PL] Jak programować aby nie zwariować?[PL] Jak programować aby nie zwariować?
[PL] Jak programować aby nie zwariować?
Jakub Marchwicki
 
Testy wydajnościowe - najlepsze praktyki - Kuba Gajda
Testy wydajnościowe - najlepsze praktyki - Kuba GajdaTesty wydajnościowe - najlepsze praktyki - Kuba Gajda
Testy wydajnościowe - najlepsze praktyki - Kuba Gajda
Bartłomiej Cymanowski
 
Od codziennej higieny do strategicznej refaktoryzacji
Od codziennej higieny do strategicznej refaktoryzacjiOd codziennej higieny do strategicznej refaktoryzacji
Od codziennej higieny do strategicznej refaktoryzacji
Michał Bartyzel
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPl
Sebastian Marek
 
Kwestionowanie ISTQB
Kwestionowanie ISTQBKwestionowanie ISTQB
Kwestionowanie ISTQB
Radoslaw Smilgin
 
Testowanie na 101 sposobów
Testowanie na 101 sposobówTestowanie na 101 sposobów
Testowanie na 101 sposobów
Katarzyna Javaheri-Szpak
 
Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16
Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16
Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16
Krzysztof Synak
 
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
Future Processing
 
Refaktoryzacja
RefaktoryzacjaRefaktoryzacja
Refaktoryzacja
PHPstokPHPstok
 
Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?
The Software House
 
Podstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptxPodstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptx
Katarzyna Javaheri-Szpak
 
Unit testing w praktyce... czyli właściwie jak?
Unit testing w praktyce... czyli właściwie jak?Unit testing w praktyce... czyli właściwie jak?
Unit testing w praktyce... czyli właściwie jak?
Bartłomiej Cymanowski
 

Similar to Confitura 2015 - Code Quality Keepers @ Allegro (20)

[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...
[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...
[Quality Meetup#12] P. Podsiadlik, R. Peroń - Testy regresji z perspektywy pi...
 
university day 1
university day 1university day 1
university day 1
 
Więcej testów/mniej kodu - Michał Gaworski, kraQA 13
Więcej testów/mniej kodu - Michał Gaworski, kraQA 13Więcej testów/mniej kodu - Michał Gaworski, kraQA 13
Więcej testów/mniej kodu - Michał Gaworski, kraQA 13
 
Produkcja aplikacji internetowych
Produkcja aplikacji internetowychProdukcja aplikacji internetowych
Produkcja aplikacji internetowych
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatyczny
 
4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...
4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...
4Developers 2015: Couple of words about testing in Java, Spock and BDD - Piot...
 
Poznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven DevelopmentPoznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven Development
 
4Developers 2018: Unit testing - introduction (Marek Kawczyński)
4Developers 2018: Unit testing - introduction (Marek Kawczyński)4Developers 2018: Unit testing - introduction (Marek Kawczyński)
4Developers 2018: Unit testing - introduction (Marek Kawczyński)
 
[PL] Jak programować aby nie zwariować?
[PL] Jak programować aby nie zwariować?[PL] Jak programować aby nie zwariować?
[PL] Jak programować aby nie zwariować?
 
Testy wydajnościowe - najlepsze praktyki - Kuba Gajda
Testy wydajnościowe - najlepsze praktyki - Kuba GajdaTesty wydajnościowe - najlepsze praktyki - Kuba Gajda
Testy wydajnościowe - najlepsze praktyki - Kuba Gajda
 
Od codziennej higieny do strategicznej refaktoryzacji
Od codziennej higieny do strategicznej refaktoryzacjiOd codziennej higieny do strategicznej refaktoryzacji
Od codziennej higieny do strategicznej refaktoryzacji
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPl
 
Kwestionowanie ISTQB
Kwestionowanie ISTQBKwestionowanie ISTQB
Kwestionowanie ISTQB
 
Testowanie na 101 sposobów
Testowanie na 101 sposobówTestowanie na 101 sposobów
Testowanie na 101 sposobów
 
Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16
Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16
Integracja środowiska testowego z użyciem Robot Framework, TrojQA 2014-12-16
 
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
 
Refaktoryzacja
RefaktoryzacjaRefaktoryzacja
Refaktoryzacja
 
Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?
 
Podstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptxPodstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptx
 
Unit testing w praktyce... czyli właściwie jak?
Unit testing w praktyce... czyli właściwie jak?Unit testing w praktyce... czyli właściwie jak?
Unit testing w praktyce... czyli właściwie jak?
 

More from allegro.tech

allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyceallegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech
 
Scaling infrastructure beyond containers
Scaling infrastructure beyond containersScaling infrastructure beyond containers
Scaling infrastructure beyond containers
allegro.tech
 
Microservices architecture pitfalls
Microservices architecture pitfallsMicroservices architecture pitfalls
Microservices architecture pitfalls
allegro.tech
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & design
allegro.tech
 
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
allegro.tech
 
Fighting with scale
Fighting with scaleFighting with scale
Fighting with scale
allegro.tech
 

More from allegro.tech (6)

allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyceallegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
 
Scaling infrastructure beyond containers
Scaling infrastructure beyond containersScaling infrastructure beyond containers
Scaling infrastructure beyond containers
 
Microservices architecture pitfalls
Microservices architecture pitfallsMicroservices architecture pitfalls
Microservices architecture pitfalls
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & design
 
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
 
Fighting with scale
Fighting with scaleFighting with scale
Fighting with scale
 

Confitura 2015 - Code Quality Keepers @ Allegro

  • 1. Code Quality Keepers opowieści z pola bitwy o jakość kodu Rafał Głowiński, Bartosz Walacik Confitura 2015
  • 2. O nas Rafał Głowiński @GlowinskiRafal Bartosz Walacik @BartoszWalacik http://javers.org
  • 3. O czym będziemy mówić Pytania: → Jak dbać o jakość kodu w zespole? Code review? → A co jeśli mamy 40+ zespołów? → Jak zadbać o jakość na poziomie całej organizacji?
  • 4. O czym będziemy mówić Opowiemy: → Po co CQK? → Jak zdefiniować kryteria jakości i ocenić kod różnych zespołów → Jak robimy prawdopodobnie największe Code Review w Polsce → Co udało nam się znaleźć: “perełki”, typowe błędy → A także… co udało nam się osiągnąć
  • 5. → 40+ zespołów (dev + infra) Zespoły w Allegro → 4 miasta (Poznań, Toruń, Warszawa, Kraków) → Często doświadczenie głównie w PHP → Większość pisze i utrzymuje mikrousługi na JVM
  • 6. Jak powstało CQK i po co? Pierwszy skład zespołu CQK: → doświadczeni inżynierowie → zaangażowani w community → autorytet nie hierarchia → kilka osób myślących podobnie, startup
  • 7. Jak powstało CQK i po co? Pierwszy Cel: Przejrzeć i ocenić (w miarę) obiektywnie cały kod Pierwsze review: → 1 dzień w 1 salce → kilkadziesiąt projektów do przejrzenia → 15 minut na projekt (!) → totalna partyzantka
  • 8. Jak powstało CQK i po co? Wnioski z pierwszego review: → 15 min na projekt to za mało → potrzebna jest metodyka i organizacja → koncentracja na wybranych aspektach Nowe Cele: → Cel 1: podnoszenie jakości kodu w całej organizacji poprzez review, feedback i mentoring → Cel 2: wkład do ocen technicznych zespołów
  • 9. Jak pracujemy → Zaczęliśmy od garstki osób, teraz jest nas więcej → Co kwartał zmieniamy metodykę review → Merytoryczny feedback → Przejście na tryb “push”
  • 10. Metodyka review: pierwszy kwartał “Wrażenia artystyczne” (15 min na projekt…)
  • 11. Metodyka review: drugi kwartał Duże i częste naruszenia podstawowych zasad Są błędy, ale generalnie jest ok Jest dobrze!
  • 12. Magic Servlet Antipattern is Back: → logika biznesowa/dostęp do repozytorium w kontrolerze → nieprawidłowe wykorzystanie frameworków (np. ręczne mapowanie wyjątków na kodu HTTP) Metodyka review: drugi kwartał Zwięzłość i czytelność testów: → struktura testów, prawidłowe wykorzystanie bibliotek → co testują testy → mocks (overmocking, mockowanie nie swoich klas)
  • 13. Szkolenia: trzeci kwartał → Naming i omówienie bytów w testach (Stub, Mock, Spy) → Spock: Data Driven, wyjątki, asercje, Groovy → (*) JUnit: Mockito, AssertJ, JUnitParams, catch-exception → Overmocking + verify = betonowy kod → Testy integracyjne: bazy danych, REST
  • 14. Zwięzłość i czytelność testów cd. Metodyka review: aktualnie Model domenowy: → klasy modelu → organizacja pakietów → powiązanie z bibliotekami / infrastrukturą
  • 15. Metodyka review: aktualnie Model domenowy: brak modelu domenowego: mutowalne & anemiczne POJO operujące na nich klasy Service
  • 16. Metodyka review: aktualnie Model domenowy: kod jest podzielony horyzontalnie domena powiązana z infrastrukturą (zapytania do baz danych, skomplikowane logowanie/monitoring, itp.) widać starania odejścia od anemiczności modelu (rozsądne podejście do mutowalności, obiekty zyskują funkcjonalności)
  • 17. Metodyka review: aktualnie Model domenowy: ładny model domenowy zgodny z OOP struktura pakietów zorientowana domenowo domena jest wyraźnie odseparowana od infrastruktury podział pakietowy zgodnie z wytycznymi np. Hexagonal Architecture
  • 18. Eksperyment: review kodu JS Opowiemy o tym za rok ;)
  • 19. Główna działalność CQK Tworzenie feedbacków dla zespołów → Zespół zgłasza do feedbacku projekt lub PR → Przeciętny projekt ma ~10KLOC
  • 20. Co to jest feedback Kilkustronicowy dokument na WIKI, lista punktów, np: dobre testy integracyjne (np BlacklistEndpointIntegrationSpec.groovy) SalesRegulationsFilterTest.java - do testu tego rodzaju prostych funkcji używajcie podejścia data-driven test Klasa Pdf.java mogłyby być immutable, czyli zamiast: Pdf pdf = new Pdf(); pdf .setContent(documentContent); lepiej Pdf pdf = new Pdf (documentContent); długa implementacja equals() w BlacklistRequest.java. Łatwo się pomylić w takim kodzie. Czy ten equals() jest do czegoś potrzebny?
  • 21. Fazy życia feedbacku: koszt os./h I. Review kodu + spisanie 2-3 II. Weryfikacja 1-2 III. Publikacja i uwagi od zespołu 1 IV. Przepracowanie w zespole 0 Jak powstaje feedback
  • 22. Faza I. Review kodu + spisanie uwag → Keeper klonuje repo i ogląda kod → Nie uruchamiamy tooli do statycznej analizy → Keeper tworzy dokument feedbacku i proponuje ocenę Jak powstaje feedback
  • 23. Faza II. Weryfikacja → Drugi Keeper przegląda feedback (kontrola merytoryczna) → Przy rozbieżnościach - uzgadniamy w ramach CQK → Kontrola czy feedback jest friendly → Drugi Keeper często dopisuje swoje uwagi → Approve Jak powstaje feedback
  • 24. Faza III. Publikacja i uwagi od zespołu → Feedback jest przekazywany do zespołu → Zachęcamy zespół do ustosunkowania się do feedback’u Czy modyfikujemy feedback? → Świadome i uzasadnione naruszenia reguł → My czegoś nie zrozumieliśmy (brak kontekstu) Jak powstaje feedback
  • 25. Faza IV. Przepracowanie feedbacku w zespole Mamy nadzieję, że zespół przekona się do naszych uwag i propozycji Jak powstaje feedback
  • 26. Co znaleźliśmy - big picture
  • 27. Co znaleźliśmy - big picture
  • 28. Główne grzechy: → TDD - Test Driven Development → Anemic Domain Model Co znaleźliśmy - big picture
  • 29. TDD - problemy: → Overmocking → Mocking What-You-Don’t-Own → Testy są kopią implementacji → Za mało testów integracyjnych → Testy pisane pod Coverage → Testy bez wartości dokumentacyjnej → Testowanie implementacji a nie funkcjonalności Co znaleźliśmy - big picture
  • 30. Anemic Domain Model → Anemiczne, mutowalne Encje → Settery i gettery rządzą → Programowanie proceduralne nie obiektowe → Często w ogóle brak wydzielonego Modelu Domenowego Co znaleźliśmy - big picture
  • 31. Test unitowy prostego konstruktora Co znaleźliśmy - ‘perełki’
  • 32. public class ClientException extends RuntimeException { static final long serialVersionUID = -712897190232112939L; public ClientException(String message) { super(message); } public ClientException(String message, Throwable cause) { super(message, cause); } } src
  • 33. @Test public void shouldSetMessageAndCauseInConstructor() { //given String exceptedMessage = "Very bad exception"; Exception expectedCauseException = new Exception("This is cause exception"); //when ClientException exception = new ClientException(exceptedMessage, expectedCauseException); String message = exception.getMessage(); Throwable causeException = exception.getCause(); //then assertEquals(exceptedMessage, message); assertEquals(expectedCauseException, causeException); } test
  • 34. Nie testuj unitowo prostych konstruktorów oraz metod CQK radzi
  • 35. Test unitowy Serwisu-przelotki Co znaleźliśmy - ‘perełki’
  • 36. public class SaleRegulationsService { public List<SaleRegulations> findRegulations(String userId, Long timestamp) { List<SaleRegulations> results; if (timestamp == null) { results = salesRegulationsRepository.findOneByUserId(userId); } else { results = salesRegulationsRepository.findByUserId(userId); } return results; } ... } src
  • 37. @Test public void shouldReturnMoreResultsWhenTimestampIsGiven() { // given SaleRegulationsService saleRegulationsService =new SaleRegulationsService(salesRegulationsRepository, eventProducer); SaleRegulations saleRegulations1 =new SaleRegulations(USER_ID, SALE_REGULATIONS_TEXT, TIMESTAMP); SaleRegulations saleRegulations2 =new SaleRegulations(USER_ID, SALE_REGULATIONS_TEXT_VERSION_2, TIMESTAMP2); List<SaleRegulations> results =new ArrayList<>(); results.add(saleRegulations1); results.add(saleRegulations2); when(salesRegulationsRepository.findByUserId(USER_ID)).thenReturn(results); // when List<SaleRegulations> regulations = saleRegulationsService.findRegulations(USER_ID, TIMESTAMP); // then assertThat(regulations.size()).isEqualTo(2); assertThat(regulations.get(0)).isEqualTo(saleRegulations1); ... test
  • 38. Nie testuj unitowo metod typu przelotka. Testuj integracyjnie, używając Embedded (lub Fake) DB CQK radzi
  • 40. @RunWith(MockitoJUnitRunner. class) public class CreateEndpointTest { @Mock private RefundsSoapBindingStub npRefundService; @Mock private RefundsClient refundsClient; @Mock private PayuOrders payuOrders; @Mock private SignatureFactory signatureFactory; @Mock private RefundInfo refundInfoMock; ... test
  • 41. unikaj Mocków z verify(), to betonowanie kodu CQK radzi
  • 43. Najczęstsze błędy Wstrzykiwanie zależności: pola vs konstruktor: → Jasna deklaracja kolaboratorów → Rozróżnienie opcjonalnych zależności → Łatwiejsza konstrukcja obiektów w testach
  • 44. Najczęstsze błędy Niemutowalność: “Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible.” Joshua Bloch, Effective Java
  • 45. Najczęstsze błędy Mockowanie nie swoich rzeczy: (a.k.a: Don’t mock what you don’t own) → zmiany poza naszą kontrolą → podwójnie kosztowne (test / prod)
  • 46. → przekonaliśmy zespoły do zewnętrznego review → konwencja: should + given/when/then → przekonaliśmy większość zespołów do Spocka → zespoły piszą coraz lepsze testy integracyjne → Overmockingu mniej → zdecydowanie widać poprawę ogólnej jakości kodu Sukcesy
  • 47. → review w ramach jednego zespołu często nie wystarcza → potrzeba systematyczności - jednorazowy zryw to za mało → otwartość na feedback → cierpliwość - efekty nie przyjdą od razu Wnioski
  • 48. Q/A?
  • 49. Znajdziesz nas: Blog: allegrotech.io Twitter: @allegrotechblog pracuj z nami kariera.allegro.pl