The cucumber book 2nd edition pdf download






















There's also live online events, interactive content, certification prep materials, and more. Explore a preview version of The Cucumber Book, 2nd Edition right now. Your customers want rock-solid, bug-free software that does exactly what they expect it to do. Yet they can't always articulate their ideas clearly enough for you to turn them into code.

You need Cucumber: a testing, communication, and requirements tool-all rolled into one. All the code in this book is updated for Cucumber 2. Salary surveys worldwide regularly place software architect in the top 10 best jobs, yet no real …. Grokking Algorithms is a friendly take on this core computer science topic. Visit our Developers Forum. Filter By Category. General Learning Resources. The Cucumber Book, Second Edition.

Latest Threads About This Book. PragProg Customers. Title: Name of book: The Cucumber Book, 2nd ed - Chapter 10 Example: Neither working through the example code nor downloading the code a Feed those examples i Book Info. Tag: book-the-cucumber-book-seco Threads: 2. View on pragprog. View Main Thread. Post Review. Take a look and see whether you recognize any of these: Symptom Problem Some of our tests fail randomly.

Flickering scenarios We keep breaking tests unintentionally. Brittle features Our features take too long to run. Flickering Scenarios When a scenario that was passing yesterday is failing today, with the same source code running in the same environment, you have what we call a flickering scenario. The same scenario, run on the same codebase in the same environment, will mostly pass but sometimes fail.

These apparently uncontrollable failures cause the team to lose confidence in their tests, in their code, and in themselves. The worst thing about a flickering scenario is that as soon as you try to repro- duce it so that you can fix it, it refuses to fail. For a suite of automated tests to be useful, the team must have absolute trust in it.

When even just a single test is compromising that trust, it has a corrosive effect on how everyone feels about the whole test suite. To fix a flickering scenario, you have to study the code and try to understand why it might be happening.

This is a scientific process of making a hypothesis about the cause of the failure, creating an experiment to prove or disprove that hypothesis, and then running the experiment to see whether you were right. You might need to go around this loop several times before you crack the problem, and it might take several days to run an experiment, if the flickering scenario fails only intermittently.

If you run out of ideas, consider simply deleting the test altogether rather than have it come back and fail on you at a time of its own choosing. When features are brittle, a necessary change in one part of the test suite or main codebase causes apparently unrelated scenarios to break. On a bad day, this can happen several times before you emerge from the rabbit warren.

Brittle features are self-fulfilling: when developers perceive their tests to be brittle, they tend to be less courageous about refactoring and cleaning up test code and instead try to get in and out as quickly as they can, leaving the tests and production codebase in an increasingly hard-to-maintain state.

For a successful application whose users continue to demand new features, that test run time is only going to get longer. A long test run creeps up on you: first five minutes seems like an eternity to wait, then fifteen minutes seems bad, but you get used to going to grab a coffee while it runs. Before you know it, your features are taking more than an hour or even longer. When Cucumbers Go Bad Once a new scenario is passing, the main reason to keep running it is for feedback: you want that scenario to warn you if you somehow accidentally break the functionality that it checks for.

The value of that feedback dimin- ishes as your test run starts taking longer and longer. If a few developers do this at the same time, the chances of all of their changes integrating suc- cessfully are slim, and a broken build becomes the norm.

Long test runs also mean people are scared to refactor and do other general maintenance on the Cucumber tests themselves. Yet many other teams attest to the transformative effect Cucumber has had, helping development teams to collaborate much more effectively with their business stakeholders. What could be the difference between these two experiences?

The answer lies partly in starting with the right kind of collaborative relation- ship with those business stakeholders. On the other hand, many teams who start out with keen and interested stakeholders waste the opportunity Cucum- ber gives them to build that collaborative relationship. When features are written by testers or developers working alone, they inevitably use technical terms that make the stakeholders feel marginalized when they read them.

This becomes a vicious circle: as stakeholders lose interest, they spend less time helping write the features in a language that makes sense to them. Before you know it, the features have become nothing more than a testing tool. This painful symptom is normally caused by a combination of the following underlying problems: www. The simplest approach to this is to partition your features using tags or folders and then run each of those partitioned sets at the same time.

Many continuous integration tools like Jenkinsa allow you to delegate builds to slave machines so you can ensure that each partitioned set of features gets its own dedicated environment. Another approach is to use a tool like Testbotb or Hydrac to distribute your features automatically across several slave machines. Specification by Example [Adz11] www. When Cucumbers Go Bad Incidental Details Consider the following scenario for an online email client: Scenario: Check inbox Given a User "Dave" with password "password" And a User "Sue" with password "secret" And an email to "Dave" from "Sue" When I sign in as "Dave" with password "password" Then I should see 1 email from "Sue" in my inbox There is a lot of detail in this scenario: we have the username and password of the main actor, Dave, and we also have the username and password of another user, Sue.

For example, Sue has a different password than Dave. We call details like the passwords incidental details,5 which are details that are mentioned in the scenario but that actually have no relevance to the purpose of the scenario.

This kind of irrelevant detail makes the scenario harder to read, which in turn can cause your stakeholders to lose interest in reading them. Bear that in mind when you write scenarios, because you may not even notice these incidental details slipping in.

Try to avoid being guided by existing step definitions when you write your scenarios and just write down exactly what you want to happen, in plain English. In fact, try to avoid programmers or testers writing scenarios on their own. Instead, get nontechnical stakeholders or analysts to write the first draft of each scenario from a purely business-focused perspective or ideally in a pair with a programmer to help them share their mental model. With a well- engineered support layer, you can confidently and quickly write new step definitions to match the way the scenario has been expressed.

Imperative Steps In computer programming, there are two contrasting styles for expressing the instructions you give to a computer to make it do something for you. These styles are called imperative programming and declarative programming. Imperative programming means using a sequence of commands for the com- puter to perform in a particular order. Ruby is an example of an imperative language: you write a program as a series of statements that Ruby runs one at a time, in order.

A declarative program tells the computer what it should do without prescribing precisely how to do it. CSS is an example of a declar- ative language: you tell the computer what you want the various elements on a web page to look like, and you leave it to take care of the rest. Gherkin is, of course, an imperative language. You could also probably just about make the argument that it acts as a guide to what the user interface will look like, since it names the fields and buttons that will be used in the login form.

Worst of all, scenarios that use generic step definitions like this are failing to create their own domain language. The language of this scenario, using words and phrases like fill in and press, is expressed in the domain of user interface widgets, a generic and relatively low-level domain. This same scenario could apply to a thick-client or mobile application. A team that used this scenario would need an incredibly high level of trust in their programmers. Duplication All good computer programmers understand how destructive duplication is to the maintainability of their code.

Duplication obviously makes your scenarios brittle, but it also makes them boring. Gherkin has the Background and Scenario Outline keywords you can use to reduce duplication, as we showed you in Chapter 5, Expressive Scenarios, on page 61, but stay vigilant for where the duplication is a sign that your steps are written at too low a level of abstraction.

Work with nontechnical members of your team to get their feedback about the kind of duplication they can accept and the kinds that make their eyes glaze over.

This is an admirable aim in that if you have to change the behavior of the system, you want to be able to change it in one place and be confident that your change will apply consistently across the codebase. However, when you are using examples to drive your code, there is another principle in play that I believe trumps the DRY principle: the examples should tell a good story. In this case, clarity of intent is found in the quality of the narrative, not necessarily in minimizing duplication.

Some years ago I had my first experience of pair programming with Martin Fowler. That is, I had done quite a bit of pair programming, just not with Martin before.

We were looking at some Ruby code I had written test-first, and Martin asked to see the tests "to find out what the code does. He started moving the tests around. I had a few helper classes and utility methods in the source file, neatly at the end out of the way. He moved them up and dropped them inline just ahead of the first test that used them. I thought—now the supporting code is all over the place!

It really offended my sense of tidiness. But then I saw a pattern beginning to emerge: the test code was starting to read like a story. He would introduce these little methods and classes just before their one walk-on line in the narrative. It was quite an eye-opener for me. The test code flowed and unfolded the story of the class under test. The a-ha! Everything would be in footnotes or appendixes. All the character descrip- tions, plot elements, subtexts, and so on, would be carefully extracted into fully cross-referenced paragraphs.

That is great if you are reading an encyclopedia but not so appropriate if you want to get into the flow and find out what happens. You would be forever flicking back and forth in the book, and you would very quickly forget where you even were in the story. In the words of the old joke, dictionaries have lousy plots, but at least they explain all the words as they go. Ubiquitous What? The point is for everyone on the team to use the same words, everywhere.

Wherever you see schism like this, stop, decide which is the right word to use, make the appro- priate correction, and then stick with it. That development takes work. The rewards are great. Teams that use a ubiquitous language make fewer mistakes and enjoy their work more because they can communicate effectively about the work. Take time to explain the concept of a ubiquitous language to your team and what its benefits are.

Used correctly, Cucumber helps a team to develop their ubiquitous language. Each of those disagreements has exposed a potential misunder- standing between the two groups, in other words, a bug magnet. For a new team, these sessions can be hard at first, but as the language develops, they get easier and easier. Three Amigos, on page 96 is a good way to structure these meetings. Siloed Features Cucumber can feel like a very technical tool.

When testers and developers tuck their features away in source control, the rest of the team www. The tester will typically come up with lots of scenarios, sometimes covering obscure edge cases and sometimes covering very important ones that no one else had thought of.

The programmer will typically add steps to scenarios, as he asks clarifying questions about what exactly should happen. When the programmer explains that implementing a particular scenario will be complicated, the product owner has the authority to help decide on alternatives or to drop it altogether. Many teams practicing BDD have found the three amigos make a great partnership for thrashing out Gherkin scenarios that the whole team believes in.

Your features act as a design tool for specifying new features, but they also act as a great reference document for what the system already does today. For a system of any significant size, no one person will remember exactly what it will do in every situation, so when you get a bug report from a user or are considering adding new functionality to some part of the system, you want this reference right at your side.

For example, if you use GitHub for source control, the pages for your project will have syntax-highlighted features that people can even comment on. Relish7 is a service that was created by members of the Cucumber and RSpec teams to provide an easy way to publish Cucumber features as documentation. You can achieve at least half of the benefit of Cucumber just by having the discipline to sit down with your business stakeholders and write scenarios collaboratively.

Assuming you do want to automate them, however, read on to find out how to do it well. For these feedback loops to be useful, the tests need to be fast and they need to be reliable.

Leaky Scenarios Cucumber scenarios are basically state-transition tests: you put the system into a Given state A, you perform action X When , and Then you check that it has moved into expected state B.

When the state of the system is not reset between tests, we say that they allow state to leak between them. This is a major cause of brittle tests. If that first scenario, the one that happens to leave the system in just the right state for the next one to pick it up, is ever changed, the next scenario will suddenly start to fail.

FactoryGirl is an excellent implementation of the Test Data Builderb pattern. The way your domain model is structured, a PayCheck needs an Employee, and the Employee in turn needs an Address. Each of them also has a few mandatory fields. Otherwise, look for similar tools for your language. Without the state leaked out by the earlier scenario, it will fail.

The opposite of this, independent scenarios, ensures they put the system into a clean state and then add their own data on top of it. This makes them able to stand on their own, rather than being coupled to the data left behind by other tests or shared fixture data. Investing in building up a good reliable library of Test Data Builders, on page 98 makes this much easier to achieve.

When you can see precisely what data is used by a scenario just by reading www. This is the common meaning of the term as used in various xUnit testing toolsa and by the Ruby on Rails framework. There is a long tradition coming from the hardware world, where test fixtures origi- nated of calling the link between the test system and the system under test a fixture.

The FIT testing frameworkb uses this meaning of the term. Some unit testing tools such as NUnit have further confused the issue by referring to the test case class itself as a fixture. So much for a ubiquitous language! Race conditions occur when two or more parts of the system are running in parallel, but success depends on a particular one of them finishing first.

In the case of a Cucumber test, your When step might cause the system to start some work that it runs in the background, such as generating a PDF or updating a search index. If this background task happens to finish before Cucumber runs your Then step, the scenario will pass. If Cucumber wins the race and the Then step executes before the background task is finished, the scenario will fail. A crude solution to this problem is to introduce a fixed-length pause or sleep into the scenario to give the system time to finish processing the background task.

Although this is definitely a useful technique in the very short term to www. When Cucumbers Go Bad diagnose a race condition, you should resist the temptation to leave a sleep in your tests once you understand the cause of the problem. When testers and pro- grammers pair up to automate scenarios, they can craft tests that are built with knowledge of how the system works.

For an example of working with asynchronous code and further detail, see Chapter 9, Dealing with Message Queues and Asynchronous Components, on page Traditionally, the manual testers on the team would have a special environ- ment, often called system test, where a recent build of the system would be deployed.

Now the environment is shared between not only the human members of the team but the test scripts too. Suppose a developer gets a bug report and wants to reproduce it for himself. As part of the steps to reproduce the bug, the developer unwittingly deletes a database record that the automated test relied on, and the automated test fails.

This kind of situation is a classic cause of flickering scenarios. The shared use of a single environment can also contribute to unreliable tests by causing heavy and inconsistent load on in-demand resources like databases. When the shared database is under excessive load, normally reli- able tests will time out and fail.

You need a One-Click System Setup, on page Tester Apartheid Testers are too often unfairly regarded as second-class citizens on a software team. When testers are left alone to build their own Cucumber tests, they may lack the software engineering skill to keep their step definition and support code well organized. Before you know it, the tests are a brittle muddle that people are scared to change.

Combat this problem by encouraging programmers and testers to work togeth- er when writing step definition and support code.

The programmers can show the tester how to keep the code organized and factor out reusable components or libraries that other teams can use. By pairing with testers like this, programmers also develop a better understanding of what it takes to make their code testable. When Cucumber is being used to good effect on a team, a tester should be able to delegate the work of running basic checks to Cucumber. When your team transitions from manual to automated tests, you can often be tempted to just port over a subset of production data so that the automated tests have a functioning system to work with straightaway.

When Cucumbers Go Bad One-Click System Setup To avoid flickering scenarios that result from using shared environments, the team needs a setup script that will create a new instance of the system from scratch, at the click of a button. If the system has a database, the database generated by the script should contain the latest schema, as well as any stored procedures, views, functions, and so on.

It should contain just the very minimum baseline data necessary for the system to be able to function, such as configuration data.

Any more should be left for the indepen- dent scenarios to create for themselves. ActiveRecord turns this kind of chore into a breeze. A set of fixture data, even if it starts out relatively lean, will only tend to grow in size over time. As more and more scenarios come to rely on the data, each needing their own specific little tweaks, the size and complexity of the fixture data grows and grows. When you have a large set of fixture data, it can be slow to set it up between each test.

We consider fixture data to be an antipattern. We much prefer using Test Data Builders, on page 98 like FactoryGirl13 where the relevant data is created within the test itself, rather than being buried away in a big tangled set of fixture data. Use tags to annotate the scenarios that should be run on every check-in, and demote the rest to a nightly build. The scenarios that should be demoted to a nightly build are the ones that rarely, if ever, fail.

Over time, some of those scenarios will stabilize and should be demoted to the nightly build, to be replaced by newer scenarios. Although a nightly build can be a good way to get you out of a hole, usually the right long-term solution is to break up your Big Ball of Mud, on page Lots of Scenarios It might seem like stating the obvious, but having a lot of scenarios is by far the easiest way to give yourself a slow overall feature run.

Having lots of tests has other dis- advantages than just waiting a long time for feedback. Maintenance is also harder on the underlying step definitions and support code. We find that teams that have a single humongous build also tend to have an architecture that could best be described as a big ball of mud. Because all of the behavior in the system is implemented in one place, all the tests have to live in one place, too, and have to all be run together as one big lump. This is a classic ailment of long-lived Ruby on Rails applications, which tend to grow organically without obvious interfaces between their subsystems.

In the meantime, you can keep your features organized using subfolders and tags see Chapter 5, Expressive Scenarios, on page Tagging is especially helpful, because you can use tags to partition your tests.

You can choose to run partitioned sets of tests in parallel or even demote some of them to run in a Nightly Build, on page Teams that enthusiastically embrace Cucumber sometimes forget to write unit tests as well and rely too much on slow integration tests for feedback. Try to think of your Cucumber scenarios as broad brush strokes that communicate the general behavior of the code to the business, but still try to get as good a coverage as you can from fast unit tests.

Help make this happen by having testers and programmers work in pairs when implementing Cucumber scenarios. This pair can make good decisions about whether a piece of behavior necessarily needs to be implemented in a slow end-to-end Cucumber scenario and drive out the behavior using a fast unit test instead. Big Ball of Mud The Big Ball of Mud14 is an ironic name given to the type of software design you see when nobody has really made much effort to actually do any software design.

Writing code for new features? Fixing bugs found in testing? Fixing bugs found in production? Speeding up your features? If the elevators are broken in your office building, you can be sure that someone will be on the phone to the facilities team straightaway. When your tests are slow or brittle, the problem is invisible to everyone but the programmers and testers who rely on them.

There just always seems to be something more important to do. Team members who think in this way about their tests have got it all wrong. The automated tests are the heartbeat of the team that relies on them, and they need meticulous care and attention to keep them healthy. The problem is then given immediate and focused attention by experienced staff, and the line is restarted only once the problem has been resolved.

Once the line has restarted, a team is tasked with performing a root- cause analysis on the problem to understand why it happened so that the source of the problem can be resolved. When Taiichi Ohno16 first introduced this idea, his managers thought he was crazy.

At the time, it was taken for granted within the manufacturing industry that the most important thing you could do was keep your assembly lines running, day and night if necessary. At first, the managers who had implemented the policy saw their produc- tivity drop. Stopping to deal with each problem immediately was slowing them down, and when they compared their output numbers with the managers who had ignored their boss, it looked like the boss had got it wrong.

Gradually, however, those managers who allowed their lines to stop and deal with every problem started to see their lines stopping less frequently. Because each problem was being dealt with using defect prevention, those lines had been investing in continuously improving the quality of the machines and processes that ran the line. That investment started to pay off, and their lines started to get faster and faster. Soon their output was much greater than that of the lines controlled by the managers who had ignored their apparently crazy boss.

Their production lines were still clunking along at the same old rate, suffering the same old problems. Without this wider process, stop the line itself would have very little effect. There are four steps to this process: 1.

Detect the abnormality. Fix or correct the immediate problem. Investigate the root cause and install a countermeasure. This fourth step is crucial because it seizes the opportunity offered by the problem at hand to understand something more fundamental about your process. For example, suppose the build has broken with a failing test. Why not? Well, it turns out that he thinks the tests take too long to run, so he ran just what he thought were the ones covering the change he made and then crossed his fingers and pushed his commit anyway.

So, the underlying cause is that the features are slow. Now that we understand the root cause, we can work to fix it. Some teams keep a log of build failures, recording the root cause each time. When they have sufficient evidence that a particular root cause is worth tackling, they can put some concentrated effort into tackling it properly. Imagine your team as a production line, cranking out valuable features for your users.

To those teams, the www. Those conversations reveal insights about their understanding of the problem, insights that will help you build a much better solution than you would have otherwise. Try This Here are some exercises for you to try for yourself. What is the root cause of each of them? What could you do to change them for the better? What is the purpose of the scenario? What behavior is it trying to test?

Notice how the incidental details are like overgrown weeds, getting in the way of you figuring out what the test is actually trying to do. Now that you understand the essence of the scenario, rewrite it in your own words. You should need much fewer steps, but you might want to consider using more than one scenario. At the end of Section 4. We had a single scenario for the most important behavior of the system: letting someone walk up to the machine and withdraw cash.

When we start to build a new system, we like to work directly with the domain model. Ruby has given us an error that tells us that the next thing we need to do is define the Account class. Yet we know from our implementation that nothing has been deposited anywhere. If we have a variable called amount, we should expect it to already be a number of some kind, not the string captured by the regular expression. In reality, though, the only way that an account would have a balance is if someone deposited funds into it.

In the step, we talk about my account, which implies the existence of a protagonist in the scenario who has a relationship to the account, perhaps a Customer. It might seem odd to put an assertion in a Given step, but it communicates to future readers of this code what state we expect the system to be in once the step has run. This way of working is fundamental to out- side-in development.

We try not to think about how the Account is going to work yet but concentrate on what it should be able to do. Step Definitions: On the Inside 1 scenario 1 failed 3 steps 1 failed, 2 skipped 0m0. Now that our step is passing, we can do that refactoring with confidence. Transforms work on captured arguments. Each transform is responsible for converting a certain captured string and turning it into something more meaningful.

This is really important, because we want our transform to match only captures that are numbers, not just captures that contain a number somewhere in them. When Cucumber matches a step definition, it checks for any transforms that match each argument. This is shown in Figure 6, Transforms: how do they work? That code looks much cleaner and easier to read.

Introducing the transform has brought in a new kind of duplication, though. As well as making it easier to change and reuse this capturing regular expression in the future, this refactoring makes it more obvious to someone reading the step definition that this argument will be transformed.

It also gives us the option to capture other currencies in the future. Argument Argument Transform Transform Using the transform has cleared up the final point from the initial code review. As we went along, we collected a new to-do list item: that we need to implement the Account properly, with unit tests.

So, our next task is to implement the step to simulate a customer withdrawing cash from the ATM. This new class is going to handle our www. If we walked into a bank in real life, that role would be played by a teller.

The teller will need to know which account to take the cash from and how much to take. Run cucumber again, and you should be prompted to create a Teller class.

The answer lies in understanding something fundamental about how Cucumber executes step definitions. Storing State in the World Just before it executes each scenario, Cucumber creates a new object. We call this object the World. The step definitions for the scenario execute in the context of the World, effectively as though they were methods of that object. Just like methods on a regular Ruby class, we can use instance variables to pass state between step definitions.

It works! We hate nils, because they creep around your system, causing weird bugs that are hard to track down. You can do the same in Cucumber. To add custom methods to the World, you define them in a module and then tell Cucumber you want them to be mixed into your World. With this change in place, run cucumber, and everything should be passing. By default, Cucumber creates each World by simply calling Object.

There are explanations of many of these methods scattered throughout the book, but if you want a complete reference of them, the best thing to do is look up the API documentation1 for Cucumber::RbSupport::RbWorld. You can discover all the modules that are mixed into the world by calling puts self from within a step definition.

A list of modules will be printed to the output. Remember that a new world is created for each scenario, so it is destroyed at the end of the scenario. This helps isolate scenarios from one another, because any instance variables set during one scenario will be destroyed along with the world in which they were created when the scenario ends. Designing Our Way to the Finish Line Back in the real world, we were trying to get our final step to pass.

When we run cucumber, we can see that the first two steps are passing, and the final one is pending. Almost there! Which part of the system can we examine for evidence of whether it doled out the readies?

Now we can imagine a new CashSlot method that the Teller can use to tell it to dispense the cash: www. There are two changes we need to make now. Pushing some of the details down into our World module means the step definition code is at a higher level of abstraction. Go and grab a drink—then we can sit down, review the code, and do some refactoring. We need a name for our application too, since another convention is that the entry point to the lib folder is a single file named after your application.

Now replace the code you just took out of steps. Loading the application code is something we want to do right at the start of the test run, before Cucumber even starts looking at the step definitions. Fortunately, Cucumber gives us another special folder where we can do just that. The support directory is for code that supports the step definitions so that the step definitions themselves stay simple and easy to read. Step Definitions: On the Inside that another file will have already been loaded.

There is one exception to that, a special file called env. You use it to prepare the environment for the rest of your support and step definition code to operate. Transforms and World Module We should also tidy away the transform and the world module.

Run cucumber, and everything should still pass. As we add more methods to our World, we would split them into multiple modules, each in their own file; however, this is fine for now. Dry Run and env. A dry run aims to parse your features and www. This is much faster than a real test run if you just want to print off your features or check for undefined steps with the usage formatter. The main difference between a normal run and a dry run of cucumber is that a dry run will not boot your environment, so env.

Get used to using dry-run, especially with the usage formatter, to help refactor your scenarios and step definitions with confidence. What we do have, though, are the beginnings of a domain model and a greater understanding of the problem.

Even in these situ- ations, trying to model your domain in Ruby classes will help your own understanding and also make the test code more maintainable in the long term. They also give names to the useful parts of your regular expressions. You can pass state between steps using instance variables and mix in helper methods defined in Ruby modules. The benefit of this decoupling will come later as the system itself evolves.

Try This There are lots of places you could take this example now that we have it up and running. Delete everything except the feature, the transform, and the step definitions. Then delete the body of each step defini- tion, and change it back to pending. Close the book, run cucumber, and off you go! Try to forget about what we did, and enjoy the process of discovering a domain model for yourself.

Play with the code and try some solutions. Edge Cases We have a single scenario here for the happy path through the process of withdrawing cash. Can you think of some simple variations on the scenario that would cause a different outcome? For example, what would happen if your account had a lower balance? This is the lowest level of your test code, where it connects or couples to your actual application.

If this coupling is well-engineered, your tests will be a pleasure to modify as your project grows. If the coupling is too tight, your tests will be brittle and break any time anything moves. Before we get started with the user interface, we have one item left on our to-do list we need to check off first. Support Code 8. We always try to keep a to-do list handy and write down everything that concerns us as we go. This inconsistency means that something is wrong, but we need to investigate further to know what we need to do about it.

The Teller should take the specified amount of money out of the account and hand it to the CashSlot. So, how did we manage to make the scenario pass without having to do any- thing to the account when we implemented that method? In my experience, bugs are a big source of friction and unhappiness in software teams.

Businesspeople blame them on careless developers, and developers blame them on inadequate requirements from the businesspeople. Run cucumber now to see whether we have it trapped: www. But not for long! In order, with the most important first, they are as follows: 1. Passes all the tests 2. Reveals all the intention 3. Contains no duplication 4. Uses the fewest number of classes or methods www.

How about rule 2? Revealing intention is essentially about how things are named, which matters to us a great deal. Which pair is more appropriate for our Account class?

We spend a bit of time chatting with one of our domain experts, and it becomes clear that credit and debit are the right names for the methods on Account. Go ahead and change that, and run cucumber again. How much does this matter?



0コメント

  • 1000 / 1000