Skip to content

Using Optic Capture with Integration Tests

Aidan Cunniffe edited this page Feb 5, 2025 · 1 revision

API Snapshot Testing

Optic allows you to use a suite of integration tests to generate and update OpenAPI. Think snapshot testing - where the OpenAPI spec is the snapshot, and the test is your integration test suit. Optic compares the traffic in your test to the current spec and detects inaccurate schemas and new endpoints. If you pass the --update flag it will fix those inaccurate schemas and document the new endpoint.

Optic makes surgical patches to the spec, it doesn't regenerate the entire YAML document, preserving your manual changes, documentation, and extensions every time.

Generate.and.Update.from.Tests.mp4

Setup

First, we configure Optic to run a test command (ie go test):

capture:
  openapi.yml:
    server:
      command: go up
      url: http://localhost:8080 # the url where it runs
      ready_endpoint: /
      ready_timeout: 10_000
    requests:
      run:
        # The command that will generate traffic to the Optic proxy
        command: go test
        # The name of the environment variable injected into the env of the command that contains the address of the Optic proxy.
        # Optional: default: OPTIC_PROXY
        proxy_variable: OPTIC_PROXY

Then when we can run:

optic capture openapi.yml

The capture command works entirely locally (no traffic leaves machine or is logged).

Here's what it does:

  1. starts your server and waits for it to come online
  2. starts a local proxy server to analyze your test traffic
  3. Runs the test command with the proxy hostname in a OPTIC_PROXY environment variable.
  4. Your tests run and are redirected through the proxy
  5. Optic compares each request / response pair to the specification. Differences are recorded.
  6. Cleans up all the processes and prints out the results.
  7. (if --update flag is passed) patch the OpenAPI file to resolve any differences.

Configuring Captures

Capturing From Remote Server

capture:
  openapi.yml:
    server:
      url: https://dev-123.your-api.com # the url where it runs
    requests:
      run:
        # The command that will generate traffic to the Optic proxy
        command: your-test-command

Capturing From Local Server

capture:
  openapi.yml:
    server:
      command: npm run server
      url: http://localhost:8080 # the url where it runs
      ready_endpoint: /
      ready_timeout: 10_000
    requests:
      run:
        # The command that will generate traffic to the Optic proxy
        command: npm test
        # The name of the environment variable injected into the env of the command that contains the address of the Optic proxy.
        # Optional: default: OPTIC_PROXY
        proxy_variable: OPTIC_PROXY

For more advanced use, here is a feature-complete Capture configuration example:

capture:
  openapi.yml:
    server:
      # The command to run your server.
      # Optional: If omitted, Optic assumes the server is running or started elsewhere.
      command: your-server-command
 
      # The url where your server can be reached once running.
      # Required: Can be overridden with '--server-override'.
      url: http://localhost:8080
 
      # A readiness endpoint for Optic to validate before sending requests.
      # Optional: If omitted, perform no readiness checking.
      ready_endpoint: /
 
      # The interval to check 'ready_endpoint', in ms.
      # Optional: default: 1000
      ready_interval: 1000
 
      # The length of time in ms to wait for a successful ready check to occur.
      # Optional: default: 10_000, 10 seconds
      ready_timeout: 10_000
 
    # One of 'requests.run' or 'requests.send' is required.
    requests:
      # Run an external command to generate traffic.
      run:
        # The command to run to generate traffic (e.g., your test command, etc.).
        command: your-test-command
 
        # The name of the environment variable injected into the env of 'command' that contains the address of the Optic proxy.
        # Optional: default: OPTIC_PROXY
        proxy_variable: OPTIC_PROXY
 
      # Use Optic to generate requests.
      send:
        - path: /users/create # Required
          method: POST # Optional: default: GET
          headers: # Optional
            content-type: application/json;charset=UTF-8 # If omitted, this is the default
          data: # Optional: If omitted on a POST request, default: {}
            name: Hank
 
    config:
      # The number of parallel requests to make when using 'requests.send'.
      # Optional: default: 4
      request_concurrency: 4

Note: if you have multiple OpenAPI files in the same repo, you can have keys for each one's git path in the YAML file ie

capture:
  /backend/serviceA.yml: ...
  /backend/serviceB.yml: ...

capture command

--proxy-port <proxy-port>             specify the port the proxy should be running on
-u, --update [mode]                   update the OpenAPI spec to match the traffic. specify the mode to change the update
                                      behavior on how to handle undocumented endpoints (endpoints not in your spec).
                                      documented will only update documented endpoints. interactive will prompt you for new
                                      endpoint paths. automatic will guess the correct path (choices: "interactive",
                                      "automatic", "documented", preset: "documented")
--postman  <postman-collection-file>  path to postman collection
--har <har-file, directory>           path to har file (v1.2, v1.3), or directory containing har files
--verbose                             display verbose diff output (default: false)
-s, --server-override <url>           Skip executing `capture[].server.command` and forward proxy traffic to this URL instead
--upload                              upload coverage results to Optic Cloud (default: false)
-h, --help                            display help for command