Skip to content
EasyTestData

Testing QuickBooks Online API integrations: 6 practices that catch real bugs

testing qbo api ci

Most QuickBooks Online (QBO) integrations are built against a sandbox with a few hand-made records. They pass the happy path and then meet a customer with years of history. These six practices close that gap. The examples use the open-source easytestdata CLI, but the ideas apply however you produce test data.

1. Test with volume, not a handful of records

Pagination, batching and rate-limit handling only fail at scale. The QBO query API returns at most 1,000 rows per page, so any sync that has never seen more than 1,000 invoices has an untested code path. A 12-month rapid-growth run generates 1,080 invoices and 2,854 transactions in total, which is enough to cross that boundary:

npx easytestdata load --template saas --scenario rapid-growth --seed 42 --start-date 2025-09-01

2. Include the messy receivables and payables

Real books are full of partial payments, credits and refunds, and each one changes an open balance your integration has to get right. The audit-nightmare scenario (messy books: credits, refunds and adjustments) is built for this. For 12 months of the professional services template (seed 42) it produces:

  • 660 invoices: 221 paid in full, 223 partially paid, 216 unpaid
  • 71 credit memos and 4 refund receipts
  • 120 bills with 98 bill payments and 8 vendor credits
  • A top-8 customer concentration of about 44% of revenue

If your app shows balances or aging, compare its numbers with QBO's own A/R Aging report for the same sandbox. Any difference is a bug in one of those edge cases.

3. Make test data deterministic

Randomly generated data makes failures hard to reproduce. With a seed, the same inputs give byte-for-byte identical output:

$ npx easytestdata generate --template saas --scenario rapid-growth --seed 42 \
    --start-date 2025-09-01 --end-date 2026-08-31 --format json --output plan-42.json
$ jq '.invoices[0] | {docNumber, customerName, txnDate, amount}' plan-42.json
{
  "docNumber": "EZTD-INV-0001",
  "customerName": "Nguyen Media",
  "txnDate": "2025-09-13",
  "amount": 10242.14
}

Run it again and you get the same invoice. Change the seed to 43 and the first invoice becomes $14,268.52 for Brooks Builders Inc., dated 2025-09-22. Record the seed in your test so a failure in CI can be reproduced on a laptop.

4. Pin the dates, not just the seed

Without explicit dates, the CLI generates the last 12 full months, which means the output moves every month. For fixtures and assertions, pass --start-date and --end-date as above. Use the rolling default when you want "recent" data, for example in a demo company.

5. Reset to a known state between runs

Leftovers from a previous run cause false passes and confusing failures. Everything EasyTestData creates is tagged EZTD, so you can clear it and keep the fixtures you created by hand: purge removes everything it added and never touches records you made by hand (details). Use a different --tag per dataset if you need to clear them separately.

npx easytestdata purge --mode generated
# or purge and reload in one step
npx easytestdata load --template saas --scenario rapid-growth --seed 42 --start-date 2025-09-01 --clear-first

In CI, run the purge in a step that always executes, even when tests fail, and pass -y because the CLI won't purge without confirmation in a non-interactive shell. The CI/CD guide has a GitHub Actions example.

6. Test more than one kind of business

The mix of transaction types depends on the industry. A restaurant takes most of its revenue through sales receipts; a construction company issues estimates and purchase orders on most jobs and gets paid slowly. With seed 42 and 12 months:

  • --template restaurant --scenario healthy-small: 85% of revenue from cash sales, 14 purchase orders, no estimates
  • --template construction --scenario cash-crisis: 246 estimates, 36 purchase orders, and 149 of 336 invoices still unpaid

Running your suite against two or three templates catches assumptions like "every sale has an invoice" before a customer does.

Try it

You can explore all 8 templates and 8 scenarios in the playground without installing anything, then copy the matching CLI command. EasyTestData is open source under Apache-2.0 on GitHub.