SpecFormula AI
ISABackend

Configuration

isa.yml configuration structure and settings

SpecFormula uses the isa.yml configuration file to define the test framework's runtime specifications, including API Spec, Entity Spec, and instruction mappings.

Project Structure

isa.yml is placed at the root of the test resources directory, alongside Spec files and test files:

src/test/resources/
├── isa.yml                              # ISA configuration
├── specs/
│   ├── api/
│   │   └── api-spec.yml                 # API Spec (OpenAPI 3.0)
│   └── data/
│       ├── schema.sql                   # DDL definition
│       └── entity_to_table_mapping.yml  # Entity mapping
└── features/
    └── todo.feature                     # Gherkin test file

Complete Example

config:
  api:
    resource_path: specs/api
    project_path: my-project/src/test/resources/specs/api
    time_format: ISO
  data:
    source:
      - name: default
        resource_path: specs/data
        project_path: my-project/src/test/resources/specs/data
        db_type: postgresql

instructions:
  - name: Time control
    format: ^current time is "(?P<time>.+)"$
    instruction_type: time_control

  - name: Data preparation
    format: ^prepare a (?P<entity>[\w\s]+), with table:$
    instruction_type: entity_setup

  - name: API call
    format: ^\((?:No Actor|UID="(?P<userId>\$[\w.]+)")\) (?P<summary>.+?), call table:$
    instruction_type: api_call

  - name: API call (JSON)
    format: ^\((?:No Actor|UID="(?P<userId>\$[\w.]+)")\) (?P<summary>.+?), call JSON:$
    instruction_type: api_call
    data_format: json

  - name: Response validation
    format: ^(?P<summary>.+?)\((?P<status_code>\d{3})\) response,?\s*with table:$
    instruction_type: response_validate

  - name: Response validation (JSON)
    format: ^(?P<summary>.+?)\((?P<status_code>\d{3})\) response,?\s*with JSON:$
    instruction_type: response_validate
    data_format: json

  - name: Database validation
    format: ^should exist a (?P<entity>[\w\s]+), with table:$
    instruction_type: entity_validate

  - name: Database validation (JSON)
    format: ^should exist a (?P<entity>[\w\s]+), with json:$
    instruction_type: entity_validate
    data_format: json

  - name: Database non-existence validation
    format: ^should not exist a (?P<entity>[\w\s]+), with table:$
    instruction_type: entity_non_existence_validate

  - name: Data preparation (JSON)
    format: ^prepare a (?P<entity>[\w\s]+), with json:$
    instruction_type: entity_setup
    data_format: json

API Configuration

config.api sets the location of the API Spec file:

FieldDescriptionDefault
resource_pathAPI Spec path in classpath (required)—
project_pathAPI Spec path in project, for Lint (required)—
time_formatOutput format for time expressionsISO
  • resource_path: The classpath used at test runtime — the framework reads Spec files from this path
  • project_path: The file path in source code — used by Lint tools to locate files and report error positions

Time Formats

ValueOutput Example
ISO (default)"2025-12-25T14:30:00+08:00"
TIMESTAMP1766735400000 (Unix milliseconds)
EPOCH1766735400 (Unix seconds)
DATE_ONLY"2025-12-25"
TIME_ONLY"14:30:00"

Database Configuration

config.data sets the location of database spec files, supporting multiple data sources:

FieldDescriptionDefault
permissionData source permission isolation modeisolated
reuseWhether to reuse Testcontainer containersfalse
sourceList of data sources—
  • permission: isolated: DataSources are permission-isolated from each other and cannot access each other's tables
  • permission: shared: DataSources share permissions and can access each other's tables
  • reuse: true: Reuse Testcontainer containers to avoid restarting for every test, speeding up execution

Fields for each source item:

FieldDescriptionDefault
nameData source name (required)—
resource_pathDDL and mapping file path in classpath (required)—
project_pathDDL and mapping file path in project, for Lint (required)—
db_typeDatabase type: embedded, postgresql, mysql, mssql. embedded is a framework-chooses-implementation alias (Java→H2, C#→sqlite-style, Python→DuckDB).embedded
schemaDefault schema for the DataSource connection (optional)Database default

Schema Configuration

The schema field is for enterprise multi-schema architectures, specifying the default schema for a DataSource connection:

config:
  data:
    source:
      - name: default
        resource_path: specs/data
        db_type: postgresql
        schema: app_schema       # optional

Database-specific behavior:

db_typeSchema BehaviorDefault Schema
postgresqlSets search_path to "<schema>", publicpublic
mssqlSets connection DEFAULT_SCHEMAdbo
mysql / mariadbIgnored (schema = database, set via connection URL)N/A
embeddedIgnored (embedded test database, no multi-schema routing; Java implementation uses H2)PUBLIC

DDL CREATE TABLE statements may include schema prefixes (e.g., CREATE TABLE dbo.users (...)). The framework extracts and preserves schema prefixes, using fully-qualified names (schema.table) in generated SQL.

Folder Structure

specs/data/
├── schema.sql                    # DDL definition
└── entity_to_table_mapping.yml   # Entity to Table mapping

Entity Mapping

Defines the mapping between business names used in Gherkin and database tables:

entity_to_table_mapping:
  - user: users
  - todo: todos

Usage:

Given prepare a user, with table:
  | name  | email             |
  | Alice | alice@example.com |

Instruction Mapping

instructions defines the mapping between Gherkin Step text and ISA instructions:

FieldDescription
nameInstruction name (for identification and error messages)
formatRegular expression to match Gherkin Steps
instruction_typeCorresponding ISA instruction type
data_formatStep payload format: none, data_table, json, text. If omitted, the default depends on instruction_type.

data_format payload contract

data_format describes whether a Step has a DataTable or DocString payload, and how DocString content is parsed. This is a shared contract between ISA and every language runtime.

data_formatPayloadUsage
noneNo payloadInstructions without DataTable / DocString; custom defaults to none.
data_tableGherkin DataTableTable-based data setup, API call, response validation, and entity validation.
jsonJSON DocStringJSON body, JSON response expectation, or JSON entity payload.
textText DocStringPlain-text payload; if a Step uses a text DocString, set data_format: text explicitly.

Default rules:

  • Built-in ISA instructions default to data_table when data_format is omitted.
  • instruction_type: custom defaults to none when data_format is omitted; the user-defined Step Definition owns the behavior and the ISA runtime does not parse a payload.
  • JSON DocString steps must set data_format: json.
  • Plain-text DocString steps must set data_format: text to avoid being treated as no-payload or JSON.

Example:

instructions:
  - name: Custom log message
    format: ^log message:$
    instruction_type: custom
    data_format: text

  - name: Custom checkpoint
    format: ^mark checkpoint (?P<name>.+)$
    instruction_type: custom
    # data_format omitted; custom defaults to none

Instruction Type Reference

instruction_typeCorresponding Instruction
time_controlTimeControl
entity_setupEntitySetup
api_callApiCall
response_validateResponseValidate
entity_validateEntityValidate
entity_non_existence_validateEntityNonExistenceValidate
customCustom Instructions

Regex to Gherkin Mapping

ISA instruction mapping does not support Cucumber Expressions (e.g. {int}, {string}).

The format field must be a regular expression that matches the full Gherkin Step text, and captures parameters via named capture groups.

  • Python-style named groups: (?P<name>...)
  • Java/JVM-style named groups: (?<name>...)

For example, with api_call:

Gherkin:  (UID="$Alice.id") create todo, call table:
Regex (Python): ^\((?:No Actor|UID="(?P<userId>...)")\) (?P<summary>.+?), call table:$
Regex (Java):   ^\((?:No Actor|UID="(?<userId>...)")\) (?<summary>.+?), call table:$
Captured:          userId = $Alice.id    summary = create todo

Capture Group Reference

instruction_typeRequired Groups
time_controltime
entity_setupentity
api_callsummary, userId (optional)
response_validatesummary, status_code
entity_validateentity
entity_non_existence_validateentity
custom(depends on user-defined Step Definition)

On this page