Organizing the Code

Before we finish this session, let’s be kind to our future selves and tidy up a little. As we worked, we just created everything we needed inline in our features/step_definitions/step.rb file. We’ll move most of that stuff out of there, and put it into a more conventional place. Here’s a list of what we’d like to fix:

  • The application’s domain model classes should go into a lib directory in the root of the project.

  • The KnowsTheDomain module can move into its own file.

  • The transform can also move into its own file.

  • The steps file can be split to organize the step definitions better. This is arguably unnecessary for a project with only three step definitions, but we’ll do it anyway to illustrate how we’d do this on a bigger project.

Separating the Application Code

It’s conventional in Ruby projects to store the system’s code in a lib directory in the root of the project. 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. Our company is trying to stand out from the crowd with the brand name NiceBank, so create a file lib/nice_bank.rb and move the three classes, Account, Teller, and CashSlot, into there.

Now replace the code you just took out of steps.rb with a line to load the files from the lib directory:

 require ​'nice_bank'

Save the files and run cucumber.

This works, but it isn’t perfect. 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.

Booting the Cucumber Environment

When Cucumber first starts a test run, before it loads the step definitions, it loads the files in a directory called features/support. We haven’t needed to use this directory so far in the book, because our examples have been so simple. The support directory is for code that supports the step definitions so that the step definitions themselves stay simple and easy to read.

Just like features/step_definitions, Cucumber will load all the Ruby files it finds in features/support. This is convenient, because it means you don’t need to pepper require statements everywhere, but it does mean that the precise order in which files are loaded is hard to control. In practice, this means you can’t have dependencies between files in the support directory, because you can’t expect that another file will have already been loaded. There is one exception to that, a special file called env.rb

The file features/support/env.rb is always the very first file to be loaded when Cucumber starts a test run. You use it to prepare the environment for the rest of your support and step definition code to operate. Loading our application is pretty fundamental to the test run, so move the require statement into your very first features/support/env.rb file:

 require ​'nice_bank'

Run cucumber, and everything should still pass.

Transforms and World Module

We should also tidy away the transform and the world module. Create a file called features/support/transforms.rb and move the transform out of steps.rb and into there. It’s useful to keep the transforms together like this because when we make changes to them, we can read all the other transforms to make sure everything is consistent. Run cucumber, and everything should still pass.

Now let’s take the KnowsTheDomain module and the call to World and move them into a new file, called features/support/world_extensions.rb. 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.

Organizing Our Step Definitions

We’ve managed to get this far with a single file of step definitions called steps.rb, and for a project of this size, we might well stick with a single file for a while longer. As the number of step definitions starts to grow, we’ll want to split up the files so that the code is more cohesive. We’ve found that our favorite way to organize step definition files is to organize them with one file per domain entity. So, in our example, we’d have three files:

 features/step_definitions/account_steps.rb
 features/step_definitions/teller_steps.rb
 features/step_definitions/cash_slot_steps.rb

For the time being, each of those files will contain only a single step definition, but now we have room to grow.

Dry Run and env.rb

As we start to move files around, it’s useful to test that everything still matches using cucumber --dry-run. A dry run aims to parse your features and step definitions but not actually run any of them. 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.rb will not be loaded. This means you need to be a little bit careful how you lay out your files:

  • Make sure that the other files in support can be loaded with or without env.rb having been loaded.

  • Put all the slow stuff in env.rb so that a dry run can start quickly.

Get used to using dry-run, especially with the usage formatter, to help refactor your scenarios and step definitions with confidence.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.103.96