SlideShare una empresa de Scribd logo
1 de 48
Descargar para leer sin conexión
Finding the Right Testing
Tool for the Job
Sebastian Bergmann and
Ciaran McNulty
Who are these guys?
3 Dimensions of Testing
Goal - why we are writing the test
Scope - how much of the system is involved in the test
Form - how we express the test
3 4 Dimensions of Testing
Goal - why we are writing the test
Scope - how much of the system is involved in the test
Form - how we express the test
Time - when we write the test
What we will talk about
— Characterisation Tests
— Acceptance Tests
— Integration Tests
— Unit Tests
Characterisation Tests
Characterisation Tests
Goals:
— Capture existing behaviour
— Find out when behaviour changes
Characterisation Tests
Scopes:
— Often at UI level
— Sometimes at object/service level
Characterisation Tests
Times:
— Always after implementation
Characterisation Tests
Best practice:
— Treat these tests as a temporary measure
— Use a tool that makes it easy to create tests
— Expect pain and suffering
Characterisation Tests
Form: Behat + MinkExtension builtin steps
Scenario: Product search returns results
Given I am on "/"
And I fill in "search" with "Blue jeans"
When I press "go"
Then I should see "100 Results Found"
Characterisation Tests
Form: PHPUnit + phpunit-mink-trait
class SearchTest extends PHPUnit_Framework_TestCase
{
use phpunitminkTestCaseTrait;
public function testProductSearchReturnsResult()
{
$page = $this->visit('http://example.com/');
$page->fillField('search', 'Blue Jeans');
$page->pressButton('go');
$this->assertContains('100 Results Found', $page->getText());
}
}
Characterisation Tests
Form: Selenium IDE
Characterisation Tests
Form: Ghost Inspector
Characterisation Tests
Form: PHPUnit + de-legacy-fy
See docs at on GitHub at
sebastianbergmann/de-legacy-fy
Acceptance Tests
Acceptance Tests
Goals:
— Match system behaviour to business requirements
— Get feedback on proposed implementations
— Understand business better
— Document behaviour for the future
Acceptance Tests
Scopes:
— At a UI layer
— At an API layer
— At the service layer
— Lower level may be too disconnected
Acceptance Tests
Times:
— Before implementation
— Before commitment (as long as it's not expensive?)
— Hard to write in retrospect
Acceptance Tests
Best practices:
— Get feedback on tests early
— Make them readable, or have readable output, for the
intended audience
— Apply for the smallest scope first
— Apply to core domain model first
— Minimise end-to-end tests
Acceptance Tests
Form: Behat at service level
Scenario: Sales tax is applied to basket
Given "Blue Jeans" are priced as €100 in the catalogue
When I add "Blue Jeans" to my shopping basket
Then the basket total should be €120
class BasketContext implements Context
{
public function __construct()
{
$this->catalogue = new InMemoryCatalogue();
$this->basket = new Basket($catalogue);
}
/**
* @Given :productName is/are priced as :cost in the catalogue
*/
public function priceProduct(ProductName $productName, Cost $cost)
{
$this->catalogue->price($productName, $cost);
}
//...
}
class BasketContext implements Context
{
//...
/**
* @When I add :productName to my shopping basket
*/
public function addProductToBasket(ProductName $productName)
{
$this->basket->add($productName);
}
/**
* @Then the basket total should be :cost
*/
public function checkBasketTotal(Cost $cost)
{
assert($this->basket->total == $cost->asInt());
}
}
Acceptance Tests
Form: PHPUnit at service level
class BasketTest extends PHPUnit_Framework_TestCase
{
public function testSalesTaxIsApplied()
{
$catalogue = new InMemoryCatalogue();
$basket = new Basket($catalogue);
$productName = new ProductName('Blue Jeans');
$catalogue->price($productName, new Cost('100'));
$basket->add($productName);
$this->assertEquals(new Cost('120'), $basket->calculateTotal());
}
}
Acceptance Tests
Form: PHPUnit at service level
Acceptance Tests
Form: Behat at UI level
Scenario: Sales tax is applied to basket
Given "Blue Jeans" are priced as €100 in the catalogue
When I add "Blue Jeans" to my shopping basket
Then the basket total should be €120
class BasketUiContext extends MinkContext
{
public function __construct()
{
$this->catalogue = new Catalogue(/* ... */);
}
/**
* @Given :productName is/are priced as :cost in the catalogue
*/
public function priceProduct(ProductName $productName, Cost $cost)
{
$this->catalogue->price($productName, $cost);
}
//...
}
class BasketUiContext extends MinkContext
{
//...
/**
* @When I add :productName to my shopping basket
*/
public function addProductToBasket(ProductName $productName)
{
$this->visitPath('/products/'.urlencode($productName));
$this->getSession()->getPage()->pressButton('Add to Basket');
}
/**
* @Then the basket total should be :cost
*/
public function checkBasketTotal(Cost $cost)
{
$this->assertElementContains('#basket .total', '€120');
}
}
Acceptance Tests
Form: PHPUnit at UI level
class BasketUiTest extends PHPUnit_Framework_TestCase
{
use phpunitminkTestCaseTrait;
public function testSalesTaxIsApplied()
{
$catalogue = new Catalogue(/* ... */);
$catalogue->price(new ProductName('Blue Jeans'), new Cost(120));
$page = $this->visit('http://example.com/products/'.urlencode($productName));
$this->getSession()->getPage()->pressButton('Add to Basket');
$this->assertContains(
'€120', $page->find('css', '#basket .total')->getText()
);
}
}
Integration Tests
Integration Tests
Goals:
— Test cross-boundary communication
— Test integration with concrete infrastructure
Integration Tests
Scopes:
— Large parts of the system
— Focus on the edges (not core domain)
— Areas where your code interacts with third-party
code
Integration Tests
Times:
— After the feature is implemented in core / contracts
are established
— During integration with real infrastructure
— When you want to get more confidence in
integration
— When cases are not covered by End-to-End
acceptance test
Integration Tests
Best Practices:
— Use tools with existing convenient integrations
— Focus on testing through your API
— Make sure your core domain has an interface
Integration Tests
Form: PHPUnit + DbUnit
class CatalogueTest extends PHPUnit_Extensions_Database_TestCase
{
public function getConnection()
{
$pdo = new PDO(/* ... */);
return $this->createDefaultDBConnection($pdo, 'myDatabase');
}
public function getDataSet()
{
return $this->createFlatXMLDataSet(dirname(__FILE__)
. '/_files/catalogue-seed.xml');
}
// ...
}
class CatalogueTest extends PHPUnit_Extensions_Database_TestCase
{
// ...
public function testProductCanBePriced()
{
$catalogue = new Catalogue(/* ... */);
$catalogue->price(
new ProductName('Blue Jeans'),
new Cost('100')
);
$this->assertEquals(
new Cost('100'),
$catalogue->lookUp(new ProductName('Blue Jeans')
);
}
}
Unit Tests
Unit Tests
Goals:
— Test components individually
— Catch errors earlier
— Drive internal design quality
— Document units for other developers
Unit Tests:
Scopes:
— Single classes
— Single classes + value objects?
— Extremely small units of code
Unit Tests:
Times:
— Just before you implement
Unit Tests:
Times:
— Just before you implement
OK, maybe...
— Just after you implement
— If you want to learn more about a class
— But always before you share the code!
Unit Tests
Best Practices
— Write in a descriptive style
— Describe interactions using Test Doubles
— Don't get too hung up on isolation
— Don't touch infrastructure
— Don't test other people's code
— Don't double other people's code?
Unit Tests
Form: PHPUnit
class BasketTest extends PHPUnit_Framework_TestCase
{
public function testSalesTaxIsApplied()
{
$catalogue = $this->getMock(Catalogue::class);
$catalogue->method('lookUp')->with(new ProductName('Blue Jeans'))
->willReturn(new Cost('100'));
$basket = new Basket($catalogue);
$basket->add(new ProductName('Blue Jeans'));
$this->assertSame(new Cost('120'), $basket->calculateTotal());
}
}
Unit Tests
Form: PhpSpec
class BasketSpec extends ObjectBehavior
{
function it_applies_sales_tax(Catalogue $catalogue)
{
$catalogue->lookUp(new ProductName('Blue Jeans'))->willReturn(new Cost('100'));
$this->beConstructedWith($catalogue);
$this->add(new ProductName('Blue Jeans'));
$basket->calculateTotal()->shouldBeLike(new Cost('120'));
}
}
5th Dimension -Who?
— Choose the right approaches for your context
— What mix of languages can the team use?
— What styles of testing will add the most value?
— What formats make the most sense to the team?
— How will tests fit into the development process?
There is no right answer, there are many right
answers!
Photo Credits
— "tools" by velacreations (CC) - https://flic.kr/p/
8ZSb3r
— "Components" by Jeff Keyzer (CC) - https://flic.kr/p/
4ZNZp1
— Doctor Who stolen from BBC.co.uk
— Other images used under license
Thank You & Questions?
@s_bergmann
@ciaranmcnulty
https://joind.in/talk/80dbd

Más contenido relacionado

La actualidad más candente

Testing persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitTesting persistence in PHP with DbUnit
Testing persistence in PHP with DbUnit
Peter Wilcsinszky
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
Harry Potter
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented Php
Michael Girouard
 

La actualidad más candente (20)

QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
 
Testing persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitTesting persistence in PHP with DbUnit
Testing persistence in PHP with DbUnit
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Introduction to refactoring
Introduction to refactoringIntroduction to refactoring
Introduction to refactoring
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpec
 
Perl Teach-In (part 2)
Perl Teach-In (part 2)Perl Teach-In (part 2)
Perl Teach-In (part 2)
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
Python advance
Python advancePython advance
Python advance
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Just Do It! ColdBox Integration Testing
Just Do It! ColdBox Integration TestingJust Do It! ColdBox Integration Testing
Just Do It! ColdBox Integration Testing
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and Dogs
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Introduction to Design Patterns in Javascript
Introduction to Design Patterns in JavascriptIntroduction to Design Patterns in Javascript
Introduction to Design Patterns in Javascript
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHP
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented Php
 
Class-based views with Django
Class-based views with DjangoClass-based views with Django
Class-based views with Django
 

Destacado (7)

5 Steps to Selecting the Right Job Board
5 Steps to Selecting the Right Job Board5 Steps to Selecting the Right Job Board
5 Steps to Selecting the Right Job Board
 
How to stand out online
How to stand out onlineHow to stand out online
How to stand out online
 
2012 and We're STILL Using PowerPoint Wrong
2012 and We're STILL Using PowerPoint Wrong2012 and We're STILL Using PowerPoint Wrong
2012 and We're STILL Using PowerPoint Wrong
 
Your Speech is Toxic
Your Speech is ToxicYour Speech is Toxic
Your Speech is Toxic
 
Great Speakers Tell Stories
Great Speakers Tell StoriesGreat Speakers Tell Stories
Great Speakers Tell Stories
 
Slides That Rock
Slides That RockSlides That Rock
Slides That Rock
 
SMOKE - The Convenient Truth [1st place Worlds Best Presentation Contest] by ...
SMOKE - The Convenient Truth [1st place Worlds Best Presentation Contest] by ...SMOKE - The Convenient Truth [1st place Worlds Best Presentation Contest] by ...
SMOKE - The Convenient Truth [1st place Worlds Best Presentation Contest] by ...
 

Similar a Finding the Right Testing Tool for the Job

Customizing oro crm webinar
Customizing oro crm webinarCustomizing oro crm webinar
Customizing oro crm webinar
Oro Inc.
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
Puppet
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Selenium
elliando dias
 

Similar a Finding the Right Testing Tool for the Job (20)

Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Clean tests good tests
Clean tests   good testsClean tests   good tests
Clean tests good tests
 
Facade Design Pattern
Facade Design PatternFacade Design Pattern
Facade Design Pattern
 
Diversified application testing based on a Sylius project
Diversified application testing based on a Sylius projectDiversified application testing based on a Sylius project
Diversified application testing based on a Sylius project
 
Java 102
Java 102Java 102
Java 102
 
Meteor Day Talk
Meteor Day TalkMeteor Day Talk
Meteor Day Talk
 
Customizing oro crm webinar
Customizing oro crm webinarCustomizing oro crm webinar
Customizing oro crm webinar
 
Refactoring a web application with Python
Refactoring a web application with PythonRefactoring a web application with Python
Refactoring a web application with Python
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Testing in Craft CMS
Testing in Craft CMSTesting in Craft CMS
Testing in Craft CMS
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
Angular JS2 Training Session #2
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2
 
Learning & using new technology
Learning & using new technologyLearning & using new technology
Learning & using new technology
 
Learning & using new technology
Learning & using new technologyLearning & using new technology
Learning & using new technology
 
MS Project
MS ProjectMS Project
MS Project
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Selenium
 
Chapter 12
Chapter 12Chapter 12
Chapter 12
 
Functional Testing for React Native Apps
Functional Testing for React Native AppsFunctional Testing for React Native Apps
Functional Testing for React Native Apps
 
Testing C# and ASP.net using Ruby
Testing C# and ASP.net using RubyTesting C# and ASP.net using Ruby
Testing C# and ASP.net using Ruby
 

Más de CiaranMcNulty

Más de CiaranMcNulty (18)

Greener web development at PHP London
Greener web development at PHP LondonGreener web development at PHP London
Greener web development at PHP London
 
Doodle Driven Development
Doodle Driven DevelopmentDoodle Driven Development
Doodle Driven Development
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with Symfony
 
Behat Best Practices
Behat Best PracticesBehat Best Practices
Behat Best Practices
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with Symfony
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016
 
Conscious Coupling
Conscious CouplingConscious Coupling
Conscious Coupling
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHP
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Fly In Style (without splashing out)
Fly In Style (without splashing out)Fly In Style (without splashing out)
Fly In Style (without splashing out)
 
Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Why Your Test Suite Sucks
Why Your Test Suite SucksWhy Your Test Suite Sucks
Why Your Test Suite Sucks
 
Driving Design with PhpSpec
Driving Design with PhpSpecDriving Design with PhpSpec
Driving Design with PhpSpec
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless Integration
 

Último

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
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
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
 

Último (20)

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
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
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
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
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 🔝✔️✔️
 
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...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
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
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

Finding the Right Testing Tool for the Job

  • 1. Finding the Right Testing Tool for the Job Sebastian Bergmann and Ciaran McNulty
  • 3. 3 Dimensions of Testing Goal - why we are writing the test Scope - how much of the system is involved in the test Form - how we express the test
  • 4.
  • 5. 3 4 Dimensions of Testing Goal - why we are writing the test Scope - how much of the system is involved in the test Form - how we express the test Time - when we write the test
  • 6. What we will talk about — Characterisation Tests — Acceptance Tests — Integration Tests — Unit Tests
  • 8. Characterisation Tests Goals: — Capture existing behaviour — Find out when behaviour changes
  • 9. Characterisation Tests Scopes: — Often at UI level — Sometimes at object/service level
  • 11. Characterisation Tests Best practice: — Treat these tests as a temporary measure — Use a tool that makes it easy to create tests — Expect pain and suffering
  • 12. Characterisation Tests Form: Behat + MinkExtension builtin steps Scenario: Product search returns results Given I am on "/" And I fill in "search" with "Blue jeans" When I press "go" Then I should see "100 Results Found"
  • 13. Characterisation Tests Form: PHPUnit + phpunit-mink-trait class SearchTest extends PHPUnit_Framework_TestCase { use phpunitminkTestCaseTrait; public function testProductSearchReturnsResult() { $page = $this->visit('http://example.com/'); $page->fillField('search', 'Blue Jeans'); $page->pressButton('go'); $this->assertContains('100 Results Found', $page->getText()); } }
  • 16. Characterisation Tests Form: PHPUnit + de-legacy-fy See docs at on GitHub at sebastianbergmann/de-legacy-fy
  • 18. Acceptance Tests Goals: — Match system behaviour to business requirements — Get feedback on proposed implementations — Understand business better — Document behaviour for the future
  • 19. Acceptance Tests Scopes: — At a UI layer — At an API layer — At the service layer — Lower level may be too disconnected
  • 20. Acceptance Tests Times: — Before implementation — Before commitment (as long as it's not expensive?) — Hard to write in retrospect
  • 21. Acceptance Tests Best practices: — Get feedback on tests early — Make them readable, or have readable output, for the intended audience — Apply for the smallest scope first — Apply to core domain model first — Minimise end-to-end tests
  • 22. Acceptance Tests Form: Behat at service level Scenario: Sales tax is applied to basket Given "Blue Jeans" are priced as €100 in the catalogue When I add "Blue Jeans" to my shopping basket Then the basket total should be €120
  • 23. class BasketContext implements Context { public function __construct() { $this->catalogue = new InMemoryCatalogue(); $this->basket = new Basket($catalogue); } /** * @Given :productName is/are priced as :cost in the catalogue */ public function priceProduct(ProductName $productName, Cost $cost) { $this->catalogue->price($productName, $cost); } //... }
  • 24. class BasketContext implements Context { //... /** * @When I add :productName to my shopping basket */ public function addProductToBasket(ProductName $productName) { $this->basket->add($productName); } /** * @Then the basket total should be :cost */ public function checkBasketTotal(Cost $cost) { assert($this->basket->total == $cost->asInt()); } }
  • 25. Acceptance Tests Form: PHPUnit at service level class BasketTest extends PHPUnit_Framework_TestCase { public function testSalesTaxIsApplied() { $catalogue = new InMemoryCatalogue(); $basket = new Basket($catalogue); $productName = new ProductName('Blue Jeans'); $catalogue->price($productName, new Cost('100')); $basket->add($productName); $this->assertEquals(new Cost('120'), $basket->calculateTotal()); } }
  • 26. Acceptance Tests Form: PHPUnit at service level
  • 27. Acceptance Tests Form: Behat at UI level Scenario: Sales tax is applied to basket Given "Blue Jeans" are priced as €100 in the catalogue When I add "Blue Jeans" to my shopping basket Then the basket total should be €120
  • 28. class BasketUiContext extends MinkContext { public function __construct() { $this->catalogue = new Catalogue(/* ... */); } /** * @Given :productName is/are priced as :cost in the catalogue */ public function priceProduct(ProductName $productName, Cost $cost) { $this->catalogue->price($productName, $cost); } //... }
  • 29. class BasketUiContext extends MinkContext { //... /** * @When I add :productName to my shopping basket */ public function addProductToBasket(ProductName $productName) { $this->visitPath('/products/'.urlencode($productName)); $this->getSession()->getPage()->pressButton('Add to Basket'); } /** * @Then the basket total should be :cost */ public function checkBasketTotal(Cost $cost) { $this->assertElementContains('#basket .total', '€120'); } }
  • 30. Acceptance Tests Form: PHPUnit at UI level class BasketUiTest extends PHPUnit_Framework_TestCase { use phpunitminkTestCaseTrait; public function testSalesTaxIsApplied() { $catalogue = new Catalogue(/* ... */); $catalogue->price(new ProductName('Blue Jeans'), new Cost(120)); $page = $this->visit('http://example.com/products/'.urlencode($productName)); $this->getSession()->getPage()->pressButton('Add to Basket'); $this->assertContains( '€120', $page->find('css', '#basket .total')->getText() ); } }
  • 32. Integration Tests Goals: — Test cross-boundary communication — Test integration with concrete infrastructure
  • 33. Integration Tests Scopes: — Large parts of the system — Focus on the edges (not core domain) — Areas where your code interacts with third-party code
  • 34. Integration Tests Times: — After the feature is implemented in core / contracts are established — During integration with real infrastructure — When you want to get more confidence in integration — When cases are not covered by End-to-End acceptance test
  • 35. Integration Tests Best Practices: — Use tools with existing convenient integrations — Focus on testing through your API — Make sure your core domain has an interface
  • 36. Integration Tests Form: PHPUnit + DbUnit class CatalogueTest extends PHPUnit_Extensions_Database_TestCase { public function getConnection() { $pdo = new PDO(/* ... */); return $this->createDefaultDBConnection($pdo, 'myDatabase'); } public function getDataSet() { return $this->createFlatXMLDataSet(dirname(__FILE__) . '/_files/catalogue-seed.xml'); } // ... }
  • 37. class CatalogueTest extends PHPUnit_Extensions_Database_TestCase { // ... public function testProductCanBePriced() { $catalogue = new Catalogue(/* ... */); $catalogue->price( new ProductName('Blue Jeans'), new Cost('100') ); $this->assertEquals( new Cost('100'), $catalogue->lookUp(new ProductName('Blue Jeans') ); } }
  • 39. Unit Tests Goals: — Test components individually — Catch errors earlier — Drive internal design quality — Document units for other developers
  • 40. Unit Tests: Scopes: — Single classes — Single classes + value objects? — Extremely small units of code
  • 41. Unit Tests: Times: — Just before you implement
  • 42. Unit Tests: Times: — Just before you implement OK, maybe... — Just after you implement — If you want to learn more about a class — But always before you share the code!
  • 43. Unit Tests Best Practices — Write in a descriptive style — Describe interactions using Test Doubles — Don't get too hung up on isolation — Don't touch infrastructure — Don't test other people's code — Don't double other people's code?
  • 44. Unit Tests Form: PHPUnit class BasketTest extends PHPUnit_Framework_TestCase { public function testSalesTaxIsApplied() { $catalogue = $this->getMock(Catalogue::class); $catalogue->method('lookUp')->with(new ProductName('Blue Jeans')) ->willReturn(new Cost('100')); $basket = new Basket($catalogue); $basket->add(new ProductName('Blue Jeans')); $this->assertSame(new Cost('120'), $basket->calculateTotal()); } }
  • 45. Unit Tests Form: PhpSpec class BasketSpec extends ObjectBehavior { function it_applies_sales_tax(Catalogue $catalogue) { $catalogue->lookUp(new ProductName('Blue Jeans'))->willReturn(new Cost('100')); $this->beConstructedWith($catalogue); $this->add(new ProductName('Blue Jeans')); $basket->calculateTotal()->shouldBeLike(new Cost('120')); } }
  • 46. 5th Dimension -Who? — Choose the right approaches for your context — What mix of languages can the team use? — What styles of testing will add the most value? — What formats make the most sense to the team? — How will tests fit into the development process? There is no right answer, there are many right answers!
  • 47. Photo Credits — "tools" by velacreations (CC) - https://flic.kr/p/ 8ZSb3r — "Components" by Jeff Keyzer (CC) - https://flic.kr/p/ 4ZNZp1 — Doctor Who stolen from BBC.co.uk — Other images used under license
  • 48. Thank You & Questions? @s_bergmann @ciaranmcnulty https://joind.in/talk/80dbd