Good and effective communication is key to BDD. Therefore, writing stories in the language spoken by the business users is essential. And even though the patterns used to match the scenario steps to Java methods can be written in any language, the Keywords still need to be expressed in different languages.
JBehave by default supports English as the scenario language. By supporting the internationalisation (i18n) of keywords by Java Locale, it also allows the stories to be written in any language. All is needed to configure the use of LocalizedKeywords for a given Locale. Each locale has a separate keywords properties file. E.g. for Italian locale, the file keywords_it.properties is:
Narrative=Narrativa: InOrderTo=Per ottenere AsA=Come IWantTo=Voglio Scenario=Scenario: GivenStories=Date le storie: ExamplesTable=Esempi: ExamplesTableRow=Esempio: ExamplesTableSeparator=| Given=Dato che When=Quando Then=Allora And=E Pending=PENDENTE NotPerformed=NON ESEGUITO Failed=FALLITO
We need to configure the use of the i18n-ed keywords in the JUnitStory, e.g.:
public class ItTraderStory extends JUnitStory { public ItTraderStory() { StoryConfiguration storyConfiguration = new MostUsefulStoryConfiguration(); storyConfiguration.useStoryPathResolver(new UnderscoredCamelCaseResolver(".story")); ClassLoader classLoader = this.getClass().getClassLoader(); // use Italian for keywords Keywords keywords = new LocalizedKeywords(new Locale("it"), new StringEncoder(), "org/jbehave/examples/trader/i18n/keywords", classLoader); storyConfiguration.useKeywords(keywords); storyConfiguration.useStoryPatter(new RegexStoryParser(storyConfiguration.keywords()); storyConfiguration.useStoryReporter(new PrintStreamOutput(storyConfiguration.keywords())); useConfiguration(storyConfiguration); StepsConfiguration stepsConfiguration = new MostUsefulStepsConfiguration(); // use Italian for keywords stepsConfiguration.useKeywords(keywords); addSteps(new StepsFactory(stepsConfiguration).createCandidateSteps(new ItTraderSteps())); } }
The corresponding i18n-ed Steps will then understand the language that has been configured via the i18n-ed keywords:
public class ItTraderSteps { private Stock stock; private ExamplesTable table; @Given("ho un'azione con simbolo $symbol e una soglia di $threshold") public void aStock(@Named("symbol") String symbol, @Named("threshold") double threshold) { stock = new Stock(symbol, threshold); } @When("l'azione e' scambiata al prezzo di $price") public void stockIsTraded(@Named("price") double price) { stock.tradeAt(price); } @Then("lo status di allerta e' $status") public void alertStatusIs(@Named("status") String status) { ensureThat(stock.getStatus().name(), equalTo(status)); } @Given("ho una tabella $table") public void aTAble(ExamplesTable table) { this.table = table; } @Then("la tabella ha $rows righe") public void hasRows(int rows){ ensureThat(table.getRowCount(), equalTo(rows)); } }
Note that the i18n-ed keywords 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.