Skip to content

Modular Architecture

Testform implements a full-featured modular system with functional parity to Terraform modules, allowing you to package, parameterize, and reuse test workflows across Gherkin and YAML.


Essential test workflows—such as authentication, cart preparation, or initial navigation—are repeatedly copied across dozens of feature files. Copy-pasting these steps manually leads to brittle test suites and violates the DRY (Don’t Repeat Yourself) principle.

With Testform Modules, you can encapsulate complete workflows or specific test scenarios and dynamically compose them with input parameters (vars) and return values (outputs).


A. Module in a Feature File (.case.feature)

Section titled “A. Module in a Feature File (.case.feature)”

Create a reusable module file under modules/auth/login.case.feature:

@testcase
Feature: Authentication Module
@tc-login
Scenario: Login with credentials
Given the user navigates to "<base_url>"
When entering username "<user>" and password "<password>"
Then the session is active with role "<role>"

Steps can use angle brackets <param> or variable syntax ${var.param}, which are dynamically replaced when the module is invoked.

You can centrally register reusable modules with their default variables:

module:
auth_standard:
source: "./modules/auth/login.case.feature"
vars:
base_url: "${var.app_url}"
user: "standard_user"
password: "${var.default_password}"
role: "viewer"
output:
session_id:
value: "${testrun.modules/auth/login.case.feature.@tr-1.issueNumber}"

Testform supports remote Git repositories to share modules across teams or organizations:

module:
auth_shared:
source: "git::https://github.com/my-org/qa-modules.git//auth?ref=v1.2.0"
vars:
base_url: "https://staging.company.com"

During testform init, remote modules are automatically downloaded to .testform/modules/.


Invoke the module while supplying specific input parameters:

@tc-checkout-admin
@module(source="./modules/auth/login.case.feature", variable={user: "admin", role: "superuser"})
Scenario: Checkout executed with administrative credentials
When the user clicks "Confirm Payment"
Then the transaction is approved

The parameters declared in variable={...} replace <user> and <role> in the inherited steps before scenario execution.

If the module is registered in main.yml, you can invoke it directly by name or override variables:

@tc-checkout-standard
@module("auth_standard")
Scenario: Checkout with standard user
When the user clicks "Confirm Payment"
Then the transaction is approved

Or with variable overrides:

@tc-checkout-custom
@module(name="auth_standard", variable={user: "custom_qa_user"})
Scenario: Checkout with custom QA user
When the user clicks "Confirm Payment"
Then the transaction is approved

If a module feature file contains multiple scenarios, select only the one you need using scenario or dot notation:

# Option 1: scenario argument
@module(source="./modules/auth/login.case.feature", scenario="@tc-login", variable={user: "demo"})
# Option 2: Canonical dot notation
@module(source="./modules/auth/login.case.feature.tc-login", variable={user: "demo"})

4. Strict Output Scoping (${module.<name>.<output>})

Section titled “4. Strict Output Scoping (${module.<name>.<output>})”

Isolation Rule: Outputs defined inside a module belong strictly to the module’s namespace and do not pollute the global scope.

Inside modules/auth/output.yml:

output:
session_token:
description: "Session token generated by authentication workflow"
value: "tok_secure_active_session"
user_id:
value: "${testcase.modules/auth/login.case.feature.@tc-login.remoteId}"

The root project or any consuming scenario references the output using the module.<name>.<output> prefix:

main.yml
output:
active_admin_token:
description: "Session token from auth module"
value: "${module.auth.session_token}"

And in Gherkin test steps:

Scenario: Authenticated operation
When executing operation with token "${module.auth.session_token}"

When running testform init, Testform detects configured modules and installs them:

Ventana de terminal
$ testform init
Initializing the backend...
Successfully configured the backend "local"!
Initializing modules...
- Using local module auth_standard from ./modules/auth/login.case.feature
- Downloading git::https://github.com/my-org/qa-modules.git//auth?ref=v1.2.0 for auth_shared...
- Installed auth_shared to .testform/modules/auth_shared
Initializing provider plugins...
- Finding fromeroc9/github versions matching "1.0.0"...
- Installed fromeroc9/github v1.0.0
Testform has been successfully initialized!