Staying Organized with Tags and Subfolders

It is easy to be organized when you have only a couple of features, but as your test suite starts to grow, you will want to keep things tidy so that the documentation is easy to read and navigate. One simple way to do this is to start using subfolders to categorize your features. This gives you only one axis for organization, though, so you can also use tags to attach a label to any scenario, allowing you to have as many different ways of slicing your features as you like.

Subfolders

This is the easiest way to organize your features. You may find yourself torn as to how to choose a category, though: do you organize by user type, with a features/admins folder, a features/logged_in_users folder, and a features/visitors folder, for example? Or do you organize them by domain entity or something else?

Of course, this is a decision for you and your team to take, but we can offer a little bit of advice. We’ve had most success using subfolders to represent different high-level tasks that a user might try to do. So, if we were building an intranet reporting system, we might organize it like this:

 features/
  reading_reports/
  report_building/
  user_administration/

Don’t get too hung up about getting your folder structure right the first time. Make a decision to try a structure, reorganize all the existing feature files, and then stick to it for a while as you add new features. Put a note in the calendar to take some time out in a couple of weeks and reflect on whether the new structure is working.

If you think about your features as a book that describes what your system does, then the subfolders are like the chapters in that book. So, as you tell the story of your system, what do you want the reader to see when they scan the table of contents?

Running Features in a Subfolder

If you have put some of your features into subfolders, you can still run them using the command cucumber, which will automatically find and run all the .feature files anywhere within the features folder. However, if you want to run just one feature from a subfolder, there’s a little trick to getting it to work. Here’s what you might expect to be able to do:

 $ ​​cucumber​​ ​​features/reading_reports/widgets_report.feature
 # all your steps come up as undefined :(

If you try to run a single feature from a subfolder, you’ll find that all your steps come up as undefined, even though the step definitions are there in features/step_definitions. What’s going on? Unfortunately, Cucumber has become a bit disoriented and no longer knows where to find your step definitions. You need to tell it explicitly to require the step definition code from the root features folder:

 $ ​​cucumber​​ ​​features/reading_reports/widgets_report.feature​​ ​​-r​​ ​​features

You can use a profile (see Chapter 11, The Cucumber Command-Line Interface) to tell Cucumber to do this automatically.

Aslak says:
Aslak says:
Features Are Not User Stories

Long ago, Cucumber started life as a tool called the RSpec Story Runner. In those days, the plain-language tests used a .story extension. When I created Cucumber, I made a deliberate decision to name the files features rather than stories. Why did I do that?

User stories are a great tool for planning. Each story contains a little bit of functionality that you can prioritize, build, test, and release. Once a story has been released, we don’t want it to leave a trace in the code. We use refactoring to clean up the design so that the code absorbs the new behavior specified by the user story, leaving it looking as though that behavior had always been there.

We want the same thing to happen with our Cucumber features. The features should describe how the system behaves today, but they don’t need to document the history of how it was built; that’s what a version control system is for!

We’ve seen teams whose features directory looks like this:

 features/
  story_38971_generate_new_report.feature
  story_38986_run_report.feature
  story_39004_log_in.feature
  ...

We strongly encourage you not to do this. You’ll end up with fragmented features that just don’t work as documentation for your system. One user story might map to one feature, but another user story might cause you to go and add or modify scenarios in several existing features—if the story changes the way users have to authenticate, for example. It’s unlikely that there will always be a one-to-one mapping from each user story to each feature, so don’t try to force it. If you need to keep a story identifier for a scenario, use a tag instead.

Tags

If subfolders are the chapters in your book of features, then tags are the sticky notes you’ve put on pages you want to be able to find easily. You tag a scenario by putting a word prefixed with the @ character on the line before the Scenario keyword, like this:

 @widgets
 Scenario​: Generate report
  Given I am logged in
  And there is a report ​"Best selling widgets"
 ...

You can attach multiple tags to the same scenario, separated with spaces:

 @slow @widgets @nightly
 Scenario​: Generate overnight report
  Given I am logged in
  And there is a report ​"Total widget sales history"
 ...

If you want to tag all the scenarios in a feature at once, just tag the Feature element at the top, and all the scenarios will inherit the tag. You can still tag individual scenarios as well.

 @nightly @slow
 Feature​: Nightly Reports
 
  @widgets
 Scenario​: Generate overnight widgets report
  ...
 
  @doofers
 Scenario​: Generate overnight doofers report
  ...

In the previous example, the scenario called Generate overnight widgets report will have three tags: @nightly, @slow, and @widgets, whereas the scenario called Generate overnight doofers report will have the tags @nightly, @slow, and @doofers. You can also tag Scenario Outline elements and even the individual Examples tables beneath them.

There are three main reasons for tagging scenarios:

  • Documentation: You want to use a tag to attach a label to certain scenarios, for example to label them with an ID from a project management tool.

  • Filtering: Cucumber allows you to use tags as a filter to pick out specific scenarios to run or report on. You can even have Cucumber fail your test run if a certain tag appears too many times.

  • Hooks: Run a block of Ruby code whenever a scenario with a particular tag is about to start or has just finished.

We’ll cover hooks later in Tagged Hooks, and we’ll explain how to filter based on tags in Filtering with Tag Expressions. In case you can’t wait until then, here’s a quick example of how to run Cucumber, selecting just scenarios with a certain tag:

 $ ​​cucumber​​ ​​--tags​​ ​​@javascript

That will select and run only the scenarios tagged with @javascript.

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

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