practice my tic-tac-toe skills As a player I need to be able to start a new game Scenario: Choose to go first Given I have not started a game yet When I start a game as player "X" Then I should see an empty board
order to practice my tic-tac-toe skills As a player I need to be able to start a new game Scenario: Choose to go first Given I have not started a game yet When I start a game as player "X" Then I should see an empty board
have not started a game yet TODO: write pending definition When I start a game as player "X" Then I should see an empty board 1 scenario (1 pending) 3 steps (1 pending, 2 skipped) 0m0.03s (10.87Mb)
have not started a game yet When I start a game as player "X" TODO: write pending definition Then I should see an empty board 1 scenario (1 pending) 3 steps (1 passed, 1 pending, 1 skipped) 0m0.03s (10.87Mb)
users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.” – Alistair Cockburn • UI tests are slow and brittle. • Business logic always creeps into the user interface code. • Also known as “ports & adapters”.
the domain logic the system must perform and demonstrates that it performs them.” – Nat Pryce • Use Ports & Adapters to run acceptance-tests directly against the application domain model. • The domain model is cleanly decoupled from the technical infrastructure that connects it to the outside world.
than the lowest common denominator.” – Eric Evans • Domain experts should object to terms or structures that are awkward or inadequate to convey domain understanding • Developers should watch for ambiguity or inconsistency that will trip up design. Ubiquitous Language
your scenarios naturally become your domain model, which you can use to develop the most important part of your application - a core domain.” – Konstantin Kudryashov • Push for Ubiquitous Language in your scenarios. • Do Domain-Driven Design while you're doing the red- green-refactor cycle.
value is at. 2. The user interface and persistence should be an afterthought. 3. If it’s easy to test, it’s probably hexagonal. 4. Don’t test for things that are not in the Ubiquitous Language.
not started a game yet When I start a game as player "X" TODO: write pending definition Then I should see an empty board 1 scenario (1 pending) 3 steps (1 passed, 1 pending, 1 skipped) 0m0.03s (10.87Mb)
player :arg1 */ public function iStartAGameAsPlayer($arg1) { $command = new StartGameCommand(); $command->gameId = self::GAME_ID; $command->playerName = $arg1; $handler = new StartGameHandler(); $handler->handle($command); }
player :arg1 */ public function iStartAGameAsPlayer($arg1) { $command = new StartGameCommand(); $command->gameId = self::GAME_ID; $command->playerName = $arg1; $handler = new StartGameHandler(); $handler->handle($command); }
player :playerName */ public function iStartAGameAsPlayer($playerName) { $command = new StartGameCommand(); $command->gameId = self::GAME_ID; $command->playerName = $playerName; $handler = new StartGameHandler(); $handler->handle($command); }
not started a game yet When I start a game as player "X" Then I should see an empty board TODO: write pending definition 1 scenario (1 pending) 3 steps (2 passed, 1 pending) 0m0.03s (10.87Mb)
not started a game yet When I start a game as player "X" Then I should see an empty board Game with ID xxxxxxxx not found (RuntimeException) 1 scenario (1 failed) 3 steps (2 passed, 1 failed) 0m0.03s (10.87Mb)
informal way to refer to the whole family of objects that are used in tests. They are called Test Doubles.” – Robert C. Martin • Dummy • Stub • Fake • Spy • Mock
• A simple sentence template keeps test methods focused • An expressive test name is helpful when a test fails • “Behaviour” is a more useful word than “test” • JBehave PHPSpec emphasizes behaviour over testing • Determine the next most important behaviour • Requirements are behaviour, too • BDD provides a “ubiquitous language” for analysis • Acceptance criteria should be executable from Introducing BDD by Dan North
BankAccountTest PHPUnit 5.3.0 by Sebastian Bergmann and contributors. BankAccount [x] Should initially have a balance of zero [x] Should never have a negative balance
• I had introduced a bug. Bad me. Solution: Fix the bug. • The intended behaviour was still relevant but had moved elsewhere. Solution: Move the test and maybe change it. • The behaviour was no longer correct – the premise of the system had changed. Solution: Delete the test.
your code, they want the value of the software.” – Marcello Duarte • Determine what objects should do before you decide how they should do it. (See also: CRC cards.) • Objects expose behaviour, not data, so you have to tell them what to do with the data. (Tell, Don’t Ask)
as player :playerName */ public function iHaveStartedAGameAsPlayer($playerName) { $this->minkContext->visit('/'); $this->minkContext->pressButton(''); }
contributors. .E 2 / 2 (100%) Time: 1.35 seconds, Memory: 18.00Mb There was 1 error: 1) AppBundle\Repository\DoctrineGameRepositoryTest::shouldGetGames Doctrine\Common\Persistence\Mapping\MappingException: The class 'Application\Game\Game' was not found in the chain configured namespaces FAILURES! Tests: 2, Assertions: 2, Errors: 1.
In order to practice by myself As a player I want to play against the computer Scenario: Choose to go second Given I have not started a game yet When I start a game as player "O" Then I should see a board with one symbol on it Scenario: Computer makes the second move Given I have started a game as player "X" When I make a move Then I should see a board with two symbols on it