Halmurat T.
Halmurat T.

Senior SDET

Home Blog Books ask About

The Dispatch

Weekly QA notes from the trenches.

Welcome aboard!

You're on the list. Expect real-world QA insights — no fluff, no spam.

© 2026 Halmurat T.

Automation 24
  • Selenium
  • Playwright
  • Appium
  • Cypress
AI Testing 5
CI/CD 6
  • GitHub Actions
  • Slack Reporting
QA Strategy 4
Case Studies 5
Blog/Automation
AutomationHalmurat T./March 19, 2024/5 min

Managing UI Text in Test Automation

Filed undertest-automation/java/localization
Managing UI Text in Test Automation

Table of Contents
  • Start with one rule
  • Option 1: Properties files for UI copy
  • Option 2: Enums for stable, code-owned text
  • Option 3: Spreadsheets when the business owns the data
  • Complementary tools people forget
  • Accessibility tools help validate meaning
  • Visual regression still matters for rendering
  • A quick decision guide
  • What I default to

On this page

  • Start with one rule
  • Option 1: Properties files for UI copy
  • Option 2: Enums for stable, code-owned text
  • Option 3: Spreadsheets when the business owns the data
  • Complementary tools people forget
  • Accessibility tools help validate meaning
  • Visual regression still matters for rendering
  • A quick decision guide
  • What I default to

Text assertions look simple until the application starts changing quickly. Copy gets revised. Product names shift. Marketing wants different wording by region. Suddenly the same message is duplicated across page objects, step definitions, and test data files, and every release turns into a search-and-replace exercise.

The problem is not “how do I store a string?” The problem is who owns the text, how often it changes, and whether tests can stay readable while it does.

This gets even more important once your team starts leaning on text for selector strategy. If your locators depend on visible copy, you need a sane way to manage that copy across locales and releases. I cover the selector side in why I prefer text-based locators and the XPath edge cases in my breakdown of text() vs dot notation.

Start with one rule

Only externalize text that earns its cost.

If a string is stable, local to one test, and unlikely to change, hardcoding it may be perfectly fine. Externalize text when:

  • the same text is reused across many tests
  • the text differs by locale or environment
  • non-developers own the copy
  • changing the text should not require code edits in ten places

Over-abstracting every string is how frameworks become harder to read than the app they test.

Option 1: Properties files for UI copy

Properties files are my default when the text is user-facing and might vary by language, environment, or brand.

Example:

loginScreen.properties
loginTitle=Welcome to Your App
loginError=Invalid username or password

And a small loader:

public class TextDataManager {
private final Properties textProperties = new Properties();
public TextDataManager(String screenName) throws IOException {
String filePath = "path/to/your/" + screenName + ".properties";
try (FileInputStream fis = new FileInputStream(filePath)) {
textProperties.load(fis);
}
}
public String getText(String key) {
return textProperties.getProperty(key);
}
}

This approach works well when:

  • the same copy appears in multiple tests
  • localization matters
  • content changes are frequent but still structured

The tradeoff is indirection. If every assertion now reads through three layers of helper classes, you’ve made the suite harder to understand. Keep the access path shallow.

Option 2: Enums for stable, code-owned text

Enums are useful when the set of values is small, well-known, and unlikely to change outside engineering control:

public enum AppText {
WELCOME_MESSAGE("Welcome to Our App"),
LOGIN_ERROR("Invalid credentials");
private final String text;
AppText(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

This gives you compile-time safety and a discoverable set of constants. I like enums for:

  • fixed labels in internal tools
  • status text used across API and UI assertions
  • small canonical vocabularies the team owns directly

I do not like enums for copy that changes every sprint. Recompiling code to update marketing text is a bad ownership model.

Option 3: Spreadsheets when the business owns the data

Excel or CSV-backed text is sometimes the right answer, especially when QA analysts, business users, or localization teams update the values. The mistake is using spreadsheets by default just because they’re familiar.

If you go this route, load once and keep the access API simple:

import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
public class ExcelDataManager {
private static final Map<String, String> textDataMap = new HashMap<>();
public static void loadTextData(String excelFilePath) throws Exception {
try (FileInputStream fileInputStream = new FileInputStream(excelFilePath);
Workbook workbook = WorkbookFactory.create(fileInputStream)) {
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
Cell keyCell = row.getCell(0);
Cell valueCell = row.getCell(1);
textDataMap.put(keyCell.getStringCellValue(), valueCell.getStringCellValue());
}
}
}
public static String getText(String key) {
return textDataMap.get(key);
}
}

Use spreadsheets when:

  • non-developers must edit the data directly
  • the dataset is large enough that code-based storage becomes noisy
  • your team already has a controlled process for versioning those files

Avoid them when the values are tiny, static, or tightly coupled to code. Spreadsheets add parsing overhead and make refactors harder to track.

Complementary tools people forget

Text management is not only about where the string lives.

Accessibility tools help validate meaning

If text is critical to the user journey, accessibility checks matter too. A label that visually looks correct but is disconnected from its input is still broken. Tools like Axe catch issues that pure string assertions miss.

Visual regression still matters for rendering

Copy can be present and still be unusable because of truncation, overflow, or layout collapse. That is where visual regression tools earn their keep. I would not use them for every text check, but for critical UI surfaces they catch a different class of failure than string assertions.

A quick decision guide

OptionBest whenMain risk
Properties filesUI copy changes by locale, environment, or featureToo much indirection if overused
EnumsSmall, stable, code-owned textHard to maintain when copy changes often
Excel or CSVBusiness users maintain large datasetsExtra complexity for small use cases

What I default to

My default order is simple:

  1. Hardcode truly local strings
  2. Use properties files for reusable UI copy
  3. Use enums for small stable vocabularies
  4. Use spreadsheets only when ownership demands it

The best text strategy is the one that matches how the text actually changes. If the ownership model and the storage model disagree, your tests will slowly turn into a maintenance project.

§ Further Reading 03 of 03
01Automation

The Browser Errors Your Test Suite Never Catches

Your UI tests pass green while the console throws errors. Learn to catch JavaScript and page errors in Selenium and Playwright Java — before users do.

Read →
02Automation

Tight vs Loose Coupling in Java Test Design

A practical explanation of tight and loose coupling in Java, with examples that show why dependency boundaries matter for maintainability and testing.

Read →
03Automation

From Selenium Wrappers to Playwright Locators

How Playwright's locator API eliminates the need for custom wrapper classes we spent weeks building in Selenium, and when wrappers still make sense today.

Read →

Don't miss a thing

Subscribe to get updates straight to your inbox.

HT

No spam · Unsubscribe anytime

Welcome aboard!

You're on the list. Expect real-world QA insights — no fluff, no spam.

§ Colophon

Halmurat T. — Senior SDET writing about test automation, CI/CD, and QA strategy from 10+ years in the enterprise trenches.

Set in
IBM Plex Sans, Lora, and IBM Plex Mono.
Built with
Astro, MDX, Tailwind CSS & Expressive Code. Served by Vercel.
Privacy
No cookies. No tracking scripts on the main thread — analytics run sandboxed via Partytown.
Source
github.com/Halmurat-Uyghur
Terminal
Try /ask to query Halmurat's notes in a shell prompt.

© 2026 Halmurat T. · Written in plain text, shipped in plain time.

Search
Esc

Search is not available in dev mode.

Run npm run build then npm run preview:local to test search locally.