Zvonimir Spajic
software developer
"Code without tests is bad code. It doesn't matter how well written it is; it doesn't matter how pretty or object-oriented or well-encapsulated it is. With tests, we can change the behaviour of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse." - Michael C. Feather, Working Effectively With Legacy Code
<?php
$I->amOnPage('/login');
$I->fillField('username', 'Ivica');
$I->fillField('password', 'Todoric');
$I->click('LOGIN');
$I->see('Welcome mister Todoric!');
<?php
/**
* @When I add a job named :jobName
* @param $jobName
*/
public function iAddAJobNamed($jobName)
{
$this->getSession()->visit('jobs');
$this->getSession()->clickLink('Add Job');
$this->getSession()->fillField('Name',$jobName);
$this->getSession()->clickLink('Save');
}
Scenario:
When I add a job named "Direktor Agrokora"
Then I should see "Direktor Agrokora" in jobs list
<?php
public function testAddingToBasket()
{
$basket = new Basket(new Storage());
$basket->add('Test Product');
$this->assertContains('Test Product', $basket->getProducts());
}
Scenario:
When I add a job named "Direktor Agrokora"
Then I should see "Direktor Agrokora" in jobs list
<?php
/**
* @When I add a job named :jobName
* @param $jobName
*/
public function iAddAJobNamed($jobName)
{
$this->jobList->addJob($jobName);
}
/**
* @Then I should see a :jobName
* @param $jobName
*/
public function iShouldSeeA($jobName)
{
assert(in_array($jobName,$this->jobList->getJobs());
}
<?php
public function testAddition()
{
$calculator = new Calculator();
$calculator->add(3,3);
$this->assertEquals(6,$calculator->getResult());
}
public function testMultiplication()
{
$calculator = new Calculator();
$calculator->multiply(3,3);
$this->assertEquals(9,$calculator->getResult());
}
<?php
class FooService
{
// ...
public function getMessage()
{
$data = $this->callsProvider->getCalls();
return $this->generateMessage($data);
}
private function generateMessage($data)
{
// do some data processing and generate message
}
}
<?php
public function testForNoCalls()
{
$callProvider = $this->createMock(CallsProvider::class);
$callProvider->method('getCalls')
->willReturn('{"data":[]}');
$fooService = new FooService($callProvider);
$message = $fooService->getMessage();
$this->assertEquals('Sorry, no messages for you', $message);
}
Test Double - a "fake" object that has the same public API as the object it is "faking"
|
<?php
public function it_returns_propper_for_multiple_calls(CallsProvider $callsProvider)
{
$callsProvider->getCalls()
->willReturn('{"data":["Davor","Zdravko","Kolinda"]}');
$this->getMessage()->shouldBe('You Have 3 messages');
}
When we are writing a test in which we cannot (or chose not to) use a real depended-on component (DOC), we can replace it with a Test Double. The Test Double doesn't have to behave exactly like the real DOC; it merely has to provide the same API as the real one so that the SUT thinks it is the real one!
Testing Evolution:
?