Run gi from Go¶
Import github.com/gi-runner/gi and call Run with explicit feature paths. The API uses the same runner and native adapters as the CLI. Register adds a Go function to the gi object for later runs; Unregister removes it.
Try it¶
In a new directory, run go mod init example.com/api-tests first. In your Go module, add the dependency with go get github.com/gi-runner/gi. Copy hello.feature from the quick start, keep its mock running, and save this as hello_test.go:
package apitest
import (
"testing"
"time"
"github.com/gi-runner/gi"
)
func TestHello(t *testing.T) {
results, err := gi.Run(t.Context(), []string{"hello.feature"}, gi.Options{
Vars: map[string]any{"baseUrl": "http://127.0.0.1:18081"},
Jobs: 1,
Timeout: 5 * time.Second,
})
if err != nil {
t.Fatal(err)
}
for _, file := range results {
if !file.Passed() {
t.Fatalf("feature failed: %s: %+v", file.Path, file.Scenarios)
}
}
}
Run go test -v. TestHello passes when the mock returns the expected greeting. A network or assertion failure fails the Go test with the scenario results.
Results and options¶
Run returns an error for a parse failure, a failed expansion, cancellation, or a selection that ran no scenarios. Assertion and setup failures are on the results. Check Passed() when the error is nil. ScenarioResult, StepResult, and Exchange are in this package.
Options also accepts Env, Tags, Client, and Output.
Jobsof 0 usesGOMAXPROCS.Timeoutbounds one network or browser operation. The context deadline bounds the run, including JavaScript.Clientsupplies transport or TLS. The caller closes it. Each scenario has its own cookie jar.Outputis synchronized for oneRun. A writer shared by concurrent runs is the caller's to synchronize.Varsholds data values.
Paths are files. Configuration is read from the first path. Packages under internal are not an extension API.
ssl, proxy and connectTimeout require a client using *http.Transport. gi clones the transport settings and reuses connections. For scope and cancellation rules when calling features, see Reuse and configuration.
Register a helper¶
if err := gi.Register("greet", func(args []any) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("greet expects one argument")
}
return fmt.Sprintf("Hello, %v!", args[0]), nil
}); err != nil {
return err
}
defer gi.Unregister("greet")
A later scenario can use * def message = gi.greet('Ada'). Registration is process-wide; each scenario snapshots the registered functions. Built-in names are rejected. Helpers may run concurrently, so synchronize any captured mutable state. This API registers functions, not protocol providers.
Common mistakes¶
| Symptom | Check |
|---|---|
| A failed scenario does not fail your Go test | Check every result's Passed() as well as the returned error. |
| A directory path fails | gi.Run accepts explicit feature files. Directory discovery belongs to the CLI. |
| A registered helper races under parallel runs | Synchronize mutable state captured by the helper. Registration is process-wide. |
| A custom transport rejects TLS configuration | The ssl, proxy and connectTimeout settings require an *http.Transport. |