What's the best way to organize feature files?
This question really is about personal preference, but my answer is how I make my directories easier to understand.
With the projects that I've been working on, I've had to think about problems like this quite a bit. I know that later down the line, other people will look through the cucumber directories to add more or do various pieces of bug fixing.
Generally speaking, we have taken this approach (I'll use our CucumberJS structure as an example):
project
| features
| | elements
| | | pages
| | | | home.js
| | | | index.js // grab all of the things in the pages directory
| | | | search.js
| | | index.js // grab everything in elements directory and the index of pages
| | | urls.js
| | | test_customers.js
| | feature_files
| | | home
| | | | homepage_links.feature
| | | | homepage_accessibility.feature
| | | | homepage_check_welsh_translation.feature
| | | search
| | | | search.feature
| | | | search_security.feature
| | step_definitions
| | | common // Won't go into this, but we have a library of reusable steps and functions in here for different projects that we can just port over from git
| | | project
| | | | pages
| | | | | search
| | | | | | search_steps.js
| | | | | | search_security_steps.js
| | | | | home
| | | | | | home_steps.js
| | | | | | home_accessibility_steps.js
| | | | navigation_steps.js
| | | | login_steps.js
| | support
| | | env.js // Timeouts
| | | hooks.js // Setup/Teardown for scenarios
| | | world.js // Setting up the drivers
| reports
| | 2017
| | | 03
| | | | 05
| | | | | report.html
| | | | | report.js
| | | | 06
| | | | | report.html
| | | | | report.js
| | | | 07
| | | | | report.html
| | | | | report.js
| | report.json
| screenshots
| | failed
| | | 2017-03-05
| | | | search_security_xss_204057.png
| | | 2017-03-06
| | | | search_security_xss_100532.png
| | | | search_security_xss_101054.png
| | | | search_security_xss_101615.png
| | search_security
| | | 2017-03-06
| | | | search_security_xss_100528.png
| | | | search_security_xss_101050.png
| | | | search_security_xss_101611.png
| | | | search_security_xss_101841.png
| .gitignore
| README.md
Say you're new to a project, so you want to find out what scenarios have been written. You know it's part of the feature set, so you go down that route, you're looking for the feature file, so you go down that route. You're interested in how the security has been tested for the search feature, so you go into there and locate the file.
It's the same theory throughout the rest of our folder structure. Everything is exactly where you'd expect it to be.
It's a big question and I don't think I have a direct answer, but here are some considerations that have helped us shape our feature files. A lot of this comes down to preference and the specific needs of the project.
Feature files are not the same as user stories.
From this excellent article from Matt Wynne (author of The Cucumber Book):
When Aslak created Cucumber, he renamed the files from .story to .feature. This wasn’t an accident or an idle act of whimsy: it’s because there’s a difference.
User Stories are a planning tool. They exist until they’re implemented, and then they disappear, absorbed into the code.
Cucumber features are a communication tool. They describe how the system behaves today, so that if you need to check how it works, you don’t need to read code or go punching buttons on the live system. Organising your features according to the way they were planned and implemented is a distraction from this purpose.
Writing declarative feature files that are dense with business language might make your scenarios even more discoverable than a perfect directory structure
As you project grows (and more people start contributing), it becomes more and more difficult to just browse directly to a scenario's location. The next best thing? Searching for it. This is easier if you're scenarios are more declarative and less imperative. From this article from SauceLabs:
Tests should largely focus on what needs to be accomplished, not the details of how it is done. They should mostly be understandable when read by non-developers.
The great thing about compact scenarios written at a higher level of abstraction, is that you can fit more of them into a feature file before it starts to feel crowded. For system tests, we've had good luck pairing high-level gherkin with the page object pattern, because it provides a layer for all that detail to live.
Scenarios and features are easier to find if they use the same business language as the UI
If you have an action called "Remove" in the UI, "Delete" in the test, and "Archive" in the production code, it can be difficult for either developers or business people to find the scenarios associated with that action. It may be easier to search for the scenario if the test always follows the UI (assuming the average team member using your BDD tool is more familiar with the UI than the source code).