
June 19, 2026

TestInspector manages dynamic test data through a double-brace variable interpolation system — {{VAR}} for stored values, {{TIMESTAMP}} and {{ALPHANUMERIC}} for generated values, and {{TOTP:secret}} for time-based one-time passwords. Values resolve at step execution time, not when the test is saved, which means a single test definition runs correctly across environments simply by changing the variable store. Sensitive values, including credentials and TOTP secrets, are stored encrypted and masked in all run logs and exports — they are never visible in plain text to any team member through the interface.
TestInspector resolves variable references at the moment each step executes. Any text-bearing field in a test step — a URL, a form input value, an HTTP request body, a header value, or an assertion's expected value — can contain one or more variable references. Resolution happens left to right within a field, and multiple references in the same string resolve independently.
A URL field like https://api.example.com/users/{{USER_ID}}/orders?env={{ENVIRONMENT}} resolves both references before the HTTP step fires. A POST body like {"email": "qa+{{TIMESTAMP}}@example.com", "role": "{{ROLE}}"} combines a dynamic timestamp with a stored variable in a single JSON payload. The test engine performs a single pass over the field text, substituting each reference it finds in the variable store or computing each dynamic value.
If a variable reference is present in a field but no value is found in the store at any scope level, the step fails with a resolution error rather than sending the literal double-brace text to the server. This fail-fast behavior surfaces missing variable configuration before the test produces misleading results.
The practical benefit is that test logic and test data are decoupled. A login step does not contain a hardcoded email and password — it contains {{USERNAME}} and {{PASSWORD}}. Rotating credentials means updating two variable values rather than searching for and editing every test step that contains them. For context on building maintainable automation strategies, see Astaqc's test automation services and the manual vs automated testing guide.
TestInspector organizes variables across three scopes: organization, suite, and test. Resolution priority flows from narrowest to broadest — test overrides suite, suite overrides organization. When the engine resolves a variable reference, it checks the test-level store first, then the suite-level store, then the organization-level store. The first match wins.
Organization-level variables are accessible to every test and suite in the account. They hold values that are genuinely shared across all work: the base URL for the primary application under test, shared read-only API tokens, environment identifiers. Owners and admins can create and modify organization variables; members can use them in tests but cannot change them.
Suite-level variables override organization defaults for all tests in a specific suite. A suite named "Staging Regression" might define BASE_URL=https://staging.example.com while the organization default is BASE_URL=https://app.example.com. Tests in that suite run against staging automatically; tests in all other suites continue to hit the production URL. No per-test changes are required to swap environments.
Test-level variables have the highest priority and the narrowest scope. They apply only within the test that defines them. Use them for values specific to a single test case — a particular user account ID for a permission test, a fixed order number for a refund workflow edge case — where the value should not leak into other tests in the same suite.
| Scope | Applies To | Priority | Common Contents |
|---|---|---|---|
| Organization | All tests and suites | Lowest (fallback) | Base URLs, shared API tokens, environment names |
| Suite | Tests within the suite | Middle | Environment-specific overrides, suite credentials |
| Test | Single test only | Highest | Case-specific IDs, one-off edge case values |
The hierarchy is deterministic. If BASE_URL is defined at all three levels, the test-level value is used for that test. Remove it from the test and the suite value takes over. Remove the suite value and the organization value applies. There is no ambiguity and no runtime configuration needed to switch which value applies — scope membership determines resolution automatically.
Variable inheritance without override is equally important. A test that does not define BASE_URL at the test level inherits it from the suite, and if the suite also omits it, from the organization. This means an organization with fifty suites and three hundred tests can control the base URL for every test by updating a single organization-level variable. Effective variable management at scale is part of Astaqc's software testing services. The complete software testing guide covers test data management within a broader QA maturity model.
TestInspector provides three built-in dynamic generators that produce values at execution time. These differ from stored variables: they have no persistent value in the variable store and generate a fresh result each time a step that references them executes.
{{TIMESTAMP}} inserts the current Unix timestamp as a decimal integer string at step execution time. Its primary use cases are constructing unique identifiers for entities that must not collide between runs — email addresses (qa+{{TIMESTAMP}}@example.com), usernames, or document titles. Because the value changes on every execution, tests that need to reference the same timestamp in multiple steps should capture the generated value from the first step's response body rather than invoking {{TIMESTAMP}} again in a later step, where it would produce a different number.
{{ALPHANUMERIC}} generates a random alphanumeric string on each invocation. Use it where the requirement is uniqueness rather than a specific format — transaction reference codes, session identifiers, or test resource names. Like {{TIMESTAMP}}, the value is not stored between steps. If the same string is needed in steps two through five of a test after being generated in step one, extract it from step one's response and store it as a run-time variable.
{{TOTP:secret}} generates a time-based one-time password conforming to RFC 6238, using the base32-encoded secret you store in TestInspector. At step execution time, the engine computes the current 6-digit TOTP value using the system clock and the stored secret, then substitutes it into the field. The TOTP secret itself is stored encrypted and is never visible in the UI, in run logs, or in exports. The generated code — not the secret — appears substituted in the executed step, and only within the scope of that run.
The practical effect is that tests requiring MFA login can run fully automated on a schedule or via CI trigger without manual intervention. A test sequence that navigates to a login page, enters username and password, waits for the OTP prompt, and enters {{TOTP:secret}} handles the complete two-factor flow without a human in the loop. The 30-second TOTP window is honored automatically — the value generated when the step executes is valid at that moment. Learn more at TestInspector.
Any variable in TestInspector can be marked as sensitive at creation or update time. Once marked, the value is encrypted before storage and is never returned in plain text through the API or displayed in the interface. The field appears masked in the variable management UI — you can overwrite or delete the value, but you cannot retrieve or display the original string.
This distinction matters in team environments. Multiple team members may have read access to test definitions and variable lists. Non-sensitive variables — base URLs, environment identifiers, timeout values — are visible to all members with access, which is generally appropriate. Sensitive variables — passwords, API secrets, bearer tokens — should be marked sensitive so that access to the test definition does not imply access to the credentials it uses.
Run logs respect the sensitive designation. When a test step substitutes a sensitive variable into a field, the log records the placeholder rather than the resolved value. This applies to live run streaming via WebSocket, stored run history, and exported result reports. Logs can be shared with stakeholders, attached to bug reports, or archived without credential scrubbing as a manual post-processing step.
TOTP secrets follow the same encryption path automatically — they are always stored encrypted regardless of whether the variable is manually marked sensitive. The computed TOTP code (the 6-digit result) is not persisted anywhere in the system after the step executes. It appears in the step's execution detail for that run only, not in any persistent store.
For teams with compliance requirements around credential handling in automated test systems, the combination of encrypted storage and log masking provides a defensible position: credentials are not transmitted or stored in plain text at any point in the test execution pipeline. Astaqc's QA team service includes security-aware test design practices for teams in regulated industries.
TestInspector's HTTP request step supports GET, POST, PUT, PATCH, and DELETE methods. Variable references resolve in all text fields within the step: the URL, any header values, query parameter values, and the request body. This enables API test sequences that chain steps together, where values captured from an earlier response are passed into later requests.
A common pattern for authenticated API testing:
{"client_id": "{{CLIENT_ID}}", "client_secret": "{{CLIENT_SECRET}}"}. A response extraction rule captures the access_token field into a run-time variable TOKEN.Authorization: Bearer {{TOKEN}} references the run-time variable from the previous step. Assertion checks status is 200.Assertions in HTTP steps can also use variable references. An assertion that checks whether response.body.user_email equals {{USERNAME}} avoids hardcoding the expected value into the test definition. If the username variable changes at the suite level, the assertion updates automatically.
| Scenario | Recommended Approach | Reason |
|---|---|---|
| Credentials used in 20+ tests | Organization-level variable (sensitive) | Update once; rotates across all tests |
| Base URL for staging vs. production | Suite-level variable | Environment separation without per-test edits |
| Specific record ID for one edge case | Test-level variable or hardcoded | Scoped; no benefit to variable for single use |
| Unique email per run | {{TIMESTAMP}} or {{ALPHANUMERIC}} | Prevents duplicate-registration failures |
| 2FA / MFA login code | {{TOTP:secret}} | Generated per execution; secret stays encrypted |
| Static URL that never changes | Hardcoded in step | Variable indirection adds management cost |
The guiding principle: use a variable when the value changes across environments, runs, or rotations. Use a hardcoded value when there is no scenario where the value would need to differ. For organizations building scalable automation frameworks, Astaqc's test automation services include implementation support for teams adopting parameterized testing practices.
Yes. Having the same variable name at multiple scope levels is intentional and is the standard pattern for environment switching. The suite-level value overrides the organization-level value for tests in that suite. Tests in other suites that do not define a suite-level override continue to use the organization value. Resolution is deterministic and requires no runtime configuration.
The step fails immediately with a variable resolution error. TestInspector does not substitute empty strings or pass the literal {{VAR_NAME}} text to the application under test. This fail-fast behavior prevents false-negative results where an unresolved reference silently produces incorrect behavior in the application. The run log identifies which variable was unresolved and in which step.
TOTP secrets are stored encrypted and are never included in plain text in any export. If you export a test definition that contains a {{TOTP:secret}} reference, the export includes the variable name reference but not the underlying secret value. Re-importing the test definition into another account requires re-entering the secret in that account's variable store.
TestInspector does not publish a hard limit on the number of organization-level variables. In practice, organization variables should be kept to genuinely shared values — typically fewer than 30 entries. A large number of organization variables often indicates that suite-level or test-level scoping would be more appropriate for many of those entries, reducing the risk of accidental cross-suite interference.
Using these generators in assertion expected values is technically supported but rarely useful, because the generated value in the expected field is independent from any generated value in an earlier request step. The correct pattern is to capture the dynamic value from a response using an extraction rule, store it in a run-time variable, and then reference that variable in the assertion's expected value field.
Create separate suites — one per environment — each with its own suite-level BASE_URL and any other environment-specific overrides. Tests are shared across suites rather than duplicated. Parallel scheduled runs or CI trigger calls for the different suites then resolve to their respective suite-level variable values independently, with no interference between environment runs. See the AI in software testing guide for additional context on modern QA tooling.

Sign up to receive and connect to our newsletter