How do I test output containing dynamic values like dates or GUIDs in EK9?

← Testing · Ref: Q810

EK9 expected output files support typed placeholders for values that change between test runs. This lets you black-box test programs that print timestamps, GUIDs, or other dynamic data.

THE PROBLEM

A program that prints the current date produces different output each run:

  stdout.println("Started at: " + $DateTime())

The expected_output.txt cannot contain a fixed date string.

THE SOLUTION: PLACEHOLDERS

Use typed placeholders in expected output files:

  Started at: {{DateTime}}

The test runner matches any valid DateTime value at that position.

AVAILABLE PLACEHOLDERS

  {{String}}         any string value
  {{Integer}}        any integer
  {{Float}}          any float
  {{Boolean}}        true or false
  {{Date}}           any valid date
  {{Time}}           any valid time
  {{DateTime}}       any valid date-time
  {{Duration}}       any duration
  {{Millisecond}}    any millisecond value
  {{Money}}          any money value
  {{Colour}}         any colour value
  {{Dimension}}      any dimension value
  {{GUID}}           any GUID/UUID
  {{FileSystemPath}} any file path

EXAMPLE EXPECTED OUTPUT FILE

  Report generated: {{DateTime}}
  Request ID: {{GUID}}
  Items processed: {{Integer}}
  Success: {{Boolean}}

MIXING FIXED AND DYNAMIC

Placeholders can appear anywhere in a line:

  User alice created at {{DateTime}} with ID {{GUID}}

Fixed text is matched exactly. Placeholders match their typed pattern.

See Q204 for black-box testing. See Q205 for parameterized tests. See Q208 for more placeholder details.

Example

defines module qa.testdeep.output.placeholders

  defines program

    // === PROGRAM WITH DYNAMIC OUTPUT ===
    // The expected_output.txt companion would use placeholders
    // to match non-deterministic values.

    PlaceholderDemo()
      stdout <- Stdout()

      // These values change every run
      now <- DateTime()
      requestId <- GUID()
      itemCount <- 42

      stdout.println("Report generated: " + $now)
      stdout.println("Request ID: " + $requestId)
      stdout.println("Items processed: " + $itemCount)
      stdout.println("Success: true")

Common mistakes

E50060 — GUID has no toString() method — use the $ prefix operator for String conversion. See ek9 -h E50060 for details.

Incorrect:

      stdout.println("Request ID: " + requestId.toString())

Correct:

      stdout.println("Request ID: " + $requestId)
Other ways to ask this
  • What are output placeholders in EK9 tests?
  • How do I handle non-deterministic output in EK9 black-box tests?
  • How do I use {{Date}} and {{GUID}} in expected output files?

Coming from another language?

Java: JUnit requires custom matchers or regex assertions for dynamic values. Python: pytest approx() for floats, custom assertion helpers for dates. Rust: no built-in equivalent, custom comparison functions. Go: testify suite with custom matchers. EK9: built-in typed placeholders in expected_output.txt files — {{DateTime}}, {{GUID}}, {{Integer}} etc.

Keywords: black-box, guid, timestamp, dynamic, non-deterministic, date, output, expected, placeholder, template