· EasyTestData Team

Automating QBO Sandbox Test Environments in CI/CD

ci/cd automation cli api devops

The challenge

QBO integration testing in CI/CD pipelines has a bootstrapping problem: your tests need a populated sandbox, but populating it manually defeats the purpose of automation.

You need a way to:

  1. Programmatically create realistic test data
  2. Load it into a QBO sandbox
  3. Run your integration tests
  4. Clean up the sandbox for the next run
  5. Do all of this deterministically so failures are reproducible

Using the CLI

Install EasyTestData globally:

npm install -g easytestdata

Then use it in your pipeline:

# Load test data with a fixed seed
easytestdata load \
  --template professional-services \
  --preset healthy-small \
  --seed 42 \
  --customers 50 \
  --revenue 500000

# Run your tests
npm test

# Clean up
easytestdata purge --mode generated

The --seed 42 flag ensures the same data is generated every run. Your test assertions can reference specific entity names, amounts, and dates.

Using the REST API

For more control, use the REST API with an API key:

# Create a load job
curl -s -X POST https://easytestdata.com/api/v1/jobs \
  -H "Authorization: Bearer qbs_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "load",
    "scenarioId": "sc_your_scenario",
    "connectionId": "conn_your_connection"
  }'

The API returns a job ID you can poll for completion, or subscribe to WebSocket updates for real-time progress.

Deterministic seeds

Deterministic seeds are the key to reproducible CI/CD testing. With the same seed, template, and parameters:

  • The same customers are generated with the same names
  • The same invoices are created with the same amounts
  • The same payment patterns are applied

This means you can write specific test assertions:

// This customer will always exist with seed 42 + SaaS template
const customer = await qbo.findCustomer("Meridian Analytics");
expect(customer).toBeDefined();
expect(customer.Balance).toBeGreaterThan(0);

The load-test-purge cycle

The recommended pipeline pattern:

  1. Load: Generate and load data with a fixed seed
  2. Test: Run your integration tests against the populated sandbox
  3. Purge: Remove generated entities (tagged with EZTD prefix)

Purging only removes entities created by EasyTestData. Any manually created test fixtures or reference data stays intact.

Pipeline configuration

Here is an example GitHub Actions workflow:

- name: Populate QBO sandbox
  run: easytestdata load --template saas --preset rapid-growth --seed 42
  env:
    EASYTESTDATA_API_KEY: ${{ secrets.ETD_API_KEY }}

- name: Run integration tests
  run: npm run test:integration

- name: Cleanup sandbox
  if: always()
  run: easytestdata purge --mode generated
  env:
    EASYTESTDATA_API_KEY: ${{ secrets.ETD_API_KEY }}

The if: always() on the cleanup step ensures the sandbox is reset even if tests fail.

Getting started

Create a free account at easytestdata.com, connect a QBO sandbox, and generate an API key from your dashboard. The free tier includes 5 jobs per month.