- •Contents
- •Preface
- •Acknowledgments
- •About the author
- •About the cover illustration
- •Higher product quality
- •Less rework
- •Better work alignment
- •Remember
- •Deriving scope from goals
- •Specifying collaboratively
- •Illustrating using examples
- •Validating frequently
- •Evolving a documentation system
- •A practical example
- •Business goal
- •An example of a good business goal
- •Scope
- •User stories for a basic loyalty system
- •Key Examples
- •Key examples: Free delivery
- •Free delivery
- •Examples
- •Living documentation
- •Remember
- •Tests can be good documentation
- •Remember
- •How to begin changing the process
- •Focus on improving quality
- •Start with functional test automation
- •When: Testers own test automation
- •Use test-driven development as a stepping stone
- •When: Developers have a good understanding of TDD
- •How to begin changing the team culture
- •Avoid “agile” terminology
- •When: Working in an environment that’s resistant to change
- •Ensure you have management support
- •Don’t make test automation the end goal
- •Don’t focus on a tool
- •Keep one person on legacy scripts during migration
- •When: Introducing functional automation to legacy systems
- •Track who is running—and not running—automated checks
- •When: Developers are reluctant to participate
- •Global talent management team at ultimate software
- •Sky Network services
- •Dealing with sign-off and traceability
- •Get sign-off on exported living documentation
- •When: Signing off iteration by iteration
- •When: Signing off longer milestones
- •Get sign-off on “slimmed down use cases”
- •When: Regulatory sign-off requires details
- •Introduce use case realizations
- •When: All details are required for sign-off
- •Warning signs
- •Watch out for tests that change frequently
- •Watch out for boomerangs
- •Watch out for organizational misalignment
- •Watch out for just-in-case code
- •Watch out for shotgun surgery
- •Remember
- •Building the right scope
- •Understand the “why” and “who”
- •Understand where the value is coming from
- •Understand what outputs the business users expect
- •Have developers provide the “I want” part of user stories
- •When: Business users trust the development team
- •Collaborating on scope without high-level control
- •Ask how something would be useful
- •Ask for an alternative solution
- •Make sure teams deliver complete features
- •When: Large multisite projects
- •Further information
- •Remember
- •Why do we need to collaborate on specifications?
- •The most popular collaborative models
- •Try big, all-team workshops
- •Try smaller workshops (“Three Amigos”)
- •Pair-writing
- •When: Mature products
- •Have developers frequently review tests before an iteration
- •When: Analysts writing tests
- •Try informal conversations
- •When: Business stakeholders are readily available
- •Preparing for collaboration
- •Hold introductory meetings
- •When: Project has many stakeholders
- •Involve stakeholders
- •Undertake detailed preparation and review up front
- •When: Remote Stakeholders
- •Prepare only initial examples
- •Don’t hinder discussion by overpreparing
- •Choosing a collaboration model
- •Remember
- •Illustrating using examples: an example
- •Examples should be precise
- •Don’t have yes/no answers in your examples
- •Avoid using abstract classes of equivalence
- •Ask for an alternative way to check the functionality
- •When: Complex/legacy infrastructures
- •Examples should be realistic
- •Avoid making up your own data
- •When: Data-driven projects
- •Get basic examples directly from customers
- •When: Working with enterprise customers
- •Examples should be easy to understand
- •Avoid the temptation to explore every combinatorial possibility
- •Look for implied concepts
- •Illustrating nonfunctional requirements
- •Get precise performance requirements
- •When: Performance is a key feature
- •Try the QUPER model
- •When: Sliding scale requirements
- •Use a checklist for discussions
- •When: Cross-cutting concerns
- •Build a reference example
- •When: Requirements are impossible to quantify
- •Remember
- •Free delivery
- •Examples should be precise and testable
- •When: Working on a legacy system
- •Don’t get trapped in user interface details
- •When: Web projects
- •Use a descriptive title and explain the goal using a short paragraph
- •Show and keep quiet
- •Don’t overspecify examples
- •Start with basic examples; then expand through exploring
- •When: Describing rules with many parameter combinations
- •In order to: Make the test easier to understand
- •When: Dealing with complex dependencies/referential integrity
- •Apply defaults in the automation layer
- •Don’t always rely on defaults
- •When: Working with objects with many attributes
- •Remember
- •Is automation required at all?
- •Starting with automation
- •When: Working on a legacy system
- •Plan for automation upfront
- •Don’t postpone or delegate automation
- •Avoid automating existing manual test scripts
- •Gain trust with user interface tests
- •Don’t treat automation code as second-grade code
- •Describe validation processes in the automation layer
- •Don’t replicate business logic in the test automation layer
- •Automate along system boundaries
- •When: Complex integrations
- •Don’t check business logic through the user interface
- •Automate below the skin of the application
- •Automating user interfaces
- •Specify user interface functionality at a higher level of abstraction
- •When: User interface contains complex logic
- •Avoid recorded UI tests
- •Set up context in a database
- •Test data management
- •Avoid using prepopulated data
- •When: Specifying logic that’s not data driven
- •Try using prepopulated reference data
- •When: Data-driven systems
- •Pull prototypes from the database
- •When: Legacy data-driven systems
- •Remember
- •Reducing unreliability
- •When: Working on a system with bad automated test support
- •Identify unstable tests using CI test history
- •Set up a dedicated continuous validation environment
- •Employ fully automated deployment
- •Create simpler test doubles for external systems
- •When: Working with external reference data sources
- •Selectively isolate external systems
- •When: External systems participate in work
- •Try multistage validation
- •When: Large/multisite groups
- •Execute tests in transactions
- •Run quick checks for reference data
- •When: Data-driven systems
- •Wait for events, not for elapsed time
- •Make asynchronous processing optional
- •Getting feedback faster
- •Introduce business time
- •When: Working with temporal constraints
- •Break long test packs into smaller modules
- •Avoid using in-memory databases for testing
- •When: Data-driven systems
- •Separate quick and slow tests
- •When: A small number of tests take most of the time to execute
- •Keep overnight packs stable
- •When: Slow tests run only overnight
- •Create a current iteration pack
- •Parallelize test runs
- •When: You can get more than one test Environment
- •Try disabling less risky tests
- •When: Test feedback is very slow
- •Managing failing tests
- •Create a known regression failures pack
- •Automatically check which tests are turned off
- •When: Failing tests are disabled, not moved to a separate pack
- •Remember
- •Living documentation should be easy to understand
- •Look for higher-level concepts
- •Avoid using technical automation concepts in tests
- •When: Stakeholders aren’t technical
- •Living documentation should be consistent
- •When: Web projects
- •Document your building blocks
- •Living documentation should be organized for easy access
- •Organize current work by stories
- •Reorganize stories by functional areas
- •Organize along UI navigation routes
- •When: Documenting user interfaces
- •Organize along business processes
- •When: End-to-end use case traceability required
- •Listen to your living documentation
- •Remember
- •Starting to change the process
- •Optimizing the process
- •The current process
- •The result
- •Key lessons
- •Changing the process
- •The current process
- •Key lessons
- •Changing the process
- •Optimizing the process
- •Living documentation as competitive advantage
- •Key lessons
- •Changing the process
- •Improving collaboration
- •The result
- •Key lessons
- •Changing the process
- •Living documentation
- •Current process
- •Key lessons
- •Changing the process
- •Current process
- •Key lessons
- •Collaboration requires preparation
- •There are many different ways to collaborate
- •Looking at the end goal as business process documentation is a useful model
- •Long-term value comes from living documentation
- •Index
Chapter 6 Specifying collaboratively |
93 |
If you read a card and say, “OK, I completely understand that,” you just go off and work, and you could have made a million and one assumptions. If you read a card and there is enough of “I’m not quite sure,” it pushes you to have a conversation, drawing it out at the start of an iteration, and then talking about different implementations and their effects. The testers would then consider how this impacts tests. BAs could think about what’s also coming up soon and see how that its in. “Just enough” means that your developer, BA, and QA are standing against a board and really discussing how this needs to work.
Whether you decide to have someone work one week ahead to prepare initial examples or hold an introductory meeting to identify open questions, remember that the goal is to prepare for the discussion later, not replace it.
Choosing a collaboration model
I don’t think there’s a one-size-its-all heuristic that will help you choose the best model for your team, including the balance between individual up-front work and more handson collaboration. After comparing the teams who had similar processes, I suggest basing your decision on the following criteria:
•How mature is the product?
•How much domain knowledge is there in the team?
•How much analysis do typical changes require?
•How close are the business users to the development team? Are they readily available to discuss and verify examples?
•Where’s the bottleneck in the process?
Immature products require big workshops and lots of up-front analysis. With immature products, it’s important to get testers and developers to contribute to speciications more actively, because the underlying system is changing frequently and they have insights that the business users won’t have.
Mature products might allow for less analysis up front and other models of collaboration. A mature product probably means that there will be few surprises. Business analysts and product owners most likely have a good idea of what the technology can give them, and they can do a good job of preparing examples up front.
If the team is relatively new or if testers and developers don’t have a solid understanding of the business domain, it’s worth running big workshops. All-hands workshops are a great way to eficiently transfer the knowledge about the business domain to the entire team. Once the team understands the business domain better, smaller and more focused discussions might be suficient.
94 Specification by Example
If typical changes require a lot of analysis, then someone in an analyst role should work ahead of the team to prepare detailed examples with stakeholders. Otherwise, any discussion during the workshops will end quickly and with too many open questions. If relatively small and well-understood features normally come into development, preparing some basic examples up front to make the discussion run more smoothly might be suficient.
Teams with remote business users typically have to do more work up front than those with business users who are readily available to answer open questions. If the business users aren’t available for speciication workshops at all, most questions and functional gaps have to be identiied and addressed up front.
Finally, there’s no point in overloading team members who are already a bottleneck in the process. The teams where testing is a bottleneck should get developers and business analysts much more engaged in up-front work. Likewise, the teams where business analysts or subject matter experts are the bottleneck should get testers to help with upfront analysis.
Remember
•Speciication by Example relies heavily on collaboration between business users and delivery team members.
•Everyone on the delivery team shares the responsibility for the right speciications. Programmers and testers have to offer input about the technical implementation and the validation aspects.
•Most teams collaborate on speciications in two phases: Someone works up front to prepare initial examples for a feature, and then those who have a stake in the feature discuss it, adding examples to clarify or complete the speciication.
•The balance between the work done in preparation and the work done during collaboration depends on several factors: the maturity of the product, the level of domain knowledge in the delivery team, typical change request complexity, process bottlenecks, and availability of business users.
7
Illustrating using examples
Examples are a good way to avoid ambiguities and communicate with precision. We use examples in everyday conversation and in writing without even thinking about it—when I searched online for the phrase “for example,” Google
returned more than 210 million pages that use this term.
With traditional speciications, examples appear and disappear several times in the software development process. Business analysts often get examples of existing orders, invoices, and reports from business users, which they translate into abstract requirements. Developers invent examples to explain edge cases and clarify them with business users or analysts and then translate the cases to code, without recording the examples. Testers design test cases that are examples of how the system is expected to work; they keep these examples to themselves and don’t communicate them to programmers or analysts.
Everyone invents their own examples, but there’s nothing to ensure that these examples are even consistent, let alone complete. In software development, this is why the end result is often different from what was expected at the beginning. To avoid this, we have to prevent misinterpretation between different roles and maintain one source of truth.
Examples are a good tool for avoiding communication problems. We can avoid playing the telephone game by ensuring that we capture all the examples—from start to inish—and use them consistently in analysis, development, and testing.
Marta Gonzalez Ferrero was working as a test lead at Beazley when they introduced Speciication by Example. According to her, the development team was committing to more work than they could produce, and they often realized they needed a lot more information than they were getting at the start of the implementation. The situation was further complicated by the fact that they were running six-week iterations, and the development team and the business analysts were on different continents. The acceptance criteria that the programmers were receiving from the business analysts was relatively abstract (for example, “make sure that for this business
95
96 Speciication by Example
unit all correct products are displayed”). Finding out that something important was missinghalfwaythroughaniterationwouldseriouslydisrupttheoutput.Oneiterationendedwithcustomerssayingthattheteamdeliveredsomethingcompletelydifferentfromwhat was expected. The last week of each iteration was reserved for the model ofice: effectively, an iteration demonstration. Ferrero traveled to the United States for one model ofice and worked with business analysts on illustrating requirements with examples for two days. As a result, the team committed to 20% less work for the next iteration and delivered what they promised.
“The feeling in the team was also much better,” said Ferrero. “Before that, [the developers] were working with a feeling that they were making it up as they go, and had to wait for feedback from business analysts.” According to Ferrero, the amount of rework dropped signiicantly after they started illustrating requirements using examples.
Ferrero’s wasn’t the only team to experience results like these. Almost all the teams proiled in this book conirmed that illustrating requirements using examples is a much more effective technique than specifying with abstract statements. Because examples are concrete and unambiguous, they’re an ideal tool for making requirements precise—this is why we use them to clarify meaning in everyday communication.
In Exploring Requirements,1 Gerald Weinberg and Donald Gause write that one of the best ways to check if requirements are complete is to try designing black-box test cases against them. If we don’t have enough information to design good test cases, we deinitely don’t have enough information to build the system. Illustrating requirements using examples is a way to specify how we expect the system to work with enough detail that we can check that assertion. Examples used to illustrate requirements are good black-box tests.
From my experience, it takes far less time to illustrate requirements with examples than to implement them. Concluding that we don’t have enough information to illustrate something with examples takes far less time than coming to the same realization after trying to implement the software. Instead of starting to develop an incomplete story only to see it blow up in the middle of an iteration, we can lush such problems out during the collaboration on speciications while we can still address them—and when the business users are still available.
In May 2009 I ran a three-hour workshop on Speciication by Example2 during the Progressive .NET tutorials. Around 50 people, mostly software developers and testers, participated in this workshop. We simulated a common situation: A customer directs the team to a competitor site and asks them to copy some functionality.
1 |
Gerald M. Weinberg and Donald C. ExploringGause, Requirements: Quality Before Design |
|
(New York, Dorset House, 1989). |
2 |
See http://gojko.net/2009/05/12/examples-make-it-easy-to-spot-inconsistencies |