How do I organise tests relative to production code in EK9?

← Testing · Ref: Q805

EK9 uses a dev/ directory convention to separate test code from production code. Tests live alongside the code they test, not in a separate tree.

DIRECTORY STRUCTURE

An EK9 project typically has:

  myProject/
    myModule.ek9          <- production code
    dev/
      tests.ek9           <- test code for myModule
      expected_output.txt  <- optional: for black-box tests

THE dev/ DIRECTORY
Files in dev/ are only compiled when running tests (ek9 -t). They are excluded from production builds. This means:
- Test code never ships to production
- Test utilities, helpers, and fixtures stay separate
- No #ifdef or conditional compilation needed

TESTS LIVE WITH THEIR CODE

Unlike Java (src/test separate tree) or Python (tests/ directory), EK9 tests sit next to the code they test. This makes it easy to find tests and keeps related code together.

MULTIPLE TEST FILES

You can have multiple test files in dev/:

  myProject/
    myModule.ek9
    dev/
      unitTests.ek9
      integrationTests.ek9
      expected_output.txt

EXPECTED OUTPUT FILES

For black-box tests, put the expected output file alongside the test:
- Single case: expected_output.txt
- Multiple cases: expected_case_1.txt, expected_case_2.txt

See Q155 for writing tests. See Q204 for black-box tests. See Q205 for parameterized tests.

Example

defines module qa.testdeep.organisation

  defines function

    greet() as pure
      -> name as String
      <- rtn as String: `Hello, ${name}!`

  defines program

    // === PRODUCTION CODE + TEST STRUCTURE ===
    // In a real project:
    //   myApp/
    //     greeting.ek9     <- this production code
    //     dev/
    //       tests.ek9      <- test code (only compiled with -t)

    TestOrganisationDemo()
      stdout <- Stdout()

      // Production function being tested
      message <- greet("EK9")
      stdout.println(message)

      // Test programs would be in dev/tests.ek9:
      //   @Test
      //   GreetingTest()
      //     result <- greet("World")
      //     assert result == "Hello, World!"

      stdout.println("Tests live in dev/ directory")
      stdout.println("Excluded from production builds")
      stdout.println("Compiled only with ek9 -t")

Common mistakes

E50010 — Variables must be declared before use. Stdout must be created before calling println on it. See ek9 -h E50010 for details.

Incorrect:

stdout.println("test output")
      stdout <- Stdout()

Correct:

      stdout <- Stdout()
Other ways to ask this
  • Where do I put test files in an EK9 project?
  • What is the dev/ directory for in EK9?
  • How does EK9 separate test code from production code?

Coming from another language?

Java: src/main/java and src/test/java separate trees, mirrored package structure. Python: tests/ directory or same package with test_ prefix. Rust: #[cfg(test)] mod tests in same file, or tests/ directory. Go: _test.go suffix in same package. EK9: dev/ directory alongside production code, excluded from production builds automatically.

Keywords: structure, dev, separate, test, organise, directory, layout, production, project