soft-passio/api-test-cases
Soft Passio API Test Cases is a Laravel package for defining and running API test cases, letting you assert endpoints, responses, status codes, and auth flows so your JSON APIs stay reliable as they grow.
soft-passio/api-test-cases is a small, PHPUnit-oriented helper bundle aimed at reducing boilerplate in functional API tests. It is effectively a thin layer on top of PHPUnit's TestCase (and, given the Bundle suffix, likely on Symfony's KernelBrowser/Client) that gives you a base test class with HTTP helpers and JSON assertions. Before you invest time in it, treat the metadata as a signal: 0 stars, 0 dependents, no release since June 2020 means you are the only user. Read the source first — it is small enough that the whole value proposition can be understood in one sitting.
Minimal steps:
src/). Confirm which PHPUnit version it extends and whether it depends on Symfony's HttpKernel/FrameworkBundle or uses raw Guzzle/curl. That single file determines whether the package is still usable on your stack.setUp(), assertJson* helpers, createMock). If you are on PHPUnit 10/11, expect signature changes and deprecations. Verify against your composer.json constraints before composer require.composer require --dev soft-passio/api-test-cases. If it doesn't, copy the base class into your own test support namespace — for a package this small, forking the one or two useful files is usually cheaper than fighting compatibility.GET /health returns 200 with a JSON body. This reveals immediately whether the HTTP client wiring (base URL, kernel boot, auth headers) actually works on your setup.Where to look first, in order: the base TestCase class → any config/bundle registration file (DependencyInjection/, *.yaml) → the test fixtures/examples shipped in the repo. If there are no examples, assume you are reverse-engineering it.
The realistic day-to-day pattern is to wrap, don't inherit deeply. Extend the package base class once into your own ApiTestCase, then have all suite tests extend that. This isolates you from the abandoned package and gives you a single seam to swap it out later.
// tests/Support/ApiTestCase.php
abstract class ApiTestCase extends \SoftPassio\ApiTestCases\...\BaseTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->setBaseUrl($_ENV['API_BASE_URL'] ?? 'http://localhost:8000');
$this->withHeaders(['Accept' => 'application/json']);
}
}
Patterns that pay off with this style of helper:
@dataProvider to feed method/path/expected-status triples into one generic test. This is where a base-class helper earns its keep — one test covers dozens of routes.setUp, not per test. Log in once, store the token, inject it into the header bag for the suite. Most API helper base classes have a hook for this; if not, set it in your wrapper.assertJsonStructure-like method the package exposes (or your own) to assert keys/types rather than exact payloads — API responses in functional tests drift constantly.setUpBeforeClass, and tear down in tearDownAfterClass.Integration tip: keep the base URL and auth config in phpunit.xml <env> entries or a .env.test, never hard-coded, so the same suite runs against local, CI, and a staging container.
composer require with an exact version, or (better) fork the two or three useful files into tests/Support/ and drop the dependency.config/bundles.php (test env only) or skip Flex entirely. Check KernelTestCase booting.setUp() vs setUpBeforeClass() semantics changed across PHPUnit 8→9→10. If you subclass the package's base, mismatched signatures produce fatal errors, not warnings. If you must use it, pin PHPUnit in require-dev.{"data": ...} responses trip them. Wrap the assertions rather than relying on the base class's assertJson* directly.setUp order. When a test fails oddly, add --debug and check whether headers/tokens carry over; reset them explicitly in your own setUp.tearDown on failure (many helpers expose the last response). With no maintainers, you cannot rely on upstream fixes — capture the raw exchange yourself with a Guzzle middleware or $client->getResponse()->getContent().file_get_contents/curl against a URL, you get more value and support from Symfony's KernelBrowser, Laravel's $this->getJson() / Http::fake(), or plain Guzzle + PHPUnit. Given zero dependents, the pragmatic default is to adopt the patterns (base test case, data providers, JSON assertions) and skip the dependency.How can I help you explore Laravel packages today?