23 marca 2011

Myśl inaczej

Metody agil'owe powstały jak odwrócenie sposobu myślenia, do metod kaskadowych. To co odniosło niesamowity sukces w fabrykach Forda, bardzo źle się sprawdza w przypadku produkcji oprogramowania. Znikoma liczba stałych elementów, "niewielka" modyfikacja przez klienta wymagań w czasie zaawansowanych pracy, albo niewykryty błąd projektowy, w jednym z modułów, często zmusza, do przeprojektowani całej architektury i wyrzuceniu dużej części tego co już stworzyliśmy. Agile to filozofia, która każe przyjąć pewien sposób myślenia: bądź otwarty na komunikację, pracę zespołową, samoorganizowanie, bądź otwarty na zmiany! Filozofia nie należy mylić ze sposobem postępowania.

Manifest Zwinnego Tworzenia Oprogramowania
* Ludzie i interakcje ponad procesami i narzędziami
* Działające produkty ponad złożoną dokumentację
* Współpraca z klientem ponad negocjacją kontraktu
* Reagowanie na zmiany ponad trzymaniem się planu

Filozofia Agile każe oswoić się ze zmiennymi wymaganiami klienta, bo każda zmiana jest dobra. Nie odbywa się to kosztem planu. Plan musi być dostosowywany za każdym razem do zmieniający się warunków środowiska.

Z filozofii Agile, wykuto kilka metod np.:
* Scrum (młyn w rugby) - metoda zarządzani projektami (nie tylko informatycznymi - scrum nie opisuje procesu wytwarzania oprogramowania, dlatego jest dopełniana czymś innym np. Extreme Programming)
* Extreme Programming (często stanowi dopełnienie metody Scrum), oparte na 4 wartościach: komunikacja, postacie, informacje zwrotna, odwaga.
* inne

Największą popularność zdobywa ostatnio Scrum:
- stawia na samoorganizację zespołów.
- "Sprint" - realizacja projektu w krótkich iteracjach (2 do 4 tyg. maks), wszystkie sprinty powinny mieć stałą długość
- "Daily Scrums" codzienne 15 minutowe spotkanie projektowe, gdzie każdy ma dać odpowiedź na pytania
* co robiłem wczoraj
* co będę robił dzisiaj
* czy występują problemy blokujące dalszą pracę
- spotkanie planistyczne na początku każdej iteracji
- prezentacja wyników iteracji wszystkim zainteresowanym
- podsumowanie przebiegu prac iteracji

Scrum definiuje także kilka ról projektowych:
- Scrum Master - (Mistrz Młyna) - trener, pomagający członkom zespołu  w osiągnięciu najlepszej wydajności
- Product Owner - właściciel produktu, reprezentuje biznes, klientów lub użytkowników, pomaga zrozumieć ich punkt widzenia
- The Team - samoorganizujacy się zespół (5-9 osób)

Wzniosłe idee, ale całej tej filozofii, zagrażają całkiem ludzkie przywary.

Cała drużyna pracuje nad wspólnym sukcesem. W zespole wszyscy mają być równi, nie można dopuścić by jednostki dominujące, próbowały wpływać/dodawać nieformalnej roboty, jednostkom słabszym. To samo tyczy się wojen programista vs tester. Spóźnienia, absencje, żarty, monologi, podczas "Daily Scrums" wpływają na obniżenie morale w całym zespole. Preferowana jest komunikacja werbalna ponad formalną, a z lenistwa, ktoś może odmówić, jeżeli nie będzie miał czegoś na papierze.


Jeżeli w zespole, będzie zdrowa i otwarta komunikacja, sami się przekonamy, że mamy tam ludzi pełnych energii i chęci życia. Aj hołp.

Testy jednostkowe

Ot zainteresowałem się ostatnio testami jednostkowymi. W moim przypadku wybór padł na CppUnit. Moja obecna platforma to Windows+Eclipse+cygwin więc, instalacji dokonałem właśnie za pośrednictwem cygwin-a
      
Devel | cppunit: C++ unit testing framework (1.12.1-1)
      
Aby dołączyć bibliotekę do środowiska Eclipse skorzystałem z tego artykułu
* http://beans.seartipy.com/2007/11/26/unit-testing-c-programs-using-cppunit-in-eclipse-ide-on-windows/
      
Znalazłem tylko dwa oficjalne artykuły traktujące o tym jak to trzeba ugryźć, ale przykład był dla mnie za mały, żebym czuł, że wszystko do mnie trafiło.
* http://cppunit.sourceforge.net/doc/1.11.6/cppunit_cookbook.html
* http://cppunit.sourceforge.net/doc/1.11.6/money_example.html
      
Mniej więcej, tworzymy klasy dziedziczące po TestFixture, do których zadań należy przetestowania pojedynczej klasy lub jakiejś funkcjonalności. W środku TextFixture tworzymy obiekt TestSuite, w którym zbieramy wskaźniki do metod, które to z kolei, służą do właściwego testowania.
      
Składać (TestSuite) możemy klepiąc kod, albo korzystając z makr (szybsze i bezpieczniejsze rozwiązanie):
      
CPPUNIT_TEST_SUITE( FluTest );
CPPUNIT_TEST( testTemerature );
CPPUNIT_TEST( testNose );
CPPUNIT_TEST_SUITE_END();


A w owych metodach testujących korzystamy z makr np.
CPPUNIT_ASSERT(warunek)
CPPUNIT_ASSERT_EQUAL(expected, actual)

Więcej tutaj:
* http://cppunit.sourceforge.net/doc/1.11.6/group___assertions.html
      
Są jeszcze inne fajne rzeczy jak, np. drukowanie raportów o testach do xml-a, ale ...
      
Wtyczka do CppUnit (ECUT) dla Eclipse.
      
Przy okazji znalazłem na googlu coś takiego jak ECUT
* http://sourceforge.net/projects/ecut/
czyli coś go generowania "szablonów kodu testującego" na podstawie kodu właściwego.
Ładnie też pokazuje jak się testy wykonały.
Wtyczkę (ECUT_1.0_M3-RC3a) zainstalowałem, posiłkując się opisem z:
* http://xrigher.co.cc/cpp/set-up-cppunit-eclipse-plugin-ecut-for-c-on-ubuntu/
     
Podczas konfiguracji wybrałem libcppunit.a, a miałem jeszcze do wyboru libcppunit.dll.a, ale poszło. Nie znalazłem żadnej "papierowej" dokumentacji, bo też jej bardzo nie szukałem. Za to po ściągnięciu EcutDemo_M3.zip ze strony projektu, znalazłem w środku przykład wraz z wideo tutorialem :D
     
Podsumowanie.
ECUT ciekawy, choć niby testy powinny być pisane, przed napisaniem właściwego kodu. Unit testy/CppUnit, hmm dobre, ale trzeba pamiętać o przetestowaniu każdej małej jednostki (metody/funkcji/klasy ?). Jak zabierzemy się tylko za te większe, to błędów możemy szukać jak zwykle ...
     
A mi się śni w szybkim tworzenia kod, WYBIÓRCZE składowanie w UnitTestach danych przykładowych (wykorzystywanych przy debugowaniu), dla niektórych metod, wtedy po naprawach mógłbym sprawdzić czy czegoś nie popsułem. Hmm, czasem przy debugu złożonych metod, musiałem wewnątrz ciała dużej metody coś za hard-kodować, ciekawe czy jakby mój sen nie był wybiórczy, to bym się przed tym ustrzegł?