After over a year in the making, it's time to release Cucumber-Ruby 3.0.0.
This post will talk you through the main changes in this release, and give you a sense of where we're headed with version 4.0 and beyond. The full change log is available here.
When I first started using Cucumber and Ruby I found regular expressions extremely intimidating. Although I've learned you only need a handful of syntax to use them with Cucumber, they've always been something that's made Cucumber less friendly to newcomers. So we wanted to fix that.
With this release you can say goodbye to regular expressions. Read Aslak's blog post for more detail.
Similarly, Cucumber has, for a long time, had an obtuse syntax for using tags to express which scenarios to run. That's now been replaced with a shiny new syntax that actually makes sense to most humans.
For example, this old expression:
--tags ~@slow --tags @smoke,@this-iteration
--tags 'not @slow and (@smoke or @this-iteration)'
You can also use this new syntax in tagged hooks.
Got a giant hairy
cucumber.yml file full of these things? Don't worry. Cucumber will warn you to update them but we won't be removing them until version 4.0.
Retry (and the new flakey status)
Sometimes, despite your best intentions, you have a scenario that you know might not pass every single time you run it.
I believe the best option with these scenarios is to bite the bullet and investigate them until you either understand the root of the problem and fix it, or remove it from your test suite for good.
Cucumber-Ruby now gives you a third way to live with flickering scenarios for a time. Using the new
--retry flag, Cucumber will retry any scenario that fails a given number of times. Scenarios that pass on a subsequent attempt will be given a
Read more in the living documentation for this feature.
Like a victorian dad, previous versions of Cucumber were opinionated and inflexible about what it meant to be strict. As of 3.0.0, you now have more options:
-S, --[no-]strict Fail if there are any strict affected results
(that is undefined, pending or flaky results).
--[no-]strict-undefined Fail if there are any undefined results.
--[no-]strict-pending Fail if there are any pending results.
--[no-]strict-flaky Fail if there are any flaky results.
Enjoy the power.
For people who want to go beyond Cucumber's out-of-the-box features, we've got a fresh API for you to use.
The lifecyle of compiling and running your features is now modelled as a series of events. Events are designed to be read-only, appropriate for writing formatters and other output tools. If you need to be able to influence the result of a scenario, use a hook instead.
Here's how events fire as your features are run:
- As your
step_definitions folder is read, Cucumber fires a StepDefinitionRegistered event.
- Cucumber reads a
feature file, and emits a GherkinSourceRead event.
- As your feature file is compiled into test cases, StepActivated events are fired as each test step is "activated" with its matching step definition block.
- Now it has a set of compiled test cases, Cucumber fires a TestRunStarted event describing what's about to be run.
- For each test case (Gherkin Scenario or Scenario Outline Example), Cucumber fires a TestCaseStarted event before any steps are run.
- Now for each test step (including hooks) it fires a TestStepStarted event
- ...and a TestStepFinished event. This contains the result and duration of that step.
- Once all the steps have run, Cucumber fires a TestCaseFinished event. This contains the overall result of running the test case.
- Finally, once all test cases are done, Cucumber fires at TestRunFinished event.
Cucumber's own formatters have largely been rewritten to use this new API, though some of them do still remain using the old formatter API for now. More on that below.
We've dropped support for Ruby 1.9 and 2.0.
Transforms have been removed in favour of the new ParameterTypes that play nicely with Cucumber Expressions.
And we have plans to start breaking more things...
Vision for 4.0 and beyond
Cucumber's codebase will be ten years old next year. As maintainers, we're still living with some decisions that were made years ago. We want to be more welcoming and inclusive to new contributors, and that means cleaning up the codebase to make it easy to pick up and understand.
In general, this means slimming down the codebase and simplifying it. The old formatter API will be removed in 4.0, so please if you're maintaining plugins that use that old API, re-write them to use the new events API described above. If you need something that isn't there, let us know and we'll fix it.
We'll be catching up with cucumber-js and adding support for the new JSON events output.
What else would you like to see us prioritise? Let us know in the comments!
Full change log