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.
1. The Code Duplication Problem in QA
Section titled “1. The Code Duplication Problem in QA”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).
2. Declaring a Module
Section titled “2. Declaring a Module”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:
@testcaseFeature: 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.
B. Declaration in main.yml
Section titled “B. Declaration in main.yml”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}"C. Remote Modules (Git Registry)
Section titled “C. Remote Modules (Git Registry)”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/.
3. Invocation and Input Parameters (vars)
Section titled “3. Invocation and Input Parameters (vars)”A. Direct Invocation with vars
Section titled “A. Direct Invocation with vars”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 approvedThe parameters declared in variable={...} replace <user> and <role> in the inherited steps before scenario execution.
B. Invocation by Module Name
Section titled “B. Invocation by Module Name”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 approvedOr 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 approvedC. Selecting a Specific Scenario
Section titled “C. Selecting a Specific Scenario”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.
A. Module Declaration
Section titled “A. Module Declaration”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}"B. Consumption from Root Project
Section titled “B. Consumption from Root Project”The root project or any consuming scenario references the output using the module.<name>.<output> prefix:
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}"5. Initialization (testform init)
Section titled “5. Initialization (testform init)”When running testform init, Testform detects configured modules and installs them:
$ testform initInitializing 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!