Skip to content

Multi-Language Support ​

Pest BDD supports writing feature files in over 70 languages. This is powered by the Gherkin parser from Behat, which includes translations for all Gherkin keywords.

Specifying Language ​

Add a language directive at the top of your feature file:

gherkin
# language: tr
Özellik: Hesap Makinesi
  Temel aritmetik işlemler

  Senaryo: Toplama
    Diyelim ki 5 sayısına sahibim
    Eğer ki 3 eklersem
    O zaman sonuç 8 olmalı

The # language: xx directive tells the parser which language to use for keywords.

Supported Languages ​

Here are some commonly used languages:

CodeLanguageFeatureScenarioGivenWhenThen
enEnglishFeatureScenarioGivenWhenThen
trTurkishÖzellikSenaryoDiyelim kiEğer kiO zaman
deGermanFunktionalitätSzenarioAngenommenWennDann
frFrenchFonctionnalitéScénarioSoitQuandAlors
esSpanishCaracterísticaEscenarioDadoCuandoEntonces
ptPortugueseFuncionalidadeCenárioDadoQuandoEntão
itItalianFunzionalitàScenarioDatoQuandoAllora
nlDutchFunctionaliteitScenarioGegevenAlsDan
ruRussianФункцияСценарийДопустимКогдаТогда
jaJapaneseフィーチャシナリオ前提もしならば
zh-CNChinese功能场景假如当那么
arArabicخاصيةسيناريوبفرضمتىاذاً

For the complete list, see the Gherkin Languages Reference.

Multi-Language Step Definitions ​

Use repeatable attributes to support the same step in multiple languages:

php
use TestFlowLabs\PestTestAttributes\Given;
use TestFlowLabs\PestTestAttributes\Then;
use TestFlowLabs\PestTestAttributes\When;

class CalculatorSteps
{
    private int $number = 0;

    // English + Turkish
    #[Given('I have number {n}')]
    #[Given('{n} sayısına sahibim')]
    public function haveNumber(int $n): void
    {
        $this->number = $n;
    }

    // English + Turkish
    #[When('I add {n}')]
    #[When('{n} eklersem')]
    public function add(int $n): void
    {
        $this->number += $n;
    }

    // English + Turkish
    #[Then('the result should be {expected}')]
    #[Then('sonuç {expected} olmalı')]
    public function resultShouldBe(int $expected): void
    {
        expect($this->number)->toBe($expected);
    }
}

Now both feature files work:

gherkin
Feature: Calculator
  Scenario: Addition
    Given I have number 5
    When I add 3
    Then the result should be 8
gherkin
# language: tr
Özellik: Hesap Makinesi
  Senaryo: Toplama
    Diyelim ki 5 sayısına sahibim
    Eğer ki 3 eklersem
    O zaman sonuç 8 olmalı

Turkish Example (Complete) ​

Here's a complete Turkish feature file with all Gherkin keywords:

gherkin
# language: tr
@tarım @kredi
Özellik: Çiftçi Kredi Başvurusu
  Bir çiftçi olarak
  Kredi başvurusu yapmak istiyorum
  Böylece tarımsal yatırımlarımı finanse edebilirim

  Geçmiş:
    Diyelim ki sistem aktif durumda

  @smoke @kritik
  Senaryo: Başarılı kredi başvurusu
    Diyelim ki çiftçi "Ahmet Yılmaz" sisteme kayıtlı
    Ve çiftçinin 50 dönüm arazisi var
    Eğer ki çiftçi 100000 TL kredi başvurusu yaparsa
    O zaman başvuru durumu "onaylandı" olmalı
    Ve çiftçiye bildirim gönderilmeli

  Senaryo: Yetersiz arazi ile başvuru
    Diyelim ki çiftçi "Mehmet Demir" sisteme kayıtlı
    Ve çiftçinin 5 dönüm arazisi var
    Eğer ki çiftçi 100000 TL kredi başvurusu yaparsa
    O zaman başvuru durumu "reddedildi" olmalı
    Fakat çiftçiye red sebebi açıklanmalı

  Senaryo Taslağı: Farklı arazi boyutları
    Diyelim ki çiftçinin <arazi> dönüm arazisi var
    Eğer ki çiftçi <miktar> TL kredi başvurusu yaparsa
    O zaman başvuru durumu "<sonuç>" olmalı

    Örnekler:
      | arazi | miktar | sonuç      |
      | 10    | 50000  | onaylandı  |
      | 50    | 100000 | onaylandı  |
      | 5     | 100000 | reddedildi |

Matching step definitions:

php
class KrediSteps
{
    private ?Farmer $farmer = null;
    private ?Application $application = null;

    #[Given('sistem aktif durumda')]
    public function sistemAktif(): void
    {
        Config::set('loan.system_active', true);
    }

    #[Given('çiftçi {name} sisteme kayıtlı')]
    public function ciftciKayitli(string $name): Farmer
    {
        return $this->farmer = Farmer::factory()->create(['name' => $name]);
    }

    #[Given('çiftçinin {area} dönüm arazisi var')]
    public function ciftcininArazisiVar(int $area): void
    {
        $this->farmer->update(['land_area' => $area]);
    }

    #[When('çiftçi {amount} TL kredi başvurusu yaparsa')]
    public function krediBasvurusu(int $amount): Application
    {
        return $this->application = LoanService::apply(
            $this->farmer,
            $amount
        );
    }

    #[Then('başvuru durumu {status} olmalı')]
    public function basvuruDurumuOlmali(string $status): void
    {
        expect($this->application->status)->toBe($status);
    }
}

German Example ​

gherkin
# language: de
Funktionalität: Benutzeranmeldung
  Als Benutzer
  Möchte ich mich anmelden können
  Um auf mein Konto zuzugreifen

  Grundlage:
    Angenommen die Anwendung ist gestartet

  Szenario: Erfolgreiche Anmeldung
    Angenommen ein Benutzer "max@example.de" existiert
    Wenn ich mich mit gültigen Anmeldedaten anmelde
    Dann sollte ich das Dashboard sehen

  Szenario: Ungültige Anmeldedaten
    Angenommen ein Benutzer "max@example.de" existiert
    Wenn ich mich mit falschen Anmeldedaten anmelde
    Dann sollte ich eine Fehlermeldung sehen
php
class AnmeldungSteps
{
    #[Given('die Anwendung ist gestartet')]
    #[Given('the application is started')]
    public function appStarted(): void
    {
        // Setup
    }

    #[Given('ein Benutzer {email} existiert')]
    #[Given('a user {email} exists')]
    public function benutzerExistiert(string $email): User
    {
        return User::factory()->create(['email' => $email]);
    }

    #[When('ich mich mit gültigen Anmeldedaten anmelde')]
    #[When('I login with valid credentials')]
    public function gueltigeAnmeldung(): void
    {
        // Login logic
    }

    #[Then('sollte ich das Dashboard sehen')]
    #[Then('I should see the dashboard')]
    public function dashboardSehen(): void
    {
        expect(true)->toBeTrue(); // Assertion
    }
}

Background in Different Languages ​

The Background keyword has translations in all languages:

LanguageKeyword
EnglishBackground
TurkishGeçmiş
GermanGrundlage
FrenchContexte
SpanishAntecedentes
PortugueseContexto
ItalianContesto

And/But Conjunctions ​

Conjunction keywords are also translated:

LanguageAndBut
EnglishAndBut
TurkishVeFakat
GermanUndAber
FrenchEtMais
SpanishYPero

Example in Turkish:

gherkin
# language: tr
Senaryo: Detaylı test
  Diyelim ki kullanıcı mevcut
  Ve kullanıcı admin
  Eğer ki giriş yaparsam
  O zaman dashboard görmeliyim
  Fakat ayarları görmemeli

Best Practices ​

Choose One Primary Language ​

For consistency, pick one primary language for your project:

gherkin
# All features in Turkish
# language: tr
Özellik: ...

Support Both Languages in Steps ​

When collaborating internationally, support multiple languages:

php
// Support both English and local language
#[Given('a user exists')]
#[Given('bir kullanıcı mevcut')]
public function userExists(): User
{
    return User::factory()->create();
}

Document Language Choice ​

Add to your README or contributing guide:

markdown
## BDD Language

Feature files are written in Turkish (`# language: tr`).
Step definitions support both Turkish and English patterns.

Use UTF-8 Encoding ​

Ensure your feature files are saved with UTF-8 encoding to support non-ASCII characters:

php
// In tests or configuration
mb_internal_encoding('UTF-8');

IDE Support ​

Most IDEs with Gherkin support handle multi-language files:

  • PHPStorm: Full Gherkin support with language detection
  • VS Code: Cucumber/Gherkin extension with language support
  • Sublime Text: Gherkin syntax highlighting packages

Released under the MIT License.