SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Symfony Testing
Basel Issmail
basel.issmail@gmail.com
Why Testing?
Prevent Bugs. (Reputation)
Prevent Fixing same Bugs more than once. (add additional cases each time)
Faster than manual testing.
Additional Documentation.
Upgrading your platform? Refactoring your Code? NO PROBLEM
Keeping your code quality.. Spaghetti Code is not testable ;)
Making QA jobless
1- Unit Testing
Unit tests are used to test your “business logic”
If you want the design
of your code to be
better
... write Unit Tests
“Symfony Live London 2015 - Ciaran McNulty”
Most Used Assertions
AssertTrue/AssertFalse
AssertEquals
(AssertGreaterThan, LessThan)
(GreaterThanOrEqual, LessThanOrEqual)
AssertContains
AssertType
AssertNull
AssertFileExists
AssertRegExp
<?php
namespace TDD;
class Receipt {
public function total(array $items = []) {
return array_sum($items);
}
}
<?php
namespace TDDTest;
use PHPUnitFrameworkTestCase;
use TDDReceipt;
class ReceiptTest extends TestCase {
public function testTotal() {
$Receipt = new Receipt();
$this->assertEquals(
14,
$Receipt->total([0,2,5,8]),
'When summing the total should equal 15'
);
}
}
PHPUnit outcomes
.
Printed when the test succeeds.
F
Printed when an assertion fails while running the test method.
E
Printed when an error occurs while running the test method.
S
Printed when the test has been skipped.
I
Printed when the test is marked as being incomplete or not yet implemented
PhpUnit Command line
Phpunit
--filter=
--testsuite= <name,...>
--coverage-html <dir>
Other configurations are imported from phpunit.xml (next slide)
#
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="app/autoload.php" backupGlobals="false" colors="true" verbose="true"
stopOnFailure="false">
<php>
<server name="KERNEL_DIR" value="/app/" />
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
</php>
<testsuites>
<!-- compose tests into test suites -->
<testsuite name="Project Test Suite">
<!-- You can either choose directory or single files -->
<directory>tests</directory>
<file>tests/General/ApplicationAvailabilityFunctionalTest.php</file>
</testsuite>
</testsuites>
<!--- This part is for code coverage (choose which directory to check and which to execlude from
coverage)-->
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src/AcmeBundle/Repository</directory>
<exclude>
<directory suffix=".php">./src/AcmeBundle/Tests</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
Arrange-Act-Assert
General Principles
Test In Isolation
Test on thing per Function
If hard to test, reimplement your code
class ReceiptTest extends TestCase {
public function setUp() {
$this->Receipt = new Receipt();
}
public function tearDown() {
unset($this->Receipt);
}
public function testTotal() {
//arrange
$input = [0,2,5,8];
//ACT
$output = $this->Receipt->total($input);
//Assert
$this->assertEquals(
15,
$output,
'When summing the total should equal 15');
}}
//Test Function
public function testTax() {
$inputAmount = 10.00;
$taxInput = 0.10;
$output = $this->Receipt->tax($inputAmount, $taxInput);
$this->assertEquals(
1.00,
$output,
'The tax calculation should equal 1.00'
);
}
//Actual Function
public function tax($amount, $tax) {
return ($amount * $tax);
}
Data Providers
/**
* @dataProvider provideTotal
*/
public function testTotal($items, $expected) {
$coupon = null;
$output = $this->Receipt->total($items, $coupon);
$this->assertEquals(
$expected,
$output,
"When summing the total should equal {$expected}"
);
}
public function provideTotal() {
return [
[[1,2,5,8], 16],
[[-1,2,5,8], 14],
[[1,2,8], 11],
];
}
Test Doubles
Replace Dependency (Isolation)
Ensure a condition occurs
Improve the performance of our tests
Dummy
Fake
Stub
Spy
Mock
Dummy
● Dummy objects are passed around but never actually used. Usually they are
just used to fill parameter lists.
Eg: empty $config array
Fake
● Fake objects actually have working implementations, but usually take some
shortcut which makes them not suitable for production.
Eg: in memory database
Stub
● Stubs provide canned answers to calls made during the test, usually not
responding at all to anything outside what's programmed in for the test.
Eg: stub for isConnected() which returns false.
Spy
● Spies are stubs that also record some information based on how they were
called.
Eg: an email service that records how many messages it was sent.
Mock
● Mocks objects pre-programmed with expectations which form a specification
of the calls they are expected to receive.
public function total(array $items = [], $coupon) {
$sum = array_sum($items);
if (!is_null($coupon)) {
return $sum - ($sum * $coupon);
}
return $sum;
}
public function testTotal() {
$input = [0,2,5,8];
$coupon = null;
$output = $this->Receipt->total($input, $coupon);
$this->assertEquals(
15,
$output,
'When summing the total should equal 15'
);
}
public function testTotalAndCoupon() {
$input = [0,2,5,8];
$coupon = 0.20;
$output = $this->Receipt->total($input, $coupon);
$this->assertEquals(
12,
$output,
'When summing the total should equal 12'
);
}
Dummy
public function total(array $items = [], $coupon) {
$sum = array_sum($items);
if (!is_null($coupon)) {
return $sum - ($sum * $coupon);
}
return $sum;
}
public function tax($amount, $tax) {
return ($amount * $tax);
}
public function postTaxTotal($items, $tax, $coupon) {
$subtotal = $this->total($items, $coupon); //total -> 10
$subtotal += $tax;
return $subtotal + $this->tax($subtotal, $tax); //tax -> 1
}
public function testPostTaxTotal () {
$Receipt = $this->getMockBuilder('TDDReceipt')
->setMethods(['tax', 'total'])
->getMock();
$Receipt->method('total')
->will($this->returnValue(10.00));
$Receipt->method('tax')
->will($this->returnValue(1.00));
$result = $Receipt->postTaxTotal([1,2,5,8], 0.20, null);
$this->assertEquals(11.00, $result);
}
Stub
public function testPostTaxTotal () {
$items = [1,2,5,8];
$tax = 0.20;
$coupon = null;
$Receipt = $this->getMockBuilder ('TDDReceipt' )
-> setMethods(['tax', 'total'])
-> getMock();
$Receipt->expects($this->once())
-> method('total')
-> with($items, $coupon)
-> will($this->returnValue(10.00));
$Receipt->expects($this->once())
-> method('tax')
-> with(10.00, $tax)
-> will($this->returnValue(1.00));
$result = $Receipt->postTaxTotal([1,2,5,8], 0.20, null);
$this->assertEquals(11.00, $result);
}
Mock
TDD
Write Test, Run Test, Write Code, Run Test, Repeat Until Completed
Data Fixtures
php bin/console doctrine:fixtures:load
class LoadJobsData extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $manager)
{
$user = $manager->getRepository('UserBundle:User')->findBy(array('username' => 'friik'));
$organization = $manager->getRepository('JobsBundle:Organization')->findBy(array('name' =>
'friikcom'));
$job = new Job();
$job->setCreatedBy($user[0]);
$job->setCreatedAt();
$job->setStartDate(new DateTime());
$job->setEndDate(new DateTime('+1 week'));
$job->setActive(1);
$job->setJobCaption('new job for all interested');
$job->setEmplType(2);
$job->setOrganization($organization[0]);
$manager->persist($job);
$manager->flush();
}
public function getOrder()
{
return 4;
}
}
protected function setUp()
{
self::bootKernel();
$this->em = static::$kernel->getContainer()
->get('doctrine')
->getManager();}
public function testFindAllJobsOrderedByDateReturnsResults()
{
$expectedOutput = 2;
$job = $this->em
->getRepository('JobsBundle:Job')
->findAllJobsOrderedByDate()->getResult(Query::HYDRATE_ARRAY);
$this->assertCount($expectedOutput, $job);
}
protected function tearDown()
{
parent::tearDown();
$this->em->close();
$this->em = null; // avoid memory leaks
}
}
2- Functional Testing
check the integration of the different layers of an
application
Define a client then Request
/**
* @dataProvider urlProvider
*/
public function testPageIsSuccessful($url)
{
$client = self::createClient();
$client->request('GET', $url);
$this->assertTrue($client->getResponse()->isSuccessful());
}
public function urlProvider()
{
return array(
array('/jobs'),
array('/jobs/organization/show'),
array('/jobs/organization/add'),
array('/jobs/organization/check'),
);
public function testIndexPageRequestAuthorized()
{
$client = static::createClient();
$crawler = $client->request('GET', '/jobs/job', array(), array(), array(
'PHP_AUTH_USER' => 'friik',
'PHP_AUTH_PW' => 'friikfriik',
));
$crawler = $client->followRedirect();
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
}
Authorized client
public function testOrganizationShowExampleTests()
{
$client = static::createClient();
$crawler = $client->request('GET', '/jobs/organization/show');
$response = $client->getResponse();
//Status Code
// $this->assertEquals(200, $response->getStatusCode());
//Check if page contains content
//$this->assertContains('company', $response->getContent());
$img = $crawler->filterXPath('//img');
$atr = $img->attr('src');
//check for alt attr in image tags
$crawler->filter('img')->each(function ($node, $i) {
$alt = $node->attr('alt');
$this->assertNotNull($alt);
});
}

Contenu connexe

Tendances

Tendances (20)

Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Chaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscoreChaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscore
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
PHP Conference Asia 2016
PHP Conference Asia 2016PHP Conference Asia 2016
PHP Conference Asia 2016
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
php 2 Function creating, calling, PHP built-in function
php 2 Function creating, calling,PHP built-in functionphp 2 Function creating, calling,PHP built-in function
php 2 Function creating, calling, PHP built-in function
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leet
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
PHP 8.1: Enums
PHP 8.1: EnumsPHP 8.1: Enums
PHP 8.1: Enums
 
Php Chapter 1 Training
Php Chapter 1 TrainingPhp Chapter 1 Training
Php Chapter 1 Training
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 

Similaire à Symfony (Unit, Functional) Testing.

Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
ferca_sl
 

Similaire à Symfony (Unit, Functional) Testing. (20)

Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Practical approach for testing your software with php unit
Practical approach for testing your software with php unitPractical approach for testing your software with php unit
Practical approach for testing your software with php unit
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Lessons learned from functional programming
Lessons learned from functional programmingLessons learned from functional programming
Lessons learned from functional programming
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Google guava
Google guavaGoogle guava
Google guava
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscore
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 

Plus de Basel Issmail

Plus de Basel Issmail (10)

Intro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSSIntro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSS
 
Intro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSSIntro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSS
 
Intro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSSIntro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSS
 
Intro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSSIntro to Web Development Part 1: HTML + CSS
Intro to Web Development Part 1: HTML + CSS
 
Oracle Database
Oracle DatabaseOracle Database
Oracle Database
 
Eclipse
EclipseEclipse
Eclipse
 
PhpStorm
PhpStormPhpStorm
PhpStorm
 
Visual Paradigm
Visual ParadigmVisual Paradigm
Visual Paradigm
 
Visual Studio
Visual StudioVisual Studio
Visual Studio
 
Social Network Website 'Midterm Project'
Social Network Website 'Midterm Project'Social Network Website 'Midterm Project'
Social Network Website 'Midterm Project'
 

Dernier

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Dernier (20)

VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 

Symfony (Unit, Functional) Testing.

  • 2.
  • 3. Why Testing? Prevent Bugs. (Reputation) Prevent Fixing same Bugs more than once. (add additional cases each time) Faster than manual testing. Additional Documentation. Upgrading your platform? Refactoring your Code? NO PROBLEM Keeping your code quality.. Spaghetti Code is not testable ;) Making QA jobless
  • 4. 1- Unit Testing Unit tests are used to test your “business logic”
  • 5. If you want the design of your code to be better ... write Unit Tests “Symfony Live London 2015 - Ciaran McNulty”
  • 6. Most Used Assertions AssertTrue/AssertFalse AssertEquals (AssertGreaterThan, LessThan) (GreaterThanOrEqual, LessThanOrEqual) AssertContains AssertType AssertNull AssertFileExists AssertRegExp
  • 7. <?php namespace TDD; class Receipt { public function total(array $items = []) { return array_sum($items); } }
  • 8. <?php namespace TDDTest; use PHPUnitFrameworkTestCase; use TDDReceipt; class ReceiptTest extends TestCase { public function testTotal() { $Receipt = new Receipt(); $this->assertEquals( 14, $Receipt->total([0,2,5,8]), 'When summing the total should equal 15' ); } }
  • 9.
  • 10. PHPUnit outcomes . Printed when the test succeeds. F Printed when an assertion fails while running the test method. E Printed when an error occurs while running the test method. S Printed when the test has been skipped. I Printed when the test is marked as being incomplete or not yet implemented
  • 11. PhpUnit Command line Phpunit --filter= --testsuite= <name,...> --coverage-html <dir> Other configurations are imported from phpunit.xml (next slide) #
  • 12. <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="app/autoload.php" backupGlobals="false" colors="true" verbose="true" stopOnFailure="false"> <php> <server name="KERNEL_DIR" value="/app/" /> <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" /> </php> <testsuites> <!-- compose tests into test suites --> <testsuite name="Project Test Suite"> <!-- You can either choose directory or single files --> <directory>tests</directory> <file>tests/General/ApplicationAvailabilityFunctionalTest.php</file> </testsuite> </testsuites>
  • 13. <!--- This part is for code coverage (choose which directory to check and which to execlude from coverage)--> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./src/AcmeBundle/Repository</directory> <exclude> <directory suffix=".php">./src/AcmeBundle/Tests</directory> </exclude> </whitelist> </filter> </phpunit>
  • 15. General Principles Test In Isolation Test on thing per Function If hard to test, reimplement your code
  • 16. class ReceiptTest extends TestCase { public function setUp() { $this->Receipt = new Receipt(); } public function tearDown() { unset($this->Receipt); } public function testTotal() { //arrange $input = [0,2,5,8]; //ACT $output = $this->Receipt->total($input); //Assert $this->assertEquals( 15, $output, 'When summing the total should equal 15'); }}
  • 17. //Test Function public function testTax() { $inputAmount = 10.00; $taxInput = 0.10; $output = $this->Receipt->tax($inputAmount, $taxInput); $this->assertEquals( 1.00, $output, 'The tax calculation should equal 1.00' ); } //Actual Function public function tax($amount, $tax) { return ($amount * $tax); }
  • 18. Data Providers /** * @dataProvider provideTotal */ public function testTotal($items, $expected) { $coupon = null; $output = $this->Receipt->total($items, $coupon); $this->assertEquals( $expected, $output, "When summing the total should equal {$expected}" ); } public function provideTotal() { return [ [[1,2,5,8], 16], [[-1,2,5,8], 14], [[1,2,8], 11], ]; }
  • 19. Test Doubles Replace Dependency (Isolation) Ensure a condition occurs Improve the performance of our tests Dummy Fake Stub Spy Mock
  • 20. Dummy ● Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists. Eg: empty $config array
  • 21. Fake ● Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production. Eg: in memory database
  • 22. Stub ● Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Eg: stub for isConnected() which returns false.
  • 23. Spy ● Spies are stubs that also record some information based on how they were called. Eg: an email service that records how many messages it was sent.
  • 24. Mock ● Mocks objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
  • 25. public function total(array $items = [], $coupon) { $sum = array_sum($items); if (!is_null($coupon)) { return $sum - ($sum * $coupon); } return $sum; }
  • 26. public function testTotal() { $input = [0,2,5,8]; $coupon = null; $output = $this->Receipt->total($input, $coupon); $this->assertEquals( 15, $output, 'When summing the total should equal 15' ); } public function testTotalAndCoupon() { $input = [0,2,5,8]; $coupon = 0.20; $output = $this->Receipt->total($input, $coupon); $this->assertEquals( 12, $output, 'When summing the total should equal 12' ); } Dummy
  • 27. public function total(array $items = [], $coupon) { $sum = array_sum($items); if (!is_null($coupon)) { return $sum - ($sum * $coupon); } return $sum; } public function tax($amount, $tax) { return ($amount * $tax); } public function postTaxTotal($items, $tax, $coupon) { $subtotal = $this->total($items, $coupon); //total -> 10 $subtotal += $tax; return $subtotal + $this->tax($subtotal, $tax); //tax -> 1 }
  • 28. public function testPostTaxTotal () { $Receipt = $this->getMockBuilder('TDDReceipt') ->setMethods(['tax', 'total']) ->getMock(); $Receipt->method('total') ->will($this->returnValue(10.00)); $Receipt->method('tax') ->will($this->returnValue(1.00)); $result = $Receipt->postTaxTotal([1,2,5,8], 0.20, null); $this->assertEquals(11.00, $result); } Stub
  • 29. public function testPostTaxTotal () { $items = [1,2,5,8]; $tax = 0.20; $coupon = null; $Receipt = $this->getMockBuilder ('TDDReceipt' ) -> setMethods(['tax', 'total']) -> getMock(); $Receipt->expects($this->once()) -> method('total') -> with($items, $coupon) -> will($this->returnValue(10.00)); $Receipt->expects($this->once()) -> method('tax') -> with(10.00, $tax) -> will($this->returnValue(1.00)); $result = $Receipt->postTaxTotal([1,2,5,8], 0.20, null); $this->assertEquals(11.00, $result); } Mock
  • 30. TDD Write Test, Run Test, Write Code, Run Test, Repeat Until Completed
  • 31. Data Fixtures php bin/console doctrine:fixtures:load class LoadJobsData extends AbstractFixture implements OrderedFixtureInterface { public function load(ObjectManager $manager) { $user = $manager->getRepository('UserBundle:User')->findBy(array('username' => 'friik')); $organization = $manager->getRepository('JobsBundle:Organization')->findBy(array('name' => 'friikcom'));
  • 32. $job = new Job(); $job->setCreatedBy($user[0]); $job->setCreatedAt(); $job->setStartDate(new DateTime()); $job->setEndDate(new DateTime('+1 week')); $job->setActive(1); $job->setJobCaption('new job for all interested'); $job->setEmplType(2); $job->setOrganization($organization[0]); $manager->persist($job); $manager->flush(); } public function getOrder() { return 4; } }
  • 33. protected function setUp() { self::bootKernel(); $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager();} public function testFindAllJobsOrderedByDateReturnsResults() { $expectedOutput = 2; $job = $this->em ->getRepository('JobsBundle:Job') ->findAllJobsOrderedByDate()->getResult(Query::HYDRATE_ARRAY); $this->assertCount($expectedOutput, $job); } protected function tearDown() { parent::tearDown(); $this->em->close(); $this->em = null; // avoid memory leaks } }
  • 34. 2- Functional Testing check the integration of the different layers of an application
  • 35. Define a client then Request /** * @dataProvider urlProvider */ public function testPageIsSuccessful($url) { $client = self::createClient(); $client->request('GET', $url); $this->assertTrue($client->getResponse()->isSuccessful()); } public function urlProvider() { return array( array('/jobs'), array('/jobs/organization/show'), array('/jobs/organization/add'), array('/jobs/organization/check'), );
  • 36. public function testIndexPageRequestAuthorized() { $client = static::createClient(); $crawler = $client->request('GET', '/jobs/job', array(), array(), array( 'PHP_AUTH_USER' => 'friik', 'PHP_AUTH_PW' => 'friikfriik', )); $crawler = $client->followRedirect(); $response = $client->getResponse(); $this->assertEquals(200, $response->getStatusCode()); } Authorized client
  • 37. public function testOrganizationShowExampleTests() { $client = static::createClient(); $crawler = $client->request('GET', '/jobs/organization/show'); $response = $client->getResponse(); //Status Code // $this->assertEquals(200, $response->getStatusCode()); //Check if page contains content //$this->assertContains('company', $response->getContent()); $img = $crawler->filterXPath('//img'); $atr = $img->attr('src'); //check for alt attr in image tags $crawler->filter('img')->each(function ($node, $i) { $alt = $node->attr('alt'); $this->assertNotNull($alt); }); }