Yo-ho-ho. It’s happened. Behat RC1 was released with bunch of new features and stability improvements.
pear channel-discover pear.behat.org pear install behat/gherkin-beta pear install behat/behat-beta
From now on, all Behat related projects will live in own GitHub organization, called Behat. And all projects there will use
Behat as vendor namespace part. So, it’s very easy to remember where to find repository:
BehatGherkin => https://github.com/Behat/Gherkin.
The core of the Behat project always was Gherkin DSL parser. It’s Behat part, which parsed all your *.feature files and sends them to a tester. And now it’s a standalone library rewritten from scratch.
What does it mean for you, Behat users?
Old parser was a mess. Parser & lexer logic lived in one place and it caused lots of problems. Now it’s a clean, beautiful & fast AST parser with line-by-line lexer.
New Gherkin parser support 42 languages out-of-the-box (thanks Cucumber ;-) ), including my favorite:
# language: en-pirate Ahoy matey!: feature title In order to be a good capitan As a John Silver I need to be able to sink enemy ships Yo-ho-ho: Let go and haul something Heave to: attack enemy ship Gangway! prepare harpoo Aye attack!!! Shiver me timbers: outline title Blimey! I drink the <count1> bottles of rom Avast! I eat <count2> chicken legs Dead men tell no tales: | count1 | count2 | | 23 | 122 |
You may check all available keywords for your language with:
behat --usage --lang en-pirate
Behat will print example feature with keywords for specified language.
The old parser was quite silent, which is bad for a parser. So the new one is super verbose with errors. It means, when you’ll try to run this feature with Behat:
Feature: Some feature Given something wrong
Behat will say something like:
BehatGherkinExceptionParserException: Expected Feature token, but got Step on line: 3
Which means, that Behat expects another feature (or scenario) instead of provided “free” step ;-)
Ambiguous language specification:
# language: en # language: ru Feature: Some feature Given something wrong
BehatGherkinExceptionParserException: Ambiguous language specifiers on lines: 1 and 3
Feature: Scenario: Given something with: """ some text
BehatGherkinExceptionParserException: Expected PyStringOperator token, but got EOS on line: 7
Filters & loaders moved to separate Gherkin project to. And now, Gherkin comes with 3 great scenario filters:
- Tags filter. Good old
behat --tag ...
- Name filter. Good old
behat --name ...
- Line filter. New one
behat features/arguments.feature:29, which will cause to run only scenario on line 29 of file
More than 130 tests, that covers almost all parser & lexer edge cases. All 42 bundled tranlslations are fully covered with unit tests.
The Behat now lives under
Behat vendor namespace too. So be careful & change old
throw new EverzetBehatExceptionPending to
New Configuration System
Behat now has new config system, based on DIC extensions. Old
behat.yml file was simply DIC configuration file, which is clunky. New one is much cleaner:
paths: base: features format: name: progress
Before RC1, all your
require_once ... was in
env.php, that evaluates before each scenario, which is not nice at all. Now Behat supports separate bootstrapping script (
bootstrap.php), that evaluates only 1 time before almost any other Behat function:
<?php // features/support/bootstrap.php require_once 'PHPUnit/Autoload.php'; require_once 'PHPUnit/Framework/Assert/Functions.php';
From now on, Behat will NOT fail if your features have pending or skipped tests by default. Behat will fail (return 1 to console) only when you have failed (red) features. It’s default behavior of Cucumber and, now, Behat to. If you still want Behat to fail on any type of status neither passed – use
behat --strict features/
Forgot what steps is available for your features? Run:
behat --steps features/
it will cause Behat to display all available step regex’s:
'/^a file named "([^"]*)" with:$/' '/^I run "behat ([^"]*)"$/' '/^it should (fail|pass) with:$/' '/^it should (fail|pass)$/' '/^the output should contain:$/' '/^the output should not contain:$/' '/^display last command exit code$/' '/^display last command output$/'
Hate this multiline arguments in pretty formatter output? Use
behat --no-multiline features/
which will turn them off in output.
Step Definition Translations
It’s hard to maintain multiple versions of your steps for community… NOT (© Borat). Behat now has feature, called step translations. It means, that you can create folder
features/steps/i18n and place translation xliff’s there:
<!-- features/steps/i18n/ru.xliff ---> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <file original="global" source-language="en" target-language="ru" datatype="plaintext"> <header /> <body> <trans-unit id="i-have-entered"> <source>/^I have entered (d+) into calculator$/</source> <target>/^Я набрал число (d+) на калькуляторе$/</target> </trans-unit> <trans-unit id="i-have-clicked-plus"> <source>/^I have clicked "+"$/</source> <target>/^Я нажал "([^"]*)"$/</target> </trans-unit> <trans-unit id="i-should-see"> <source>/^I should see (d+) on the screen$/</source> <target>/^Я должен увидеть на экране (d+)$/</target> </trans-unit> </body> </file> </xliff>
This translations will be used to match your features. For example, this is russian translation & it will be used in all my features, written in
# language: ru. Also,
--steps keyword accepts additional Behat
--lang option in which you can specify language in which you want to see available steps:
behat --steps --lang=ru
will print all available steps in ru (if has translation).
Formatters were rewritten from scratch with extensibility & clean code in mind. Compare old pretty formatter with new one. It’s much cleaner, readable & extendable. Now it’s possible to extend PrettyFormatter by overriding 1-2 small methods with 3-6 LOC.
Whole code was cleaned and refactored. For example, take a look at:
Every single part of Behat code was reviewed & cleaned to ease it’s future extending/enhancement.
Documentation is work in progress (together with Mink project ;-) ) and will be available very soon & definetly before release. For now, you can use old docs & wikis, cuz it works for RC1 too.
What is RC?
By RC (release candidate) we mean, that Behat & Gherkin API is stable. It woun’t change and all later RC releases will only fix bugs. But Behat code in some places can have bugs, which will be fixed very fast with further release candidates right until 1.0.0 release. For example, while we wrote this article, RC2 was released with small bug-fix. So, you can and MUST use it now to help us with testing ;-)
If you found some bug or you simple have question, you can always ask it on:
- Official google group
- Official IRC channel on Freenode: #behat
- Through GitHub messages
- Or by mail: firstname.lastname@example.org
Also, if you found a bug, it would be super awesome if you create issue in official issue tracker.
More to come…
Stay tuned & we will suprise you many times in the coming month ;-)