Writing Scenarios in your language

Good and effective communication is key to BDD. Therefore, writing scenarios 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 scenarios to be written in any language. All is needed to configure the use of I18nKeyWords for a given Locale. Each locale has a separate keywords properties file. E.g. for Italian locale, the file keywords_it.properties is:

Scenario=Scenario:
GivenScenarios=Dati gli scenari:
ExamplesTable=Esempi:
ExamplesTableRow=Esempio:
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 JUnitScenario, e.g.:

public class ItTraderScenario extends JUnitScenario {

	public ItTraderScenario(final ClassLoader classLoader) {
		super(new PropertyBasedConfiguration() {
			@Override
			public ScenarioDefiner forDefiningScenarios() {
				// use underscored camel case scenario files with extension ".scenario"
				return new ClasspathScenarioDefiner(
						new UnderscoredCamelCaseResolver(".scenario"),
						new PatternScenarioParser(this), classLoader);
			}

			@Override
			public ScenarioReporter forReportingScenarios() {
				// report outcome in Italian (to System.out)
				return new PrintStreamScenarioReporter(keywordsFor(new Locale("it"), classLoader));
			}

			@Override
			public KeyWords keywords() {
				// use Italian for keywords
				return keywordsFor(new Locale("it"), classLoader);
			}

		}, new ItTraderSteps(classLoader));
	}

	protected static KeyWords keywordsFor(Locale locale, ClassLoader classLoader) {
		return new I18nKeyWords(locale, new StringEncoder(), "org/jbehave/examples/trader/i18n/keywords", classLoader);
	}

}

The corresponding i18n-ed Steps, also requires the configuration of i18n-ed keywords:

public class ItTraderSteps extends Steps {

    private Stock stock;

    public ItTraderSteps(ClassLoader classLoader) {
    	// Use Italian for keywords
        super(new StepsConfiguration(keywordsFor(new Locale("it"), classLoader)));
    }

    @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));
    }

	protected static KeyWords keywordsFor(Locale locale, ClassLoader classLoader) {
		return new I18nKeyWords(locale, new StringEncoder(), "org/jbehave/examples/trader/i18n/keywords", classLoader);
	}

}

Note that the i18n-ed keywords not only allow the translation of the keywords used in parsing the textual scenario, but also the keywords used in the reporting of the scenario execution, e.g. Pending, NotPerformed and Failed.

Why are different languages not supported out-of-the-box?

Most non-English languages require characters that are rendered inconsistently using the native encoding of a given operating system. We are working on a consistent solution that is re-usable across multiple platforms.