Stories in your language

Effective communication of behaviour is the main objective of BDD. Therefore, writing stories in the language spoken by the business users is essential. Both the patterns used to match the scenario steps to Java methods and the Keywords need to be expressed in the appropriate language.

By default, JBehave uses English as the story language, but supports stories to be written in any language. The LocalizedKeywords provides keywords in any given locale for which a properties bundle is found, by default in i18n/keywords_[locale].properties in the jbehave-core jar.

To write storeis in a given language, we need to specify three elements:

  • a locale, e.g. new Locale("it")
  • a story pattern, as typically the extension of the story resources is language specific, e.g. **/*.storia.
  • one or more steps instances with patterns written in the appropriate language, e.g. new ItTraderSteps()

So, in the case of Italian, we'd have:

The patterns annotating the steps instance methods must be in the same language configured for the story parsing:

public class ItTraderSteps {

    private Stock stock;
    private ExamplesTable table;

    @Given("ho un'azione con simbolo $symbol e una soglia di $threshold")
    public void stock(@Named("symbol") String symbol, @Named("threshold") double threshold) {
        stock = new Stock(symbol, threshold);
    }

}

Note that the keywords for a given locale not only allow the translation of the keywords used in parsing the textual story, but also the keywords used in the reporting of the story execution, e.g. Pending, NotPerformed and Failed.

A working example of story running in different languages can be found in trader-i18n example (see running examples).

Which encoding should I use for textual stories and Java source classes?

Always use encoding UTF-8 for textual stories and Java source classes. The JVM property -Dfile.encoding=UTF-8 should be set in your runtime environment. Your IDE editors should also be configured to use UTF-8 for textual and Java resources.

Which languages are supported out-of-the-box?

JBehave supports a number of languages out-of-the-box, allowing users to simply specify the locale in the LocalizedKeywords. You can verify which language is supported by looking at the i18n/ directory in the jbehave-core-resources.zip. If you'd like your language to be supported, you can contribute the keywords in that language and we'll happily add the language to the list of those supported out-of-the-box, see how to contribute.

Note that Java resource bundles require non-English language characters to be expressed as Unicode escaped characters (of the form \uxxxx where xxxx is 4-digit Hexadecimal number), using ISO-8859-1 encoding. There are a number of tools that enable easy conversion between your non-English language characters and Unicode escaped characters. A useful web-based tool for conversion to Unicode escaped characters is javaescape_tool.

How do I provide my own keywords bundle?

Write a properties bundle containing the following keywords and save it as i18n/keywords_xx.properties. E.g. for Italian i18n/keywords_it.properties:

Meta=Meta:
MetaProperty=@
Narrative=Narrativa:
InOrderTo=Per ottenere
AsA=In qualit\u00E0 di
IWantTo=Voglio
SoThat=Al fine di
Scenario=Scenario:
GivenStories=Date le Storie\:
Lifecycle=Ciclo di vita:
Before=Prima:
After=Dopo:
ExamplesTable=Esempi:
ExamplesTableRow=Esempio:
ExamplesTableHeaderSeparator=|
ExamplesTableValueSeparator=|
ExamplesTableIgnorableSeparator=|--
Given=Dato che
When=Quando
Then=Allora
And=E
Ignorable=!--
Pending=IN SOSPESO
NotPerformed=NON ESEGUITO
Failed=FALLITO
DryRun=ESECUZIONE SIMULATA
StoryCancelled=STORIA SOPPRESSA
Duration=DURATA
Scope=Ambito:
ScopeScenario=SCENARIO
ScopeStory=STORIA
MetaFilter=MetaFilter:
Outcome=Esito:
OutcomeAny=QUALUNQUE
OutcomeSuccess=SUCCESSO
OutcomeFailure=FALLIMENTO
OutcomeDescription=Descrizione
OutcomeValue=Valore
OutcomeMatcher=Matcher
OutcomeVerified=Verificato
Yes=S\u00EC
No=No

Make sure the bundle is in the your classpath and identify it by locale (if using default bundle name):

 Keywords keywords = new LocalizedKeywords(new Locale("it"));

If using a non-standard bundle name, e.g. mykeywords/keys:

 ClassLoader classLoader = ... // the classloader where to find the bundle from
 Keywords keywords = new LocalizedKeywords(new Locale("it"), "mykeywords/keys", classLoader);