{"action":"created","issue":{"url":"https://api.github.com/repos/Glenpl/Sapper/issues/8","labels_url":"https://api.github.com/repos/Glenpl/Sapper/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/Glenpl/Sapper/issues/8/comments","events_url":"https://api.github.com/repos/Glenpl/Sapper/issues/8/events","html_url":"https://github.com/Glenpl/Sapper/issues/8","id":72315141,"number":8,"title":"Testy jednostkowe: BoardField","user":{"login":"MacDada","id":136261,"avatar_url":"https://avatars.githubusercontent.com/u/136261?v=3","gravatar_id":"","url":"https://api.github.com/users/MacDada","html_url":"https://github.com/MacDada","followers_url":"https://api.github.com/users/MacDada/followers","following_url":"https://api.github.com/users/MacDada/following{/other_user}","gists_url":"https://api.github.com/users/MacDada/gists{/gist_id}","starred_url":"https://api.github.com/users/MacDada/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MacDada/subscriptions","organizations_url":"https://api.github.com/users/MacDada/orgs","repos_url":"https://api.github.com/users/MacDada/repos","events_url":"https://api.github.com/users/MacDada/events{/privacy}","received_events_url":"https://api.github.com/users/MacDada/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-05-01T00:06:13Z","updated_at":"2015-05-01T11:39:35Z","closed_at":null,"body":"Kod się rozrasta i komplikuje, co raz więcej czasu spada na debugging i ręczne przechodzenie gry.\r\n\r\nCo robią programiści jak problem się powtarza? Automatyzują! :)\r\n\r\nI choć automatyzacja to jedno, nauka to drugie – TDD (test driven development) moim zdaniem jest **podstawowym** narzędziem prowadzącym do wysokiej jakości kodu, bo sprawia, że zaczynasz więcej myśleć o kompetencjach obiektów i o tym jak w ogóle sprawić, żeby były testowalne (a nieprzypadkowo kod testowalny posiada cechy kodu wysokiej jakości).\r\n\r\nJak nie bawiłeś się tym jeszcze, zacznij przy pisaniu [BoardField'a](https://github.com/Glenpl/Sapper/issues/5).\r\n\r\nTesty powinny sprawdzać zachowanie obiektu, więc przykładowy scenariusz:\r\n\r\n_BoardField can be marked and unmarked_\r\n\r\n1. Tworzysz obiekt `BoardField` (obojętne czy z bombą czy bez)\r\n2. Sprawdzasz że na starcie `is_marked()` zwraca `false`\r\n3. Odpalasz `mark()`\r\n4. Sprawdzasz, że `is_marked()` zwraca `true`\r\n5. Odpalasz `unmark()`\r\n6. Sprawdzasz, że `is_marked()` zwraca `false`\r\n\r\n_Revealed BoardField cannot be marked_\r\n\r\n1. Tworzysz obiekt `BoardField`, który nie jest bombą\r\n2. Odpalasz `reveal()` (czy tam `show()` czy jak tam nazwy w końcu :D)\r\n3. Odpalasz `mark()`\r\n4. Sprawdzasz, że wybucha błędem\r\n\r\n_j.w. dla `unmark()`_\r\n\r\n_itp wszystko co ten obiekt robi_\r\n\r\nTesty mają opisywać zachowanie. Czego się po tym obiekcie spodziewać? Jak go używać? Żywa dokumentacja :)"},"comment":{"url":"https://api.github.com/repos/Glenpl/Sapper/issues/comments/98110565","html_url":"https://github.com/Glenpl/Sapper/issues/8#issuecomment-98110565","issue_url":"https://api.github.com/repos/Glenpl/Sapper/issues/8","id":98110565,"user":{"login":"MacDada","id":136261,"avatar_url":"https://avatars.githubusercontent.com/u/136261?v=3","gravatar_id":"","url":"https://api.github.com/users/MacDada","html_url":"https://github.com/MacDada","followers_url":"https://api.github.com/users/MacDada/followers","following_url":"https://api.github.com/users/MacDada/following{/other_user}","gists_url":"https://api.github.com/users/MacDada/gists{/gist_id}","starred_url":"https://api.github.com/users/MacDada/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MacDada/subscriptions","organizations_url":"https://api.github.com/users/MacDada/orgs","repos_url":"https://api.github.com/users/MacDada/repos","events_url":"https://api.github.com/users/MacDada/events{/privacy}","received_events_url":"https://api.github.com/users/MacDada/received_events","type":"User","site_admin":false},"created_at":"2015-05-01T11:39:35Z","updated_at":"2015-05-01T11:39:35Z","body":"Google'uj, poczytaj trochę teorii na temat TDD. Poszukaj przykładów bibliotek, które mają napisane testy.\r\n\r\nTechnicznie dla `ccp` ciężko mi cokolwiek powiedzieć (google mi pokazuje np framework `CppUnit` – ale czy jest spoko, czy jest popularny – nie wiem – choć Martin Fowler wśród twórców brzmi obiecująco :)).\r\n\r\nIdea ogólna jest taka, że do każdej klasy, którą chcesz napisać, najpierw piszesz drugą klasę ją testującą.\r\n\r\nW kodzie testującym sprawdzasz czy klasa testowana działa jak jak chcesz.\r\n\r\n---\r\n\r\nNp, chcesz, żeby była taka klasa jak `BoardField`. Piszesz więc test, który sprawdza, że można utworzyć jej obiekt. I tyle.\r\n\r\nDalej, chciałbyś, żeby `BoardField` można było „oznaczyć” i „odznaczyć”. W teście więc „projektujesz” sobie jak chcesz korzystać z tej klasy. Możesz np napisać, że po wywołaniu metody `mark()`, metoda `is_marked()` powinna zwrócić `true`. I bierzesz się za implementację w klasie `BoardField`.\r\n\r\nPotem możesz chcieć, żeby klasa `BoardField` robiła X. Piszesz więc test, który sprawdza, że `BoardField` to robi. Potem piszesz implementację tak, żeby test przechodził.\r\n\r\nZapętlasz.\r\n\r\n---\r\n\r\nPewne rzeczy trudno przetestować (jak klasa robi za dużo, jak niejawnie korzysta z innych obiektów – np sam je sobie tworzy, jak robi efekty uboczne typu drukowanie na ekran; przede wszystkim jak robi „za dużo”, itp) – rzeczy, które trudno testować pokazują, gdzie jest błąd w dizajnie.\r\n\r\n---\r\n\r\nRóżnie bywa u mnie z testowaniem (na co dzień pracuję z archaicznym kodem, który jest ekstramalnie trudny do testowania), ale ostatnio siadłem do małego projektu, gdzie wszystko robię TDD.\r\n\r\nMożesz zobaczyć moje „specyfikacje” tutaj: https://github.com/MacDada/WykopAspieStats/tree/master/spec\r\n\r\nAle najlepiej znajdź przykłady w CPP :)"}}