Testing Internationalization (i18n) Automatically
AI generated
PASS
expect()
i18n Testing · Store Views
Testing Internationalization (i18n) Automatically
How store views, missing translations, and locale-dependent formats get tested reliably and automatically

A missing translation key or an incorrectly formatted currency amount never shows up in a project's default language, since that's where nearly all development and review activity happens anyway, but it shows up instantly, visible to real customers, in every other, less frequently reviewed language version. Automated i18n tests close exactly this blind spot by systematically, instead of only spot-checking, testing store view switching, translation completeness, and locale-dependent formats.

15 min read i18n Testing Store Views

1. Why i18n bugs often surface late, and to the wrong audience

Usual development and review practice happens almost exclusively in a project's default language, which is why a missing translation key, an incorrectly interpolated placeholder, or a text field sized too tight for longer translations never shows up in that language and consequently never gets noticed by anyone on the team, even though the exact same bug is instantly visible to real customers in a different language version.

This structural asymmetry between the intensely checked default language and the rarely manually reviewed other language versions makes i18n bugs one of the most common causes of poor user experience in international online stores, precisely because they stay practically invisible in everyday development until a customer from the affected country happens to report one.

2. Testing store views and language switching automatically

A basic i18n test iterates over all configured Magento store views, requests the same central page for every store view, say a reference product's detail page, and checks that the page actually gets delivered in the expected language with the correct, store-view-specific base URL, instead of accidentally falling back to the default language's content.

An additional, practically relevant test case checks the fallback behavior for content that was deliberately or accidentally left without an individual translation in a given store view, say a CMS block without a store-view-specific translation, where a correctly configured system should fall back to the default language's content instead of displaying the block completely empty or with a visible error.


import { test, expect } from '@playwright/test';

const storeViews = [
  { code: 'de_de', expectedLang: 'de', expectedText: 'In den Warenkorb' },
  { code: 'en_us', expectedLang: 'en', expectedText: 'Add to Cart' },
  { code: 'fr_fr', expectedLang: 'fr', expectedText: 'Ajouter au panier' },
];

for (const view of storeViews) {
  test(`product page in store view ${view.code} shows the correct language`, async ({ page }) => {
    await page.goto(`/${view.code}/catalog/product/view/id/123`);
    await expect(page.locator('html')).toHaveAttribute('lang', view.expectedLang);
    await expect(page.locator('[data-testid="add-to-cart"]')).toHaveText(view.expectedText);
  });
}

3. Automatically detecting missing translations

An especially effective, but rarely used, testing technique doesn't check individual, concrete pieces of text, it systematically searches the entire rendered page content for unresolved translation keys, which typically remain recognizable by a detectable pattern like square brackets or a dot-notation format whenever a translation system outputs a missing key verbatim instead of the actually expected, translated string.

This generic scan can be applied to every page of an automated crawl run, instead of writing a separate, explicit assertion for every single piece of text, and thereby systematically uncovers translation gaps that a purely manual, spot-checking review would simply miss, since nobody actually clicks through every single page in every language.


test('category page contains no unresolved translation keys', async ({ page }) => {
  await page.goto('/fr_fr/catalog/category/view/id/5');
  const bodyText = await page.locator('body').innerText();

  const unresolvedKeyPattern = /\[\[.+?\]\]|\btranslate\.[a-z_]+\b/;
  expect(bodyText).not.toMatch(unresolvedKeyPattern);
});

4. Checking locale-dependent currency formats

Currency formatting differs between locales not just in the symbol used, but also in the symbol's position, thousands separator, and decimal separator, meaning the exact same price needs to be displayed completely differently across language versions, say as 1.234,56 EUR in the German and as EUR 1,234.56 in the American representation, even though the underlying numeric value stays identical.

A deliberate test renders a deliberately chosen, unambiguous test price for several locales and compares the displayed string exactly against the formatting expected for that locale, reliably surfacing both a misconfigured locale format and a regression introduced by a later change to the price formatting logic.

In Magento stores with multiple currencies per store view, say an additionally selectable US dollar view within a European store, the test should additionally check that switching currency works correctly independent of the currently set language, since language and currency overlap in configuration but are technically independent of each other and can accordingly also misbehave independently of each other.

5. Testing locale-dependent date formats

Similar to currency formats, date display differs considerably between locales, say day-month-year in the European and month-day-year in the American format, where a swapped format on ambiguous date values like the third of January can lead to a complete misinterpretation of the date, causing genuine confusion for customers, especially with delivery date or order date displays.

A test sensibly fixes a concrete, unambiguous test date for this, say December the twenty-fifth, renders it in every relevant locale, and checks the resulting string exactly, instead of relying on an ambiguous date where a swapped format could coincidentally still produce a plausible-looking result and leave the bug unnoticed.

6. Automated screenshot comparisons per language

Longer translations, say in German or Finnish, frequently break a layout originally designed for the shorter English default language, a problem hardly detectable reliably through text alone, but made visible by a visual regression test (see the separate article on this topic) per language version, once a button label suddenly wraps or a navigation element unexpectedly changes its line height.

A sensible, resource-conscious compromise limits visual checks per language to a few, genuinely critical page types, say the header, product detail page, and checkout, instead of visually comparing every single page in every language, which keeps the maintenance burden of the screenshot baselines within a reasonable range.

7. CI strategy: a language matrix instead of individual tests

Instead of writing separate, language-specific test cases for every individual feature, an efficient CI strategy defines a central language matrix, through which the most important, shared test cases automatically get re-run for every configured language, letting new languages slot into the existing test structure with minimal extra effort.

To keep CI runtime within a reasonable range despite running the same tests multiple times, it pays off to actually repeat only a small, carefully selected core set of tests for every language, while the bulk of functional tests keeps running only in the default language, and the remaining languages get used exclusively for the i18n-specific checks described in this article.

8. Automatically testing pluralization rules across languages

While English and German only distinguish between singular and plural, languages like Polish or Russian require different grammatical forms depending on the exact count, say a distinct form for the number one, another for small numbers like two through four, and a third, general form for every other number, making correct pluralization considerably more complex than a simple if-then for singular and plural.

A deliberate test therefore checks not just a single example value but a deliberately chosen series of boundary values like zero, one, two, five, and twenty-one items in the cart, to make sure the pluralization function actually selects the grammatically correct form for every one of these numbers in every supported language, instead of only covering the simplest, most common case of exactly one item.

9. i18n test approaches at a glance

The table below summarizes the test approaches presented for internationalization.

Test approach Covers Limit
Store view iteration Basic language switching and URL structure No substantive completeness check
Unresolved key scan Missing translations, systematically Doesn't find wrong but translated content
Locale format test Currency and date correctly formatted Requires deliberately chosen test values
Visual regression per language Layout breakage from longer text Only sensible for a few critical pages

Mironsoft

E2E test strategy, CI integration, and stable test suites

Test suites that actually find bugs instead of just blinking red?

We review existing E2E test suites for flakiness, missing test isolation, and inefficient CI runtimes, then build a test strategy that genuinely creates confidence instead of just checking a box.

Test Audit

Systematically uncovering flaky tests, testing pyramid gaps, and coverage blind spots.

CI Optimization

Building parallel execution, retry strategies, and fast feedback loops.

Cypress/Playwright Setup

Setting up robust E2E suites for Magento frontends from the ground up.

10. Summary

i18n Testing: The Essentials at a Glance

Core idea

i18n bugs stay invisible in the default language and only surface for real customers in other languages.

Strength

A systematic scan for unresolved translation keys uncovers gaps that manual review misses.

Pitfall

Ambiguous test data for date formats can coincidentally mask a swapped format.

CI strategy

A central language matrix with a small, repeated core test set keeps runtime reasonable.

11. FAQ: i18n Testing: The Essentials at a Glance

1Why do i18n bugs often surface late?
Because development and review happen almost exclusively in the default language, where the bug isn't visible at all.
2How do I automatically detect missing translations?
Through a generic scan of the rendered page content for unresolved translation key patterns.
3Why doesn't an arbitrary test date suffice for date format tests?
Because an ambiguous date like the third of January can coincidentally make a swapped format look plausible.
4How do I test currency formats across locales?
By rendering a fixed test price per locale and comparing it exactly against the expected formatting.
5Should I visually compare every page in every language?
No, that's too costly, limiting it to a few critical page types is the better compromise.
6How do I keep CI runtime manageable with many languages?
Through a small, carefully selected core set of tests that actually gets repeated for every language.
7What is a language matrix?
A central configuration through which the same core tests automatically get re-run for every configured language.
8Does a translation key scan also detect wrong translations?
No, it only finds missing, unresolved keys, not substantively wrong but present translations.
9How do I concretely test Magento store views?
By iterating over every configured store view code and checking language, URL, and central pieces of text.
10Why do longer translations sometimes break the layout?
Because layouts are often designed for the shorter English default language, and longer text wraps or overflows.