RSpec and Cucumber tutorial

rspec cucumber features and rspec feature cucumber. rspec and cucumber difference pdf free download
Prof.WilliamsHibbs Profile Pic
Prof.WilliamsHibbs,United States,Teacher
Published Date:28-07-2017
Your Website URL(Optional)
Comment
Prepared exclusively for Shohei TanakaCHAPTER 1 Introduction Behaviour-Driven Development began its journey as an attempt to better understand and explain the process of Test-Driven Development. Dan North had observed that the developers he was coaching were having a tough time relating to TDD as a design tool and came to the conclusion that it had a lot to do with the word test. Dave Astels took that to the next step in the seminal article “A New Look at 1 Test-Driven Development,” in which he suggested that even experienced TDDers were not getting all the benefit from TDD that they could be getting. To put this into perspective, perhaps a brief exploration of Test-Driven Development is in order. 1.1 Test-Driven Development: Where It All Started Test-Driven Development is a developer practice that involves writing tests before writing the code being tested. Begin by writing a very small test for code that does not yet exist. Run the test, and, naturally, it fails. Now write just enough code to make that test pass. No more. Once the test passes, observe the resulting design, and refactor any duplica- 2 tion you see. It is natural at this point to judge the design as too simple to handle all the responsibilities this code will have. Instead of adding more code, document the next responsibility in the form of the next test. Run it, watch it fail, write just enough code to get it to pass, review the design, and remove duplication. Now add the next test, watch it 1.http://techblog.daveastels.com/2005/07/05/a-new-look-at-test-driven-development/ 2. Refactoring: improving the design of code without changing its behavior. From Martin Fowler’s Refactoring FBBO99. Prepared exclusively for Shohei Tanaka report erratum • discussChapter 1. Introduction • 4 fail, get it to pass, refactor, fail, pass, refactor, fail, pass, refactor, and so on, and so on. In many unit testing systems, when a test fails, we see the results printed in red. Then when it passes, the results are printed in green. Because of this, we often refer to this cycle as red/green/refactor. Emergent Design As a code base increases in size, we find that more attention is consumed by the refactoring step. The design is constantly evolving and under constant review, though it is not predetermined. This is emergent design at a granular level and is one of the most significant by-products of Test-Driven Development. Rather than thinking of TDD as a testing practice, we see it as a technique used to deliver high-quality code to testers, who are responsible for formal testing practices (see But What If “the Testers” Is Me?). Joe asks: But What If “the Testers” Is Me? Not all project teams have a separate tester role. On teams that don’t, the notion of pushing off the responsibility of testing practices to other people doesn’t really fly. In cases like this, it’s still helpful to separate testing practices from TDD. When you’re “wearing your TDD hat,” focus on red/green/refactor, design, and doc- umentation. Don’t think about testing. Once you’ve developed a body of code, put on your “tester hat,” and think about all the things that could go wrong. This is where you add all the crazy edge cases, using exploratory testing to weed out the nasty bugs hiding in the cracks and documenting them as you discover them with more code examples. And this is where the Test in TDD becomes a problem. Specifically, it is the idea of unit testing that often leads new TDDers to verify things such as making sure that a register() method stores a Registration in a Registry’s registrations collection and that collection is specifically an Array. This sort of detail in a test creates a dependency in the test on the internal structure of the object being tested. This dependency means that if other requirements guide us to change the Array to a Hash, this test will fail, even though the behavior of the object hasn’t changed. This brittleness can make test suites much more expensive to maintain and is the primary reason for test suites to become ignored and, ultimately, discarded. Prepared exclusively for Shohei Tanaka report erratum • discussBehaviour-Driven Development: The Next Step • 5 So if testing internals of an object is counterproductive in the long run, what should we focus on when we write these tests first? 1.2 Behaviour-Driven Development: The Next Step The problem with testing an object’s internal structure is that we’re testing what an object is instead of what it does. What an object does is significantly more important. The same is true at the application level. Stakeholders don’t usually care that data is being persisted in an ANSI-compliant, relational database. They care that it’s in “the database,” but even then, they generally mean is that it’s stored somewhere and they can get it back. It’s All Behavior BDD puts the focus on behavior instead of structure, and it does so at every level of development. Whether we’re talking about an object calculating the distance between two cities, another object delegating a search off to a third- party service, or a user-facing screen providing feedback when we provide invalid input, it’s all behavior Once we acknowledge this, it changes the way we think about driving out code. We begin to think more about interactions between people and systems, or between objects, than we do about the structure of the objects. Getting the Words Right We believe that most of the problems that software development teams face are communication problems. BDD aims to help communication by simplifying the language we use to describe scenarios in which the software will be used: Given some context, When some event occurs, Then I expect some outcome. Given, When, Then, the BDD triad, are simple words that we use whether we’re talking about application behavior or object behavior. They are easily understood by business analysts, testers, and developers alike. As you’ll see in Section 17.8, Given/When/Then, on page 242 and throughout the book, these words are embedded right in the language of Cucumber. 1.3 RSpec RSpec was created by Steven Baker in 2005. Steven had heard about BDD from Aslak Hellesøy, who had been working on a project with Dan North when the idea first came to light. Steven was already interested in the idea when Prepared exclusively for Shohei Tanaka report erratum • discussChapter 1. Introduction • 6 Dave Astels suggested that with languages like Smalltalk and Ruby, we could more freely explore new TDD frameworks that could encourage focus on behavior. And RSpec was born. Although the syntactic details have evolved since Steven’s original version of RSpec, the basic premise remains. We use RSpec to write executable examples of the expected behavior of a small bit of code in a controlled context. Here’s how that might look: describeMovieListdo context"whenfirstcreated"do it"isempty"do movie_list=MovieList.new movie_list.shouldbe_empty end end end The it() method creates an example of the behavior of a MovieList, with the context being that the MovieList was just created. The expression movie_list.shouldbe_empty is self-explanatory. Just read it out loud. You’ll see how be_empty() interacts with movie_list in Section 13.3, Predicate Matchers, on page 163. Running this code in a shell with the rspec command yields the following specification: MovieListwhenfirstcreated isempty Add some more contexts and examples, and the resulting output looks even more like a specification for a MovieList object. MovieListwhenfirstcreated isempty MovieListwith1item isnotempty includesthatitem Of course, we’re talking about the specification of an object, not a system. You could specify application behavior with RSpec. Many do. Ideally, however, for specifying application behavior, we want something that communicates in broader strokes. And for that, we use Cucumber. 1.4 Cucumber As you’ll read about in Chapter 11, Writing Software That Matters, on page 121, BDD is a full-stack agile methodology. It takes some of its cues from Prepared exclusively for Shohei Tanaka report erratum • discussCucumber • 7 Extreme Programming, including a variation of Acceptance Test-Driven Devel- opment called Acceptance Test-Driven Planning (ATDP). In ATDP, we use customer acceptance tests to drive the development of code. Ideally, these are the result of a collaborative effort between the customer and the delivery team. Sometimes they are written by the delivery team and then reviewed/approved by the customer. In either case, they are customer facing and must be expressed in a language and format that customers can relate to. Cucumber gives us that language and format. Cucumber reads plain-text descriptions of application features with example scenarios and uses the scenario steps to automate interaction with the code being developed. Here’s an example: Line 1Feature:paybillon-line - -InordertoreducethetimeIspendpayingbills -Asabankcustomerwithacheckingaccount 5Iwanttopaymybillson-line - - Scenario:payabill -Givencheckingaccountwith50 -AndapayeenamedAcme 10AndanAcmebillfor37 -WhenIpaytheAcmebill -ThenIshouldhave13remaininginmycheckingaccount - Andthepaymentof37toAcmeshouldbelistedinRecentPayments Cucumber Seeds Even before we started exploring structures and syntax for RSpec, Dan North had been exploring a completely different model for a BDD tool. He wanted to document and drive behavior in a simplified language that could be easily understood by customers, developers, testers, business analysts, and so on. The early result of that exploration was the JBehave library, which is still in active use and development. Dan ported JBehave to Ruby as RBehave, and we merged it into RSpec as the Story Runner. It only supported scenarios written in Ruby at first, but we later added support for plain text, opening up a whole new world of expressiveness and access. But as new possibilities were revealed, so were limitations. In the spring of 2008, Aslak Hellesøy set out to rewrite RSpec’s Story Runner with a real grammar defined with Nathan Sobo’s Treetop library. Aslak dubbed it Cucumber at the suggestion of his fiancée, Patricia Carrier, thinking it would be a short-lived working title until it was merged back into RSpec. Little did either of them know that Cucumber would develop a life of its own. Prepared exclusively for Shohei Tanaka report erratum • discussChapter 1. Introduction • 8 Everything up to and including the Scenario declaration on line 7 is treated as documentation (not executable). The subsequent lines are steps in the scenario. In Chapter 4, Automating Features with Cucumber, on page 35, you’ll be writing step definitions in Ruby. These step definitions interact with the code being developed and are invoked by Cucumber as it reads in the scenario. Don’t worry if that doesn’t make perfect sense to you just yet. For now, it’s only important to understand that both RSpec and Cucumber help us specify the behavior of code with examples that are programmatically tied to that code. The details will become clear as you read on. We use Cucumber to describe the behavior of applications and use RSpec to 3 describe the behavior of objects. If you’ve ever done TDD before, you’re probably familiar with the red/green/refactor cycle. With the addition of a higher-level tool like Cucumber, we’ll actually have two concentric red/green/ refactor cycles, as depicted in Figure 1, The BDD cycle, on page 9. Both cycles involve taking small steps and listening to the feedback you get from the tools. We start with a failing step (red) in Cucumber (the outer cycle). To get that step to pass, we’ll drop down to RSpec (the inner cycle) and drive out the underlying code at a granular level (red/green/refactor). 1.5 The BDD Cycle At each green point in the RSpec cycle, we’ll check the Cucumber cycle. If it is still red, the resulting feedback should guide us to the next action in the RSpec cycle. If it is green, we can jump out to Cucumber, refactor if appropri- ate, and then repeat the cycle by writing a new failing Cucumber step. In the next chapter, we’ll get you set up with Cucumber and RSpec and walk you through a simple example of each tool. In the tutorial that begins in Chapter 3, Describing Features, on page 19, we’ll use a number of features in Cucumber and RSpec. In most cases, we’ll only touch the surface of a feature, covering just enough to be able to use it as needed for this project, with references to other places in the book where you can go to learn more of the detail and philosophy behind each feature. 3. Although we use Cucumber to focus on high-level behavior and use RSpec to focus on more granular behavior, each can be used for either purpose. Prepared exclusively for Shohei Tanaka report erratum • discussThe BDD Cycle • 9 Figure 1—The BDD cycle Prepared exclusively for Shohei Tanaka report erratum • discussCHAPTER 2 Hello All good programming language books start with the obligatory Hello World example. Although RSpec is not an all-purpose programming language, it is sometimes described as a domain-specific language (DSL), for describing the behavior of objects. Similarly, Cucumber is a DSL for describing the behavior of applications. To satisfy this requirement, we’ll write Hello examples for both RSpec and Cucumber. But first things first, let’s get the environment set up. 2.1 Installation If you haven’t done so already, the first thing you’ll need to do is install the 1 rspec and cucumber gems. Open a shell, and type the following (you may need to prefix this with sudo on some systems): geminstallrspecversion2.0.0 Now type rspechelp, and you should see output that starts like this: Usage:rspecoptionsfilesordirectories If you don’t see that, or something close, then the installation failed for any number of reasons. If that happened, we recommend you email the rspec- users mailing list. All the authors of this book and many other knowledgeable members of the community are members and will be happy to help you sort 2 it out. 1. We assume that you already have a basic working knowledge of Ruby and Rubygems. If you don’t, we can recommend Programming Ruby: The Pragmatic Programmers’ Guide TFH05 to learn about Ruby 1.8 and/or Programming Ruby 1.9: The Pragmatic Programmers’ Guide TFH09 if you want to learn about Ruby 1.9. 2.http://rubyforge.org/mailman/listinfo/rspec-users Prepared exclusively for Shohei Tanaka report erratum • discussChapter 2. Hello • 12 Assuming all is well so far, the next thing to do is install Cucumber by typing this: geminstallcucumberversion0.9.2 Again, you may need to prefix this command with sudo on some systems. Now type cucumberhelp, and you should see output that starts something like this: Usage:cucumberoptionsFILEDIRURL:LINE:LINE+ In the unlikely event of a Cucumber installation failure, please consult the 3 Cucumber Google group for assistance. Now that the tools are installed, it’s time to say hello 2.2 Hello RSpec Create a file named greeter_spec.rb anywhere on your system, open it in your favorite text editor, and type the following code: hello/1/greeter_spec.rb Line 1 describe"RSpecGreeter"do 2it"shouldsay'HelloRSpec'whenitreceivesthegreet()message"do 3greeter=RSpecGreeter.new 4greeting=greeter.greet 5greeting.should=="HelloRSpec" 6end 7 end We’ll get into all the details of this later in the book, but briefly here’s an explanation. We start by declaring an example group using the describe() method on line 1. On line 2, we declare an example using the it() method. Within the example, we initialize a new RSpecGreeter on line 3. This is the Given in this example: the context that we set up and take for granted as a starting point. On line 4, we assign the value returned by the greet() method to a greeting variable. This is the When in this example: the action that we’re focused on. Lastly, on line 5, we set an expectation that the value of greeting should equal “Hello RSpec” This is the Then of this example: the expected outcome. 3.http://groups.google.com/group/cukes Prepared exclusively for Shohei Tanaka report erratum • discussHello RSpec • 13 As you’ll see throughout this book, we use these three simple words—Given, When, and Then—because they are easily understood by both technical and nontechnical contributors to a project. Now save the file, open a command shell, cd into the directory in which it is saved, and type this command: rspecgreeter_spec.rb You should see output including this in the shell: uninitializedconstantRSpecGreeter This is RSpec telling you that the example failed because there is no RSpecGr eeter class defined yet. To keep things simple, let’s just define it in the same file. Adding this definition, the entire file should look like this: hello/2/greeter_spec.rb classRSpecGreeter defgreet "HelloRSpec" end end describe"RSpecGreeter"do it"shouldsay'HelloRSpec'whenitreceivesthegreet()message"do greeter=RSpecGreeter.new greeting=greeter.greet greeting.should=="HelloRSpec" end end Run the file again by typing rspecgreeter_spec.rb, and the output should be something like this: . Finishedin0.00075seconds 1example,0failures Success The dot on the first line represents the one example that was run, and the summary on the last line reports that there was one example and zero failures. This is a bit different from the Hello World examples we’re used to seeing in programming language books because it doesn’t actually print Hello RSpec to the command line. In this case, the feedback we get tells us the example ran and the code works as expected. Prepared exclusively for Shohei Tanaka report erratum • discussChapter 2. Hello • 14 2.3 Hello Cucumber For Cucumber, we’re going to need a little bit more structure, so let’s create a small project directory named hello. Inside the hello directory, add two directories named features and spec, and then move the greeter_spec.rb file from the RSpec example into the hello/spec directory. Now create a file greeter_says_hello.feature in the features directory, and enter the following text: hello/3/features/greeter_says_hello.feature Feature:greetersayshello InordertostartlearningRSpecandCucumber AsareaderofTheRSpecBook IwantagreetertosayHello Scenario:greetersayshello Givenagreeter WhenIsenditthegreetmessage ThenIshouldsee"HelloCucumber" In the shell, cd to the project root, the hello directory, and type cucumberfeatures. You should see output like this: Feature:greetersayshello InordertostartlearningRSpecandCucumber AsareaderofTheRSpecBook IwantagreetertosayHello Scenario:greetersayshellofeatures/greeter_says_hello.feature:7 Givenagreeterfeatures/greeter_says_hello.feature:8 WhenIsenditthegreetmessagefeatures/greeter_says_hello.feature:9 ThenIshouldsee"HelloCucumber"features/greeter_says_hello.feature:10 1scenario(1undefined) 3steps(3undefined) 0m0.003s Youcanimplementstepdefinitionsforundefinedstepswiththesesnippets: Given/agreeter/do pendingexpresstheregexpabovewiththecodeyouwishyouhad end When/Isenditthegreetmessage/do pendingexpresstheregexpabovewiththecodeyouwishyouhad end Then/Ishouldsee"(")" Prepared exclusively for Shohei Tanaka report erratum • discussHello Cucumber • 15 We’ll go into the details of this output later, but the high points are that we see the feature and scenario text from the greeter_says_hello.feature file, a summary of everything that was run, and then some code snippets that we can use for our step definitions. A step definition is a method that creates a step. In this example, we use the Given(), When(), and Then() methods to write step definitions, each of which takes a Regexp and a block. Cucumber will read the first step in the scenario, Given a greeter; look for a step definition whose regular expression matches that step; and then execute that step definition’s block. To get this scenario to pass, we need to store step definitions in a file that Cucumber can load. Go ahead and add a step_definitions directory inside hello/fea- tures, and add a file named greeter_steps.rb with the following code: hello/4/features/step_definitions/greeter_steps.rb Given/agreeter/do greeter=CucumberGreeter.new end When/Isenditthegreetmessage/do message=greeter.greet end Then/Ishouldsee"(")"/dogreeting message.should==greeting end This looks a lot like the code snippets that we got from running the cucumber command, but we’ve added some code in each step definition. Now run cucumberfeatures again, and the output should look more like this: Feature:greetersayshello InordertostartlearningRSpecandCucumber AsareaderofTheRSpecBook IwantagreetertosayHello Scenario:greetersayshello\ features/greeter_says_hello.feature:7 Givenagreeter\ features/step_definitions/greeter_steps.rb:1 uninitializedconstantCucumberGreeter(NameError) ./features/step_definitions/greeter_steps.rb:2:in`/agreeter/' features/greeter_says_hello.feature:8:in`Givenagreeter' WhenIsenditthegreetmessage\ features/step_definitions/greeter_steps.rb:5 ThenIshouldsee"HelloCucumber"\ features/step_definitions/greeter_steps.rb:9 Prepared exclusively for Shohei Tanaka report erratum • discussChapter 2. Hello • 16 FailingScenarios: cucumberfeatures/greeter_says_hello.feature:7Scenario:greetersayshello 1scenario(1failed) 3steps(1failed,2skipped) 0m0.003s The first step is failing because we haven’t defined a CucumberGreeter. The next two steps are being skipped because the first one failed. Again, to keep things simple, go ahead and define the missing class right alongside the step defini- tions in greeter_steps.rb. Here is the full listing: hello/5/features/step_definitions/greeter_steps.rb classCucumberGreeter defgreet "HelloCucumber" end end Given/agreeter/do greeter=CucumberGreeter.new end When/Isenditthegreetmessage/do message=greeter.greet end Then/Ishouldsee"(")"/dogreeting message.should==greeting end Now we should get different output when we run cucumberfeatures: Feature:greetersayshello InordertostartlearningRSpecandCucumber AsareaderofTheRSpecBook IwantagreetertosayHello Scenario:greetersayshello\ features/greeter_says_hello.feature:7 Givenagreeter\ features/step_definitions/greeter_steps.rb:7 WhenIsenditthegreetmessage\ features/step_definitions/greeter_steps.rb:11 ThenIshouldsee"HelloCucumber"\ features/step_definitions/greeter_steps.rb:15 1scenario(1passed) 3steps(3passed) 0m0.003s Prepared exclusively for Shohei Tanaka report erratum • discussHello Cucumber • 17 This time, the scenario and all of its steps pass. So, now we have a passing RSpec example and a passing Cucumber scenario. You can type rspecspec, and the rspec command will run everything inside the spec directory. If you moved greeter_spec.rb to the spec directory, then you should see output similar to the output you saw at the end of Section 2.2, Hello RSpec, on page 12. There is certainly a lot of detail yet to cover here, but that’s why this is a book and not a blog post In the chapters that follow, you’ll learn all about RSpec and Cucumber and how to use them in the context of Behaviour-Driven Development. So, what are you waiting for? All the good stuff is yet to come. Turn the page already Prepared exclusively for Shohei Tanaka report erratum • discussCHAPTER 3 Describing Features To get started doing BDD with RSpec and Cucumber, we’re going to write a problem-solving game that we’ll call Codebreaker. Our version will be played in a shell, but it is based on a classic pencil and paper game named Bulls 1 and Cows. We picked a game because we thought it would be more fun than a banking or social networking application. We also wanted something that was small enough to accomplish in a few short chapters but complex enough to provide some interesting edge cases. By the time we get through this tutorial, we’ll have planned a small release, planned and executed an iteration, developed some code from the outside in, and have a game we can play at the command line. We’ll develop the game using the process and practices of Behaviour-Driven Development that we introduced in Chapter 1, Introduction, on page 3, and that you’ll read more about throughout this book. We’re going to drive straight on through, stopping only occasionally to review things and answer questions at the end of each chapter. When you’re looking for more detail, we’ll tell you where you can find it, but we won’t get hung up in too much detail during this part of the book so that we can experience the feel of BDD in the trenches. But before we develop anything, let’s start with an overview of the game and its rules. 1.http://en.wikipedia.org/wiki/Bulls_and_cows Prepared exclusively for Shohei Tanaka report erratum • discussChapter 3. Describing Features • 20 3.1 Introducing Codebreaker Codebreaker is a logic game in which a code-breaker tries to break a secret code created by a code-maker. The code-maker, which will be played by the application we’re going to write, creates a secret code of four numbers between 1 and 6. The code-breaker then gets some number of chances to break the code. In each turn, the code-breaker makes a guess of four numbers (again, 1 to 6). The code-maker then marks the guess with up to four + and - signs. A + indicates an exact match: one of the numbers in the guess is the same as one of the numbers in the secret code and in the same position. A - indicates a number match: one of the numbers in the guess is the same as one of the numbers in the secret code but in a different position. For example, given a secret code 1234, a guess with 4256 would earn a +-. The + is for the 2 in the second position in the guess, which matches the 2 in the secret code in both number and position: an exact match. The - is for the 4 in the first position in the guess, which matches the 4 in the code but not in the same position: a number match. The plus signs for the exact matches always come before the minus signs for the number matches and don’t align with specific positions in the guess or the secret code. 3.2 Planning the First Release As you’ll read about in Chapter 11, Writing Software That Matters, on page 121, one of the three principles of BDD is “Enough is enough.” We want to 2 avoid the pitfalls of the Big Design Up Front, but we also want to do enough planning to know we’re heading in the right direction. We’ll do some of that planning in this chapter, picking out user stories for our first iteration. For the first release, we simply want to be able to play the game. We should be able to type a command in a shell to start it up, submit guesses, and see the mark for each of our guesses until we crack the code. That may sound like an over-simplification, and it certainly leaves open more questions than it answers, but it sets a target in our sights, which serves as a basis from which we can start assembling a list of user stories that will get us there. 2. BDUF is designing an application in significant detail before writing the first line of code. Prepared exclusively for Shohei Tanaka report erratum • discussPlanning the First Release • 21 Selecting Stories A great way to get started gathering user stories is to do a high-level brain dump of the sorts of things we might like to do. Here are some titles to get started: • Code-breaker starts game • Code-breaker submits guess • Code-breaker wins game • Code-breaker loses game • Code-breaker plays again • Code-breaker requests hint • Code-breaker saves score See how each of these is phrased as role + action? The role is the code- breaker role each time because this game has only one kind of user. In other applications, we might have several different kinds of users, in which case we want to express stories in terms of a specific role (not just a generic user), because that impacts how we think about each requirement and why we’re implementing code to satisfy it. See Focus on the Role for more on this. Focus on the Role Mike Cohn, author of User Stories Applied Coh04, talked about focusing on the role when writing user stories at the Agile 2006 Conference. The example he gave was that of an airline reservation system, pointing out that the regular business traveler booking a flight wants very different things from such a system than the occasional vacation traveler. Think about that for a minute. Imagine yourself in these two different roles and the different sorts of details you would want from such a system based on your goals. For starters, the business traveler might want to maintain a profile of regular itineraries, while the vacationer might be more interested in finding package deals that include hotel and car at a discount. Focusing on this distinction is a very powerful tool in getting down to the details of the features required of a system. These are also high level and don’t tell us much about how the system should respond to these actions. Let’s take these titles and generate some user stories from them. A Token for a Conversation We’ll use the simple format described in Extreme Programming Installed JAH02. The idea is that there should be just enough information to serve Prepared exclusively for Shohei Tanaka report erratum • discussChapter 3. Describing Features • 22 as a token for a conversation that should take place as we get closer to 3 implementation. Code-breaker starts game The code-breaker opens a shell, types a command, and sees a welcome message and a prompt to enter the first guess. Code-breaker submits guess The code-breaker enters a guess, and the system replies by marking the guess according to the marking algorithm. Code-breaker wins game The code-breaker enters a guess that matches the secret code exactly. The system responds by marking the guess with four + signs and a message congratulating the code-breaker on breaking the code in however many guesses it took. We can already see some of the challenges ahead: “according to the marking algorithm” is going to require some conversation with the stakeholders. In fact, this is where we’ll spend most of our time both planning and developing, because the marking algorithm is where much of the complexity lies. Continuing with stories for the other titles: Code-breaker loses game After some number of turns, the game tells the code-breaker that the game is over (need to decide how many turns and whether to reveal the code). Code-breaker plays again After the game is won or lost, the system prompts the code-breaker to play again. If the code-breaker indicates yes, a new game begins. If the code-breaker indicates no, the system shuts down. Code-breaker requests hint At any time during a game, the code-breaker can request a hint, at which point the system reveals one of the numbers in the secret code. Code-breaker saves score After the game is won or lost, the code-breaker can opt to save information about the game: who (initials?), how many turns, and so on. Note the deliberate lack of detail and even some open questions. We’ll get into some detail as we choose which of these stories we want to include in the release, and then we’ll get more detailed in each iteration within the release. 3. In Extreme Programming, index cards are the preferred medium for user stories. This keeps them lightweight and reinforces the idea that these are not formal documentation. There is an XP joke that if you can’t fit a requirement on an index card, you should get a smaller card. Prepared exclusively for Shohei Tanaka report erratum • discussPlanning the First Release • 23 But at each phase, we want to do just enough planning to keep on moving, and no more. Narrowing Things Down 4 Now that we have some stories, let’s consider them in the context of the stated goal for the initial release: to simply be able to play the game. Looking at the original list of stories, there are only two that are absolutely necessary to meet that goal: • Code-breaker starts game • Code-breaker submits guess We definitely have to be able to start the game somehow so that one is a no- brainer. Once we’ve started the game, if we can submit a guess and get the mark, then we can submit more guesses. As soon as we get a perfect mark, the game is won, and we hit Ctrl+C to stop the game and start the game back up to play again. What do you think? Maybe it would be a bit more satisfying to play if the game told us when we won—a bit of positive feedback to motivate us to play again. That sounds pretty important, so let’s add the Code-breakerwinsgame story to our release plan. Of course, having to hit Ctrl+C and then restart the game to play again is a little cheesy, don’t you think? That just won’t do, so let’s also add the Code- breakerplaysagain story as well. So, now our release plan includes these stories: • Code-breaker starts game • Code-breaker submits guess • Code-breaker wins game • Code-breaker plays again Hmmm. Seeing those together brings up the question of what will happen if the code-breaker doesn’t win after some number of guesses. How else will we know when to prompt the code-breaker to play again? Maybe we should add the Code-breakerlosesgame story. What do you think? Wait, wait, wait We’re heading down a slippery slope here. Pretty soon we’ll be including our entire backlog of stories in the first release Let’s step back for a second. What is the release goal? To be able to play the game. Let’s examine that a bit. Why does playing the game matter? Why do we want to be able to play the game? 4. If we were developing this for commercial distribution, we’d likely have dozens more stories, even for such a simple game. Prepared exclusively for Shohei Tanaka report erratum • discuss

Advise: Why You Wasting Money in Costly SEO Tools, Use World's Best Free SEO Tool Ubersuggest.