The document discusses best practices for using Behat, a behavior-driven development (BDD) framework, for testing Symfony applications. It covers how to write feature files with Gherkin syntax, map examples to PHP step definitions, and drive the domain and service layers with Behat scenarios. Running scenarios directly against domain objects or injecting services into a Behat context allows testing features end-to-end while aligning code with business needs. Using fakes for infrastructure keeps tests fast but contract tests sync code with real systems.
Behat is widely used as part of a Behaviour Driven Development lifecycle, but it's also widely misused.
In this talk Ciaran will explain what BDD and Behat involve, and show the best practices including writing good scenarios, driving service development from scenarios, and techniques for fast UI testing.
Behat is widely used as part of a Behaviour Driven Development lifecycle, but it's also widely misused. In this talk Ciaran will explain BDD, and show the best practices for using Behat including: writing good scenarios, driving service development from scenarios, and fast UI testing, using Behat and the Symfony2Extension.
This document discusses ways that web developers can help address climate change through greener development practices. It recommends reducing personal impacts through actions like eating less meat, using green electricity, driving electric vehicles, and offsetting remaining emissions. For companies, it suggests starting to measure carbon footprints, advocating for change within organizations, improving back-end efficiency through tools like PHP 7, optimizing for reduced bandwidth usage, and selling these practices by noting their cost-saving and accessibility benefits in addition to environmental impacts. The document closes by encouraging joining a climate advocacy group and identifying areas where one's technical stack overuses energy.
Having a good example-driven conversation can be messy. Humans scribble on whiteboards, rip up index cards, and stick things to the wall.
Automating examples brings huge benefits, but forcing them into linear Gherkin doesn't always feel natural. We'll explore some more natural visual formats for examples, and how they can practically be used to drive tests.
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to create a workflow that directly drives code from a starting point of user requirements. We will see how a simple feature can be defined via conversation with stakeholders, captured as automatable requirements, and expressed directly in the object model using tools such as Behat and PhpSpec.
Modelling by Example Workshop - PHPNW 2016CiaranMcNulty
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to create a workflow that directly drives code from a starting point of user requirements. We define a feature via conversation with stakeholders, capture it as automatable requirements, then express it in code using Behat and PhpSpec.
By using a comprehensive feature-filled framework we can build software fast. On the other hand, by decoupling our applications we can build sofware that is independent of our framework and infrastructure choices, and therefore longer lasting.
We can't do both, is one approach always right?
In this talk we'll look at different decoupling techniques, what problems they solve, and when they make sense. We will learn some concrete techniques to discover where we should be investing in decoupling, and when we should let the framework maintainers do the work for us.
The document discusses using examples and behavior-driven development (BDD) to drive the design of a domain model. Examples are presented in a formal language called Gherkin to illustrate behaviors like earning loyalty points for flights. The examples are then used to directly drive the code model, with behaviors tested first before user interfaces or infrastructure. By embedding the ubiquitous language from the domain in scenarios, the scenarios naturally become the domain model. Tests are written to define objects like flights, fares, tickets and points to match the examples.
Behat is widely used as part of a Behaviour Driven Development lifecycle, but it's also widely misused.
In this talk Ciaran will explain what BDD and Behat involve, and show the best practices including writing good scenarios, driving service development from scenarios, and techniques for fast UI testing.
Behat is widely used as part of a Behaviour Driven Development lifecycle, but it's also widely misused. In this talk Ciaran will explain BDD, and show the best practices for using Behat including: writing good scenarios, driving service development from scenarios, and fast UI testing, using Behat and the Symfony2Extension.
This document discusses ways that web developers can help address climate change through greener development practices. It recommends reducing personal impacts through actions like eating less meat, using green electricity, driving electric vehicles, and offsetting remaining emissions. For companies, it suggests starting to measure carbon footprints, advocating for change within organizations, improving back-end efficiency through tools like PHP 7, optimizing for reduced bandwidth usage, and selling these practices by noting their cost-saving and accessibility benefits in addition to environmental impacts. The document closes by encouraging joining a climate advocacy group and identifying areas where one's technical stack overuses energy.
Having a good example-driven conversation can be messy. Humans scribble on whiteboards, rip up index cards, and stick things to the wall.
Automating examples brings huge benefits, but forcing them into linear Gherkin doesn't always feel natural. We'll explore some more natural visual formats for examples, and how they can practically be used to drive tests.
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to create a workflow that directly drives code from a starting point of user requirements. We will see how a simple feature can be defined via conversation with stakeholders, captured as automatable requirements, and expressed directly in the object model using tools such as Behat and PhpSpec.
Modelling by Example Workshop - PHPNW 2016CiaranMcNulty
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to create a workflow that directly drives code from a starting point of user requirements. We define a feature via conversation with stakeholders, capture it as automatable requirements, then express it in code using Behat and PhpSpec.
By using a comprehensive feature-filled framework we can build software fast. On the other hand, by decoupling our applications we can build sofware that is independent of our framework and infrastructure choices, and therefore longer lasting.
We can't do both, is one approach always right?
In this talk we'll look at different decoupling techniques, what problems they solve, and when they make sense. We will learn some concrete techniques to discover where we should be investing in decoupling, and when we should let the framework maintainers do the work for us.
The document discusses using examples and behavior-driven development (BDD) to drive the design of a domain model. Examples are presented in a formal language called Gherkin to illustrate behaviors like earning loyalty points for flights. The examples are then used to directly drive the code model, with behaviors tested first before user interfaces or infrastructure. By embedding the ubiquitous language from the domain in scenarios, the scenarios naturally become the domain model. Tests are written to define objects like flights, fares, tickets and points to match the examples.
Finding the Right Testing Tool for the JobCiaranMcNulty
Over the last decade the idea that we should test our applications has slowly made its way from a niche idea to the mainstream of PHP development. With many tools and approaches to testing now available it can be difficult to choose which ones to use.
In this talk we will explore the current landscape of PHP testing practices, look at the different tools and approaches available, and find out how we can decide which are best for our project, team, and context.
By using a comprehensive feature-filled framework we can build software fast. On the other hand, by decoupling our applications we can build sofware that is independent of our framework and infrastructure choices, and therefore longer lasting.
We can't do both, is one approach always right?
In this talk we'll look at different decoupling techniques, what problems they solve, and when they make sense. We will learn some concrete techniques to discover where we should be investing in decoupling, and when we should let the framework maintainers do the work for us.
PhpSpec is a SpecBDD tool that enables you to use a TDD workflow that can transform the way you write PHP. In this session we will look at the TDD workflow and see how PhpSpec can be used to speed up your development; add regression safety, and improve your object-oriented design.
Co-presented with Marek Matulka at one of Inviqa's Enlightening Lunches.
How to fly in style without splashing out. With so many competing airlines and travel agents, it is hard to find flights at the right price, or the right level of comfort and convenience. Ciaran and Marek will show us how to "exploit" the system to get the best deals, travel in style, and maximise your benefits.
Why Your Test Suite Sucks - PHPCon PL 2015CiaranMcNulty
Many teams adopt TDD attracted by the promise of a more productive workflow, fewer regressions and higher code quality. Sometimes this goes wrong and these benefits do not materialise, despite a healthy-seeming test suite. In this talk we will look at what the common pitfalls of testing are, why teams fall into these traps, and they can dig themselves out.
Driving Design through Examples - PhpCon PL 2015CiaranMcNulty
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to creat a workflow that directly drives code from a starting point of user requirements. We will see how a simple feature can be defined via conversation with stakeholders, captured as automatable requirements, and expressed directly in the object model using tools such as Behat and PhpSpec.
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
The last few years have seen a huge adoption of testing practices, and an explosion of different testing tools, in the PHP space. The difficulties come when we have to choose which tools to use, in what combinations, and how to apply them to existing codebases.
In this talk we will look at what tools are available, what their strengths are, how to decide which set of tools to use for new or legacy projects, and when to prioritise decoupling and testability over the convenience we get from our frameworks.
The document discusses Test Driven Development (TDD) using PhpSpec. It begins with an overview of TDD vs Behavior Driven Development (BDD). It then covers key aspects of using PhpSpec including describing object behavior with examples, verifying behavior by running tests, matchers for assertions, describing collaborations and exceptions. The rest of the document demonstrates a TDD workflow using PhpSpec to develop a greeter class and related classes like Person in a step-by-step manner.
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to create a workflow that directly drives code from a starting point of user requirements. We will see how a simple feature can be defined via conversation with stakeholders, captured as automatable requirements, and expressed directly in the object model using tools such as Behat and PhpSpec.
Many teams adopt TDD attracted by the promise of a more productive workflow, fewer regressions and higher code quality. Sometimes this goes wrong and these benefits do not materialise, despite a healthy-seeming test suite. In this talk we will look at what the common pitfalls of testing are, why teams fall into these traps, and they can dig themselves out.
What is BDD? Is it the same as TDD, or something quite different? This talk will answer these questions, and show how PhpSpec can be integrated into your development workflow to drive your Object Oriented design. Plus: a sneak peak at some of the new features in the forthcoming 2.1 release.
Using HttpKernelInterface for Painless IntegrationCiaranMcNulty
In this short session we will look at one of the Symfony2 components adopted since Drupal 8; the HttpKernelInterface.
Attendees will gain familiarity with this component, the related Request and Response objects, and the overall top level structure of a Drupal 8 project's integration.
We will also see how the Stack PHP project allows us to easily integrate a Drupal 8 site with another codebase that uses the HttpKernelInterface (including Symfony2, Silex, Laravel or even another Drupal 8 project).
We will also explore some of the other functionality that can be added by Stack, all enabled by this powerful abstraction.
Most important New features of Oracle 23c for DBAs and Developers. You can get more idea from my youtube channel video from https://youtu.be/XvL5WtaC20A
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...XfilesPro
Wondering how X-Sign gained popularity in a quick time span? This eSign functionality of XfilesPro DocuPrime has many advancements to offer for Salesforce users. Explore them now!
Atelier - Innover avec l’IA Générative et les graphes de connaissancesNeo4j
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Allez au-delà du battage médiatique autour de l’IA et découvrez des techniques pratiques pour utiliser l’IA de manière responsable à travers les données de votre organisation. Explorez comment utiliser les graphes de connaissances pour augmenter la précision, la transparence et la capacité d’explication dans les systèmes d’IA générative. Vous partirez avec une expérience pratique combinant les relations entre les données et les LLM pour apporter du contexte spécifique à votre domaine et améliorer votre raisonnement.
Amenez votre ordinateur portable et nous vous guiderons sur la mise en place de votre propre pile d’IA générative, en vous fournissant des exemples pratiques et codés pour démarrer en quelques minutes.
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesQuickdice ERP
Explore the seamless transition to e-invoicing with this comprehensive guide tailored for Saudi Arabian businesses. Navigate the process effortlessly with step-by-step instructions designed to streamline implementation and enhance efficiency.
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemPeter Muessig
Learn about the latest innovations in and around OpenUI5/SAPUI5: UI5 Tooling, UI5 linter, UI5 Web Components, Web Components Integration, UI5 2.x, UI5 GenAI.
Recording:
https://www.youtube.com/live/MSdGLG2zLy8?si=INxBHTqkwHhxV5Ta&t=0
What is Master Data Management by PiLog Groupaymanquadri279
PiLog Group's Master Data Record Manager (MDRM) is a sophisticated enterprise solution designed to ensure data accuracy, consistency, and governance across various business functions. MDRM integrates advanced data management technologies to cleanse, classify, and standardize master data, thereby enhancing data quality and operational efficiency.
Mobile App Development Company In Noida | Drona InfotechDrona Infotech
Drona Infotech is a premier mobile app development company in Noida, providing cutting-edge solutions for businesses.
Visit Us For : https://www.dronainfotech.com/mobile-application-development/
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfVALiNTRY360
Salesforce Healthcare CRM, implemented by VALiNTRY360, revolutionizes patient management by enhancing patient engagement, streamlining administrative processes, and improving care coordination. Its advanced analytics, robust security, and seamless integration with telehealth services ensure that healthcare providers can deliver personalized, efficient, and secure patient care. By automating routine tasks and providing actionable insights, Salesforce Healthcare CRM enables healthcare providers to focus on delivering high-quality care, leading to better patient outcomes and higher satisfaction. VALiNTRY360's expertise ensures a tailored solution that meets the unique needs of any healthcare practice, from small clinics to large hospital systems.
For more info visit us https://valintry360.com/solutions/health-life-sciences
Finding the Right Testing Tool for the JobCiaranMcNulty
Over the last decade the idea that we should test our applications has slowly made its way from a niche idea to the mainstream of PHP development. With many tools and approaches to testing now available it can be difficult to choose which ones to use.
In this talk we will explore the current landscape of PHP testing practices, look at the different tools and approaches available, and find out how we can decide which are best for our project, team, and context.
By using a comprehensive feature-filled framework we can build software fast. On the other hand, by decoupling our applications we can build sofware that is independent of our framework and infrastructure choices, and therefore longer lasting.
We can't do both, is one approach always right?
In this talk we'll look at different decoupling techniques, what problems they solve, and when they make sense. We will learn some concrete techniques to discover where we should be investing in decoupling, and when we should let the framework maintainers do the work for us.
PhpSpec is a SpecBDD tool that enables you to use a TDD workflow that can transform the way you write PHP. In this session we will look at the TDD workflow and see how PhpSpec can be used to speed up your development; add regression safety, and improve your object-oriented design.
Co-presented with Marek Matulka at one of Inviqa's Enlightening Lunches.
How to fly in style without splashing out. With so many competing airlines and travel agents, it is hard to find flights at the right price, or the right level of comfort and convenience. Ciaran and Marek will show us how to "exploit" the system to get the best deals, travel in style, and maximise your benefits.
Why Your Test Suite Sucks - PHPCon PL 2015CiaranMcNulty
Many teams adopt TDD attracted by the promise of a more productive workflow, fewer regressions and higher code quality. Sometimes this goes wrong and these benefits do not materialise, despite a healthy-seeming test suite. In this talk we will look at what the common pitfalls of testing are, why teams fall into these traps, and they can dig themselves out.
Driving Design through Examples - PhpCon PL 2015CiaranMcNulty
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to creat a workflow that directly drives code from a starting point of user requirements. We will see how a simple feature can be defined via conversation with stakeholders, captured as automatable requirements, and expressed directly in the object model using tools such as Behat and PhpSpec.
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
The last few years have seen a huge adoption of testing practices, and an explosion of different testing tools, in the PHP space. The difficulties come when we have to choose which tools to use, in what combinations, and how to apply them to existing codebases.
In this talk we will look at what tools are available, what their strengths are, how to decide which set of tools to use for new or legacy projects, and when to prioritise decoupling and testability over the convenience we get from our frameworks.
The document discusses Test Driven Development (TDD) using PhpSpec. It begins with an overview of TDD vs Behavior Driven Development (BDD). It then covers key aspects of using PhpSpec including describing object behavior with examples, verifying behavior by running tests, matchers for assertions, describing collaborations and exceptions. The rest of the document demonstrates a TDD workflow using PhpSpec to develop a greeter class and related classes like Person in a step-by-step manner.
Modelling by Example is a set of practices that combine BDD (Behaviour Driven Development) and DDD (Domain Driven Design) techniques to create a workflow that directly drives code from a starting point of user requirements. We will see how a simple feature can be defined via conversation with stakeholders, captured as automatable requirements, and expressed directly in the object model using tools such as Behat and PhpSpec.
Many teams adopt TDD attracted by the promise of a more productive workflow, fewer regressions and higher code quality. Sometimes this goes wrong and these benefits do not materialise, despite a healthy-seeming test suite. In this talk we will look at what the common pitfalls of testing are, why teams fall into these traps, and they can dig themselves out.
What is BDD? Is it the same as TDD, or something quite different? This talk will answer these questions, and show how PhpSpec can be integrated into your development workflow to drive your Object Oriented design. Plus: a sneak peak at some of the new features in the forthcoming 2.1 release.
Using HttpKernelInterface for Painless IntegrationCiaranMcNulty
In this short session we will look at one of the Symfony2 components adopted since Drupal 8; the HttpKernelInterface.
Attendees will gain familiarity with this component, the related Request and Response objects, and the overall top level structure of a Drupal 8 project's integration.
We will also see how the Stack PHP project allows us to easily integrate a Drupal 8 site with another codebase that uses the HttpKernelInterface (including Symfony2, Silex, Laravel or even another Drupal 8 project).
We will also explore some of the other functionality that can be added by Stack, all enabled by this powerful abstraction.
Most important New features of Oracle 23c for DBAs and Developers. You can get more idea from my youtube channel video from https://youtu.be/XvL5WtaC20A
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...XfilesPro
Wondering how X-Sign gained popularity in a quick time span? This eSign functionality of XfilesPro DocuPrime has many advancements to offer for Salesforce users. Explore them now!
Atelier - Innover avec l’IA Générative et les graphes de connaissancesNeo4j
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Allez au-delà du battage médiatique autour de l’IA et découvrez des techniques pratiques pour utiliser l’IA de manière responsable à travers les données de votre organisation. Explorez comment utiliser les graphes de connaissances pour augmenter la précision, la transparence et la capacité d’explication dans les systèmes d’IA générative. Vous partirez avec une expérience pratique combinant les relations entre les données et les LLM pour apporter du contexte spécifique à votre domaine et améliorer votre raisonnement.
Amenez votre ordinateur portable et nous vous guiderons sur la mise en place de votre propre pile d’IA générative, en vous fournissant des exemples pratiques et codés pour démarrer en quelques minutes.
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesQuickdice ERP
Explore the seamless transition to e-invoicing with this comprehensive guide tailored for Saudi Arabian businesses. Navigate the process effortlessly with step-by-step instructions designed to streamline implementation and enhance efficiency.
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemPeter Muessig
Learn about the latest innovations in and around OpenUI5/SAPUI5: UI5 Tooling, UI5 linter, UI5 Web Components, Web Components Integration, UI5 2.x, UI5 GenAI.
Recording:
https://www.youtube.com/live/MSdGLG2zLy8?si=INxBHTqkwHhxV5Ta&t=0
What is Master Data Management by PiLog Groupaymanquadri279
PiLog Group's Master Data Record Manager (MDRM) is a sophisticated enterprise solution designed to ensure data accuracy, consistency, and governance across various business functions. MDRM integrates advanced data management technologies to cleanse, classify, and standardize master data, thereby enhancing data quality and operational efficiency.
Mobile App Development Company In Noida | Drona InfotechDrona Infotech
Drona Infotech is a premier mobile app development company in Noida, providing cutting-edge solutions for businesses.
Visit Us For : https://www.dronainfotech.com/mobile-application-development/
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfVALiNTRY360
Salesforce Healthcare CRM, implemented by VALiNTRY360, revolutionizes patient management by enhancing patient engagement, streamlining administrative processes, and improving care coordination. Its advanced analytics, robust security, and seamless integration with telehealth services ensure that healthcare providers can deliver personalized, efficient, and secure patient care. By automating routine tasks and providing actionable insights, Salesforce Healthcare CRM enables healthcare providers to focus on delivering high-quality care, leading to better patient outcomes and higher satisfaction. VALiNTRY360's expertise ensures a tailored solution that meets the unique needs of any healthcare practice, from small clinics to large hospital systems.
For more info visit us https://valintry360.com/solutions/health-life-sciences
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsPeter Muessig
The UI5 tooling is the development and build tooling of UI5. It is built in a modular and extensible way so that it can be easily extended by your needs. This session will showcase various tooling extensions which can boost your development experience by far so that you can really work offline, transpile your code in your project to use even newer versions of EcmaScript (than 2022 which is supported right now by the UI5 tooling), consume any npm package of your choice in your project, using different kind of proxies, and even stitching UI5 projects during development together to mimic your target environment.
Using Query Store in Azure PostgreSQL to Understand Query PerformanceGrant Fritchey
Microsoft has added an excellent new extension in PostgreSQL on their Azure Platform. This session, presented at Posette 2024, covers what Query Store is and the types of information you can get out of it.
OpenMetadata Community Meeting - 5th June 2024OpenMetadata
The OpenMetadata Community Meeting was held on June 5th, 2024. In this meeting, we discussed about the data quality capabilities that are integrated with the Incident Manager, providing a complete solution to handle your data observability needs. Watch the end-to-end demo of the data quality features.
* How to run your own data quality framework
* What is the performance impact of running data quality frameworks
* How to run the test cases in your own ETL pipelines
* How the Incident Manager is integrated
* Get notified with alerts when test cases fail
Watch the meeting recording here - https://www.youtube.com/watch?v=UbNOje0kf6E
Microservice Teams - How the cloud changes the way we workSven Peters
A lot of technical challenges and complexity come with building a cloud-native and distributed architecture. The way we develop backend software has fundamentally changed in the last ten years. Managing a microservices architecture demands a lot of us to ensure observability and operational resiliency. But did you also change the way you run your development teams?
Sven will talk about Atlassian’s journey from a monolith to a multi-tenanted architecture and how it affected the way the engineering teams work. You will learn how we shifted to service ownership, moved to more autonomous teams (and its challenges), and established platform and enablement teams.
Transform Your Communication with Cloud-Based IVR SolutionsTheSMSPoint
Discover the power of Cloud-Based IVR Solutions to streamline communication processes. Embrace scalability and cost-efficiency while enhancing customer experiences with features like automated call routing and voice recognition. Accessible from anywhere, these solutions integrate seamlessly with existing systems, providing real-time analytics for continuous improvement. Revolutionize your communication strategy today with Cloud-Based IVR Solutions. Learn more at: https://thesmspoint.com/channel/cloud-telephony
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j
Dr. Jesús Barrasa, Head of Solutions Architecture for EMEA, Neo4j
Découvrez les dernières innovations de Neo4j, et notamment les dernières intégrations cloud et les améliorations produits qui font de Neo4j un choix essentiel pour les développeurs qui créent des applications avec des données interconnectées et de l’IA générative.
8 Best Automated Android App Testing Tool and Framework in 2024.pdfkalichargn70th171
Regarding mobile operating systems, two major players dominate our thoughts: Android and iPhone. With Android leading the market, software development companies are focused on delivering apps compatible with this OS. Ensuring an app's functionality across various Android devices, OS versions, and hardware specifications is critical, making Android app testing essential.
12. Rule:
We charge our customers sales tax at a rate of 20%
Crania Ltd | @ciaranmcnulty | #symfonycon
13. Rule:
We charge our customers sales tax at a rate of 20%
Example:
So, if an item is priced at $10, we charge $10
+ $2 tax for a total of $12
Crania Ltd | @ciaranmcnulty | #symfonycon
19. Rule:
We charge our customers sales tax at a rate of 20%
Example:
So, if an item is priced at $10, we charge $10
+ $2 tax for a total of $12
Crania Ltd | @ciaranmcnulty | #symfonycon
20. Rule:
We charge our customers sales tax at a rate of 20%
Example:
No! If an item is priced at £10, we charge £10
and allocate £1.67 of that as sales tax
Crania Ltd | @ciaranmcnulty | #symfonycon
22. Capturing Examples
Action Outcome
What causes the behaviour? What is the result of the
behaviour?
I buy a pair of Levi 501s I am charged £32.99
Crania Ltd | @ciaranmcnulty | #symfonycon
23. Why does that action
cause that outcome?
Crania Ltd | @ciaranmcnulty | #symfonycon
24. Capturing Examples
Context Action Outcome
What happened in
the past that affects
the behaviour?
What causes the
behaviour?
What is the result of
the behaviour?
Levi 501s are listed
at £32.99
I buy a pair of Levi
501s
I am charged £32.99
Crania Ltd | @ciaranmcnulty | #symfonycon
26. Context Questioning
“Is there any other context which, when this event happens, will
produce a different outcome?” - Liz Keogh
Crania Ltd | @ciaranmcnulty | #symfonycon
27. Context Questioning
Context Action Outcome
Levi 501s are listed
at £32.99
I buy a pair of Levi
501s
I am charged £32.99
“Is there any situation where I could buy these jeans and pay a different
amount?”
Crania Ltd | @ciaranmcnulty | #symfonycon
28. Context Questioning
Context Action Outcome
Levi 501s are listed at
£32.99
I buy a pair of Levi 501s I am charged £32.99
Levis are on sale " ?
Purchaser is a staff
member
" ?
The jeans are damaged " ?
Crania Ltd | @ciaranmcnulty | #symfonycon
29. Outcome Questioning
“Given this context, when this event happens, is there another outcome
that’s important? Something we missed, perhaps?” - Liz Keogh
Crania Ltd | @ciaranmcnulty | #symfonycon
30. Outcome Questioning
Context Action Outcome
Levi 501s are listed
at £32.99
I buy a pair of Levi
501s
I am charged £32.99
"Aside from me being charged for the jeans, does something else
happen that we need to care about?"
Crania Ltd | @ciaranmcnulty | #symfonycon
31. Outcome Questioning
Context Action Outcome
Levi 501s are listed
at £32.99
I buy a pair of Levi
501s
I am charged
£32.99 ...and I get
sent some
jeans ...and the
warehouse stock
level is reduced
Crania Ltd | @ciaranmcnulty | #symfonycon
43. Outstanding questions
» Can we start work on this item without this answer?
» Do we need to resolve it first?
» Can the story be split along this seam?
Crania Ltd | @ciaranmcnulty | #symfonycon
58. Feature: Scheduling a training course
As a trainer
In order to be able to cancel courses or schedule new ones
I should be able to specify a maximum and minimum class size
Rules:
- Course is proposed with size limits
- When enough enrolments happen, course is considered viable
- When maximum class size is reached, further enrolments are not allowed
Background:
Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
Scenario: Course does not get enough enrolments to be viable
Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
Scenario: Course gets enough enrolments to be viable
Given Alice has already enrolled on this course
When Bob enrols on this course
Then this course will be viable
Scenario: Enrolments are stopped when class size is reached
Given Alice, Bob and Charlie have already enrolled on this course
When Derek tries to enrol on this course
Then he should not be able to enrol
Crania Ltd | @ciaranmcnulty | #symfonycon
59. Feature: Scheduling a training course
As a trainer
In order to be able to cancel courses or schedule new ones
I should be able to specify a maximum and minimum class size
Rules:
- Course is proposed with size limits
- When enough enrolments happen, course is considered viable
- When maximum class size is reached, further enrolments are not allowed
Crania Ltd | @ciaranmcnulty | #symfonycon
60. Background:
Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
Scenario: Course does not get enough enrolments to be viable
When only Alice enrols on this course
Then this course will not be viable
Crania Ltd | @ciaranmcnulty | #symfonycon
61. Background:
Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
Scenario: Course does not get enough enrolments to be viable
When only Alice enrols on this course
Then this course will not be viable
Crania Ltd | @ciaranmcnulty | #symfonycon
62. Background:
Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
Scenario: Course gets enough enrolments to be viable
Given Alice has already enrolled on this course
When Bob enrols on this course
Then this course will be viable
Crania Ltd | @ciaranmcnulty | #symfonycon
63. Background:
Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
Scenario: Enrolments are stopped when class size is reached
Given Alice, Bob and Charlie have already enrolled on this course
When Derek tries to enrol on this course
Then he should not be able to enrol
Crania Ltd | @ciaranmcnulty | #symfonycon
65. Gherkin:
Given a thing happens to Ciaran
PHP:
/**
* @Given a thing happens to :person
*/
public function doAThing(string $person)
{
// you have to write this
}
Crania Ltd | @ciaranmcnulty | #symfonycon
68. Driving the Domain layer
» Drive PHP objects directly from scenario
» Proves domain supports business actions
» Aligns domain model with business language
» Executes quickly with few dependencies
Crania Ltd | @ciaranmcnulty | #symfonycon
70. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class FeatureContext implements Context
{
/**
* @Given :courseTitle was proposed with a class size of :min to :max people
*/
public function courseWasProposedWithAClassSizeOfToPeople(string $courseTitle, int $min, int $max)
{
$this->course = Course::propose(
$courseTitle,
ClassSize::between($min, $max)
);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
73. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class FeatureContext implements Context
{
/** @Transform */
public function transformLearner(string $name) : Learner
{
return Learner::called($name);
}
/**
* @When only :learner enrols on this course
*/
public function learnerEnrolsOnCourse(Learner $learner)
{
$this->course->enrol($learner);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
74. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class FeatureContext implements Context
{
/**
* @Then this course will not be viable
*/
public function thisCourseWillNotBeViable()
{
assert($this->course->isViable() == false);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
78. Driving the Service layer
» Configure services in test environment
» Inject services into Behat context (using an extension)
» Interact with domain model via the services
» Aligns service layer with business use cases
Crania Ltd | @ciaranmcnulty | #symfonycon
80. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class ServiceContext implements Context
{
public function __construct(CourseEnrolments $courseEnrolments)
{
$this->courseEnrolments = $courseEnrolments;
}
/**
* @Given :course was proposed with a class size of :min to :max people
*/
public function wasProposedWithAClassSizeOfToPeople(string $course, int $min, int $max)
{
$this->course = $course;
$this->courseEnrolments->propose($course, $min, $max);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
81. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class ServiceContext implements Context
{
public function __construct(CourseEnrolments $courseEnrolments)
{
$this->courseEnrolments = $courseEnrolments;
}
/**
* @Given :course was proposed with a class size of :min to :max people
*/
public function wasProposedWithAClassSizeOfToPeople(string $course, int $min, int $max)
{
$this->courseId = $course;
$this->courseEnrolments->propose($course, $min, $max);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
83. class CourseEnrolments
{
private $courses;
public function __construct(Courses $courses)
{
$this->courses = $courses;
}
public function propose(string $title, int $minimum, int $maximum)
{
$this->courses->add(
Course::propose(
$title,
ClassSize::between($minimum, $maximum)
)
);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
84. Infrastructure
» Using real infrastructure is slow
» Using fake infrastructure can lower confidence
» Use fake infrastructure but sync via contract tests
Crania Ltd | @ciaranmcnulty | #symfonycon
85. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class ServiceContext implements Context
{
/**
* @When (only) :learner enrols on this course
*/
public function learnerEnrolsOnThisCourse(string $learner)
{
$this->courseEnrolments->enrol($learner, $this->courseId);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
86. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class ServiceContext implements Context
{
/**
* @Then this course will not be viable
*/
public function thisCourseWillNotBeViable()
{
assert($this->courseEnrolments->isCourseViable($this->courseId) == false);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
87. Domain vs Service layer
» Start by driving domain layer
» Refactor to services when confidence grows
» Drop back to domain layer when remodelling
Crania Ltd | @ciaranmcnulty | #symfonycon
89. Driving the UI layer
» Simulate a browser with behat/minkextension
» Interact with domain model via the UI
» Ensures UI supports business actions
» Slow, brittle, flakey...
» Does not constrain API
Crania Ltd | @ciaranmcnulty | #symfonycon
90. Don't do this
Scenario: Buying a pair of jeans
Given I am on "/products/levi-501"
When I click on "#add-form input[type=submit]"
Then "#basket ul" should contain "jeans"
Crania Ltd | @ciaranmcnulty | #symfonycon
95. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class EndToEndContext implements RawMinkContext
{
/**
* @Given :course was proposed with a class size of :min to :max people
*/
public function wasProposedWithAClassSizeOfToPeople(string $course, int $min, int $max)
{
$this->course = $course;
$this->courseEnrolments->propose($course, $min, $max);
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
96. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class EndToEndContext implements RawMinkContext
{
/**
* @When only :learner enrols on this course
*/
public function learnerEnrolsOnCourse(string $learner)
{
$this->visitPath('/courses/' . $this->course);
$page = $this->getSession()->getPage();
$page->fillField('Your name', $learner);
$page->pressButton('Enrol');
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
97. Given "BDD for Beginners" was proposed with a class size of 2 to 3 people
When only Alice enrols on this course
Then this course will not be viable
class EndToEndContext implements RawMinkContext
{
/**
* @Then this course will not be viable
*/
public function thisCourseWillNotBeViable()
{
$this->visitPath('/courses/'.$this->course);
$this->assertSession()->elementExists('css', '#not-viable-warning');
}
}
Crania Ltd | @ciaranmcnulty | #symfonycon
98. Automating a real browser
» Avoid or minimise
» Orders of magnitude slower
» Required for end-to-end with JS
» Can often be replaced with JS cucumber stack
Crania Ltd | @ciaranmcnulty | #symfonycon
100. chrome --disable-gpu --headless
--remote-debugging-address=0.0.0.0
--remote-debugging-port=9222
or
docker run -d -p 9222:9222
--cap-add=SYS_ADMIN
justinribeiro/chrome-headless
Crania Ltd | @ciaranmcnulty | #symfonycon
101. Summary
» Drive domain objects directly to explore model
» Refactor to services when model is stable
» Add minimal UI coverage
Crania Ltd | @ciaranmcnulty | #symfonycon