stephenjude/api-test-helper
stephenjude/api-test-helper is a Laravel package that streamlines API testing with convenient helpers and expressive assertions for HTTP and JSON responses. It reduces boilerplate around authentication, request building, and response checks, helping you write cleaner, faster, more reliable API test...
This package is a thin, opinionated convenience layer over Laravel's TestResponse assertions: status-code helpers, JSON-shape assertions, and a pretty-printer for failed API responses. It is archived (last release August 2023), so treat it as a frozen utility you pin deliberately rather than a living dependency.
Install as a dev dependency only:
composer require --dev stephenjude/api-test-helper
Read the repository README first — it is the only real documentation and the method list is small enough to scan in a couple of minutes. There is no maintained docs site.
Publish the config if the install does not auto-discover it (check vendor/stephenjude/api-test-helper/config for the tag name), then commit the published file so behaviour is stable across machines and CI.
Pull the provided trait into your base test case so every feature test gets the helpers:
// tests/TestCase.php
use StephenJude\ApiTestHelper\ApiTestHelper; // confirm exact namespace in README
abstract class TestCase extends BaseTestCase
{
use ApiTestHelper;
}
First use case: replace verbose chains on a JSON endpoint with a single semantic assertion.
public function test_users_index()
{
$this->actingAs($this->user)
->getJson('/api/users')
->assertApiSuccess(); // instead of ->assertStatus(200)->assertJsonStructure([...])
}
If that one-liner buys you nothing over stock Laravel, stop here — the rest of the package only pays off once you have many endpoints and want uniform assertions.
Standardise status assertions across the suite. The main value is naming intent rather than HTTP codes. Wrap happy paths, validation failures, auth failures, and 404s so a reader knows what is being asserted without decoding assertStatus(422).
$this->postJson('/api/posts', [])->assertApiValidationError();
$this->getJson('/api/posts/999')->assertApiNotFound();
$this->getJson('/api/me')->assertApiUnauthorized();
Confirm the exact helper names and signatures against the README before adopting them wholesale — the package predates several Laravel additions and naming may not match your expectations.
Pair with Laravel assertions, do not replace them. Use the package for status/error semantics and keep native assertions for payload shape:
$response = $this->postJson('/api/posts', $payload);
$response->assertCreated()
->assertJsonPath('data.title', $payload['title'])
->assertJsonStructure(['data' => ['id', 'title', 'author']]);
Debug-on-failure workflow. When a JSON assertion fails, the raw body is often unreadable. Route failures through the package's response-dumping helper (or a small wrapper of your own) so the full pretty-printed payload appears in the test output:
$response = $this->getJson('/api/orders');
if ($response->status() !== 200) {
$this->dumpApiResponse($response); // whichever debug helper ships with the package
}
$response->assertApiSuccess();
Gate debug output behind an environment flag. Add API_TEST_DEBUG=true to your local .env.testing and check it before dumping, so CI logs stay clean.
Use it as a contract for API resources. For resource-heavy APIs, assert the envelope (data, meta, links) once in a shared helper method on your base TestCase, then reuse it across endpoint tests. This is where the package's brevity compounds.
Integration with auth scaffolding. Combine with Sanctum/Passport actingAs or token headers; the helper assertions are agnostic to how the request is authenticated, so they slot in cleanly after your auth setup.
composer.json and expect to drop it on your next major upgrade. If you only need two or three helpers, copy the trait into tests/Concerns/ instead of depending on an unmaintained package.application/json. Always call the *Json request methods, and ensure your exception handler returns JSON for Accept: application/json in tests.withoutExceptionHandling() interaction. If you disable exception handling, exceptions bubble before any assertion runs and the helpful failure message is lost. Keep it off for API feature tests, or wrap the call carefully.php artisan config:clear after editing the published file — a stale cached config is a common source of "my flag is ignored" confusion.Tests\Concerns\ApiAssertions trait: alias the package methods, add project-specific assertions (assertApiPaginated, assertApiForbiddenForRole), and you keep a single migration point when the package is eventually removed.How can I help you explore Laravel packages today?