BDD in Action: Behavior-Driven Development for the whole software lifecycle, 2nd Edition
9781617297533
Deliver software that does what it’s supposed to do! Behavior-Driven Development guides your software projects to succes
243
129
23MB
English
Pages 384
Year 2023
Report DMCA / Copyright
DOWNLOAD EPUB FILE
Table of contents :
inside front cover
BDD in Action
Praise for the first edition
Copyright
dedication
Deliberate Discovery—A “Sonnet”
contents
front matter
foreword
preface
acknowledgments
about this book
Who should read this book
How the book is organized: A road map
Prerequisites
About the code
Source code and other resources
liveBook discussion forum
about the authors
about the cover illustration
Part 1. First steps
1 Building software that makes a difference
1.1 BDD from 50,000 feet
1.2 What problems are you trying to solve?
1.2.1 Building the software right
1.2.2 Building the right software
1.2.3 The knowledge constraint: Dealing with uncertainty
1.3 Is BDD right for your projects?
1.4 What you will learn in this book
Summary
2 Introducing Behavior-Driven Development
2.1 BDD was originally designed to make teaching TDD easier
2.2 BDD also works well for requirements analysis
2.3 BDD principles and practices
2.3.1 Focus on features that deliver business value
2.3.2 Work together to specify features
2.3.3 Embrace uncertainty
2.3.4 Illustrate features with concrete examples
2.3.5 A Gherkin primer
2.3.6 Don’t write automated tests; write executable specifications
2.3.7 These principles also apply to unit tests
2.3.8 Deliver living documentation
2.3.9 Use living documentation to support ongoing maintenance work
2.4 Benefits of BDD
2.4.1 Reduced waste
2.4.2 Reduced costs
2.4.3 Easier and safer changes
2.4.4 Faster releases
2.5 Disadvantages and potential challenges of BDD
2.5.1 BDD requires high business engagement and collaboration
2.5.2 BDD works best in an Agile or iterative context
2.5.3 BDD doesn’t work well in a silo
2.5.4 Poorly written tests can lead to higher test-maintenance costs
Summary
3 BDD: The whirlwind tour
3.1 The BDD flow
3.2 Speculate: Identifying business value and features
3.2.1 Identifying business objectives
3.2.2 Discovering capabilities and features
3.2.3 Describing features
3.3 Illustrate: Exploring a feature with examples
3.3.1 Discovering the feature
3.3.2 Slicing the feature into User Stories
3.4 Formulate: From examples to executable specifications
3.5 Automate: From executable specifications to automated tests
3.5.1 Setting up a project with Maven and Cucumber
3.5.2 Recording the executable specifications in Cucumber
3.5.3 Automating the executable specifications
3.5.4 Implementing the glue code
3.6 Demonstrate: Tests as living documentation
3.7 BDD reduces maintenance costs
Summary
Part 2. What do I want? Defining requirements using BDD
4 Speculate: From business goals to prioritized features
4.1 The Speculate phase
4.1.1 Strategic Planning in a BDD project
4.1.2 Strategic Planning is a continuous activity
4.1.3 Strategic Planning involves both stakeholders and team members
4.1.4 Identifying hypotheses and assumptions rather than features
4.2 Describing business vision and goals
4.2.1 Vision, goals, capabilities, and features
4.2.2 What do you want to achieve? Start with a vision
4.2.3 The vision statement
4.2.4 Using vision statement templates
4.2.5 How will it benefit the business? Identify the business goals
4.2.6 Writing good business goals
4.2.7 Show me the money: Business goals and revenue
4.2.8 Popping the “why stack”: Digging out the business goals
4.3 Impact Mapping
4.3.1 Identify the pain point
4.3.2 Define the business goal
4.3.3 Who will benefit? Defining the actors
4.3.4 How should their behavior change? Defining the impacts
4.3.5 What should we do about it? Defining the deliverables
4.3.6 Reverse Impact Mapping
4.4 Pirate Canvases
4.4.1 Pirate Metrics
4.4.2 From Pirate Metrics to Pirate Canvases
4.4.3 Discovering what sucks
4.4.4 Building the Epic Landscape
Summary
5 Describing and prioritizing features
5.1 BDD and Product Backlog Refinement
5.2 What is a feature?
5.2.1 Features deliver capabilities
5.2.2 Features can be broken down into more manageable chunks
5.2.3 A feature can be described by one or more User Stories
5.2.4 A feature is not a User Story
5.2.5 Release features and product features
5.2.6 Not everything fits into a hierarchy
5.3 Real Options: Don’t make commitments before you have to
5.3.1 Options have value
5.3.2 Options expire
5.3.3 Never commit early unless you know why
5.4 Deliberate Discovery
5.5 Release and sprint planning with BDD
Summary
6 Illustrating features with examples
6.1 The Three Amigos and other requirements discovery workshops
6.2 Illustrating features with examples
6.3 Using tables to describe more complex requirements
6.4 Example Mapping
6.4.1 Example Mapping starts with a User Story
6.4.2 Finding rules and examples
6.4.3 Discovering new rules
6.4.4 Surfacing uncertainty
6.4.5 Facilitating an Example Mapping session
6.5 Feature Mapping
6.5.1 Feature Mapping begins with an example
6.5.2 Examples are broken into steps
6.5.3 Look for variations and new rules
6.5.4 Look for alternate flows
6.5.5 Grouping related flows and recording uncertainty
6.6 OOPSI
6.6.1 Outcomes
6.6.2 Outputs
6.6.3 Process
6.6.4 Scenarios
6.6.5 Inputs
Summary
7 From examples to executable specifications
7.1 Turning concrete examples into executable scenarios
7.2 Writing executable scenarios
7.2.1 A feature file has a title and a description
7.2.2 Describing the scenarios
7.2.3 The Given ... When ... Then structure
7.2.4 Ands and buts
7.2.5 Comments
7.3 Using tables in scenarios
7.3.1 Using tables in individual steps
7.3.2 Using tables of examples
7.3.3 Pending scenarios
7.4 Organizing your scenarios using feature files and tags
7.4.1 The scenarios go in a feature file
7.4.2 A feature file can contain one or more scenarios
7.4.3 Organizing the feature files
7.4.4 Using a flat directory structure
7.4.5 Organizing feature files by stories or product increments
7.4.6 Organizing feature files by functionality and capability
7.4.7 Annotating your scenarios with tags
7.4.8 Provide background and context to avoid duplication
7.5 Rules and examples
7.6 Expressive scenarios: Patterns and anti-patterns
7.6.1 The art of good Gherkin
7.6.2 What bad Gherkin looks like
7.6.3 Good scenarios are declarative, not imperative
7.6.4 Good scenarios do one thing, and one thing well
7.6.5 Good scenarios have meaningful actors
7.6.6 Good scenarios focus on the essential and hide the incidental
7.6.7 Gherkin scenarios are not test scripts
7.6.8 Good scenarios are independent
7.7 But where are all the details?
Summary
Part 3. How do I build it? Coding the BDD way
8 From executable specifications to automated acceptance tests
8.1 Introduction to automating scenarios
8.1.1 Step definitions interpret the steps
8.2 Setting up your project
8.2.1 Setting up a Cucumber project in Java or TypeScript
8.2.2 Organizing a Cucumber project in Java
8.2.3 Organizing a Cucumber project in TypeScript
8.3 Running Cucumber scenarios
8.3.1 Cucumber test runner classes in Java
8.3.2 Running Cucumber scenarios in JavaScript and TypeScript
8.4 Writing glue code
8.4.1 Injecting data with step definition parameters
8.4.2 Making your Cucumber Expressions more flexible
8.4.3 Cucumber Expressions and custom parameter types
8.4.4 Using regular expressions
8.4.5 Working with lists and data tables
8.5 Setting up and tearing down with backgrounds and hooks
8.5.1 Using background steps
8.5.2 Using hooks
8.6 Preparing your test environments using hooks
8.6.1 Using in-memory databases
8.7 Using virtual test environments
8.7.1 Using TestContainers to manage Docker containers for your tests
Summary
9 Writing solid automated acceptance tests
9.1 Writing industrial-strength acceptance tests
9.2 Using personas and known entities
9.2.1 Working with persona in your scenarios
9.2.2 Storing persona data in HOCON
9.3 Layers of abstraction
9.3.1 The Business Rules layer describes the expected outcomes
9.3.2 The Business Flow layer describes the user’s journey
9.3.3 Business tasks interact with the application or with other tasks
9.3.4 The Technical layer interacts with the system
Summary
10 Automating acceptance criteria for the UI layer
10.1 When and how should you test the UI?
10.2 Where does UI testing fit in your test automation strategy?
10.2.1 Which scenarios should be implemented as UI tests?
10.2.2 Illustrating user journeys
10.2.3 Illustrating business logic in the user interface
10.2.4 Documenting and verifying screen-specific business logic
10.2.5 Showing how information is rendered in the user interface
10.2.6 Automating web-based acceptance criteria using Selenium WebDriver
10.2.7 Getting started with WebDriver in Java
10.2.8 Setting up a WebDriver driver
10.2.9 Integrating WebDriver with Cucumber
10.2.10 Sharing WebDriver instances between step definition classes
10.2.11 Interacting with the web page
10.2.12 How to locate elements on a page
10.2.13 Interacting with web elements
10.2.14 Working with modern UI library components
10.2.15 Working with asynchronous pages and testing AJAX applications
10.3 Test-friendly web applications
10.4 Next steps
Summary
11 Test automation design patterns for the UI layer
11.1 The limitations of unstructured test scripts
11.2 Separating location logic from test logic
11.3 Introducing the Page Objects pattern
11.3.1 Page Objects are responsible for locating elements on a page
11.3.2 Page Objects represent objects on a page, not an entire page
11.3.3 Page Objects tell you about the state of a page
11.3.4 Page Objects perform business tasks or simulate user behavior
11.3.5 Page Objects present state in business terms
11.3.6 Page Objects hide wait conditions and other incidental implementation details
11.3.7 Page Objects do not contain assertions
11.3.8 WebDriver Page Factories and the @FindBy annotation
11.3.9 Finding collections
11.3.10 Page Objects in Serenity BDD
11.4 Going beyond Page Objects
11.4.1 Action classes
11.4.2 Query classes
11.4.3 DSL layers and builders
Summary
12 Scalable test automation with the Screenplay Pattern
12.1 What is the Screenplay Pattern, and why do we need it?
12.2 Screenplay fundamentals
12.3 What is an actor?
12.4 Actors perform tasks
12.5 Interactions model how actors interact with the system
12.5.1 Actors can perform multiple interactions
12.5.2 Interactions are objects, not methods
12.5.3 Interactions can perform waits as well as actions
12.5.4 Interactions can also interact with REST APIs
12.6 Abilities are how actors interact with the system
12.7 Writing our own interaction classes
12.8 Questions allow an actor to query the state of the system
12.8.1 Questions query the state of the system
12.8.2 Domain-specific Question classes make our code more readable
12.8.3 Actors can use questions to make assertions
12.9 Tasks model higher-level business actions
12.9.1 Simple tasks improve readability
12.9.2 More complex tasks enhance reusability
12.10 Screenplay and Cucumber
12.10.1 Actors and casts
12.10.2 The Screenplay stage
12.10.3 Defining a custom parameter type for actors
12.10.4 Defining persona in enum values
12.10.5 Screenplay assertions in Cucumber
Summary
13 BDD and executable specifications for microservices and APIs
13.1 APIs and how to test them
13.2 Defining a feature using a web UI and a microservice
13.2.1 Understanding the requirements
13.2.2 From requirements to executable specifications
13.3 Automating acceptance tests for microservices
13.4 The microservice architecture under test
13.4.1 Preparing the test data
13.4.2 Performing a POST query: Registering a Frequent Flyer member
13.4.3 Querying JSON responses with JSONPath
13.4.4 Performing a GET query: Confirming the frequent flyer address
13.4.5 Partial JSON Responses: Checking the new Frequent Flyer account details
13.4.6 Performing a DELETE query: Cleaning up afterward
13.5 Automating more granular scenarios and interacting with external services
13.6 Testing the APIs or testing with the APIs
Summary
14 Executable specifications for existing systems with Serenity/JS
14.1 Navigating an uncharted territory with Journey Mapping
14.1.1 Determine actors and goals to understand the business context
14.1.2 Determine what workflows support the goals of interest
14.1.3 Associate workflows with features
14.1.4 Establish a steel thread of scenarios that demonstrate the features
14.1.5 Determine verifiable consequences of each scenario
14.1.6 Using task analysis to understand the steps of each scenario
14.2 Designing scalable test automation systems
14.2.1 Using layered architecture to design scalable test automation systems
14.2.2 Using actors to link the layers of a test automation system
14.2.3 Using actors to describe personas
14.3 Capturing business context in the Specification layer
Summary
15 Portable test automation with Serenity/JS
15.1 Designing the Domain layer of a test automation system
15.1.1 Modeling business domain tasks
15.1.2 Implementing business domain tasks
15.1.3 Composing interactions into tasks
15.1.4 Using an outside-in approach to enable task substitution
15.1.5 Leveraging non-UI interactions with blended testing
15.1.6 Using tasks as a mechanism for code reuse
15.1.7 Implementing verification tasks
15.2 Designing a portable Integration layer
15.2.1 Writing portable tests for the web interfaces
15.2.2 Identifying page elements
15.2.3 Implementing Lean Page Objects
15.2.4 Implementing Companion Page Objects
15.2.5 Implementing portable interactions with Page Elements
15.2.6 Using Page Element Query Language to describe complex UI widgets
15.2.7 Configuring web integration tools
15.2.8 Sharing test code across projects and teams
Summary
16 Living documentation and release evidence
16.1 Living documentation: A high-level view
16.2 Reporting on feature readiness and feature coverage
16.2.1 Feature readiness: What features are ready to deliver
16.2.2 Feature coverage: What requirements have been built
16.3 Integrating a digital product backlog
16.4 Leveraging product backlog tools for better collaboration
16.5 Organizing the living documentation
16.5.1 Organizing living documentation by high-level requirements
16.5.2 Organizing living documentation using tags
16.5.3 Living documentation for release reporting
16.5.4 Low-level living documentation
16.5.5 Unit tests as living documentation
16.6 Living documentation for legacy applications
Summary