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:
# 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:
| Code | Language | Feature | Scenario | Given | When | Then |
|---|---|---|---|---|---|---|
en | English | Feature | Scenario | Given | When | Then |
tr | Turkish | Özellik | Senaryo | Diyelim ki | Eğer ki | O zaman |
de | German | Funktionalität | Szenario | Angenommen | Wenn | Dann |
fr | French | Fonctionnalité | Scénario | Soit | Quand | Alors |
es | Spanish | Característica | Escenario | Dado | Cuando | Entonces |
pt | Portuguese | Funcionalidade | Cenário | Dado | Quando | Então |
it | Italian | Funzionalità | Scenario | Dato | Quando | Allora |
nl | Dutch | Functionaliteit | Scenario | Gegeven | Als | Dan |
ru | Russian | Функция | Сценарий | Допустим | Когда | Тогда |
ja | Japanese | フィーチャ | シナリオ | 前提 | もし | ならば |
zh-CN | Chinese | 功能 | 场景 | 假如 | 当 | 那么 |
ar | Arabic | خاصية | سيناريو | بفرض | متى | اذاً |
For the complete list, see the Gherkin Languages Reference.
Multi-Language Step Definitions
Use repeatable attributes to support the same step in multiple languages:
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:
Feature: Calculator
Scenario: Addition
Given I have number 5
When I add 3
Then the result should be 8# 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:
# 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:
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
# 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 sehenclass 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:
| Language | Keyword |
|---|---|
| English | Background |
| Turkish | Geçmiş |
| German | Grundlage |
| French | Contexte |
| Spanish | Antecedentes |
| Portuguese | Contexto |
| Italian | Contesto |
And/But Conjunctions
Conjunction keywords are also translated:
| Language | And | But |
|---|---|---|
| English | And | But |
| Turkish | Ve | Fakat |
| German | Und | Aber |
| French | Et | Mais |
| Spanish | Y | Pero |
Example in Turkish:
# 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örmemeliBest Practices
Choose One Primary Language
For consistency, pick one primary language for your project:
# All features in Turkish
# language: tr
Özellik: ...Support Both Languages in Steps
When collaborating internationally, support multiple languages:
// 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:
## 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:
// 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