All jobs

Write Unit Tests for a Laravel Project

Yes. An agent runs Pest coverage on a Laravel app, adds tests for the thinnest logic, and opens a pull request with the before and after.

Run this on RushIn a Project that has your repository.

What the agent does

The agent learns the app's PHP and test stack from the repo, not from a generic Laravel tutorial. In laravelio/laravel.io it reads composer.json: PHP 8.4.*, laravel/framework ^11.5, Livewire ^3.3, Filament ^4, and dev tools pestphp/pest ^3.0 with pest-plugin-laravel and pest-plugin-livewire. phpunit.xml defines Unit, Integration and Feature suites, sets APP_ENV=testing, DB_CONNECTION=mysql / DB_DATABASE=testing, and nulls Scout and Telegram. tests/Pest.php is present; unit examples such as tests/Unit/Rules/HttpImageRuleTest.php use Pest's it(...) closures against rules like HttpImageRule.

Jobs under app/Jobs/ are the densest behaviour surface: forty-plus classes such as CreateThread, ReportSpam, BlockUser, LikeReply, with many already covered under tests/Integration/Jobs/. Comparing directories shows gaps such as ApproveArticle, DeclineArticle, DisapproveArticle, SaveNotificationSettings, UpdatePassword, UpdateReply, UpdateThread, VerifyAuthor and UnVerifyAuthor without a matching *Test.php. Models (Article, Thread, Reply, User) and rules under app/Rules/ are the other places coverage often thins out.

It runs the suite with coverage (./vendor/bin/pest --coverage or phpunit with Xdebug/PCOV, whichever the project already documents in CONTRIBUTING) and picks five least-covered files that still hold real branches. New Pest tests go in the matching suite: Integration jobs use the same CreatesUsers / database setup as neighbouring job tests; pure rules stay under tests/Unit. Assertions use Pest expectations and exercise outcomes (database relations, events like SpamWasReported, validation failures), not private property reads.

Production PHP is unchanged unless a test exposes a bug, which is named in the pull request. The description includes coverage before and after. MySQL for testing is provided inside the sandbox (or SQLite only if the project already supports it for tests); the agent does not silently rewrite phpunit.xml to weaken the database. Helpers in tests/CreatesUsers.php and tests/HttpAssertions.php are reused instead of inventing a second user factory path.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Run the test suite with coverage, pick the five least-covered files that hold real logic, and write Pest tests for them that exercise behaviour, not implementation details. Do not change production code unless a test reveals a bug; if it does, say so in the description. Open a pull request with the coverage before and after.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is a pull request on a new branch. In a Laravel.io-shaped app it adds Pest files under tests/Unit or tests/Integration/Jobs (for example covering ReportSpam attaching reporters and dispatching SpamWasReported, or UpdatePassword hashing behaviour). app/Jobs and other production paths stay untouched absent a documented fix.

The description lists the five files, the coverage figures before and after, and the exact Pest command that passed. The trajectory keeps the coverage table and any SQL errors the agent had to work through.

Before merging, a reviewer checks that new tests follow Pest style already in the repo, that they do not call external Algolia or Telegram services (env already nulls those in phpunit.xml), and that factories used match database/factories. Once merged, the existing Tests GitHub Action runs them.

Run it on every job class merged without a test

When a pull request adds a class under app/Jobs/ without a file under tests/Integration/Jobs/, your server sends this request so Pest coverage for that job lands before release.

Listen for run.completed on the API key webhook and paste the pull request into the review thread. Queue starts if you batch several jobs; max_concurrent defaults to 4.

The use case this job follows, with its automation and trigger: Write the missing tests.

Why run it on Rush?

Laravel.io needs PHP 8.4, Composer deps, a testing MySQL, and Pest with Livewire plugins. Reproducing that on every laptop is slow. On Rush the agent builds that environment in a sandbox, runs coverage, writes the missing Pest cases, and opens a pull request that already passes.

The coverage delta is written on the pull request, and the trajectory shows the Pest output. You can apply the same request to several Laravel apps and review each diff on its own.

Frequently asked questions

Pest or PHPUnit classes?

Pest, because that is what composer.json and tests/Pest.php set up. The agent writes it(...) cases consistent with HttpImageRuleTest.php, not new PHPUnit class files, unless a neighbouring folder still uses classes exclusively.

Will it need Algolia or Telegram credentials?

No. phpunit.xml already sets SCOUT_DRIVER=null and null Telegram env vars. Tests should not make outbound calls; if a job would, the agent fakes the facade the way other integration tests do.

Feature tests or unit tests?

Whichever suite matches the file. Jobs go under Integration next to CreateThreadTest.php; pure rules stay under Unit. It does not demote everything to HTTP feature tests.

Does it change Livewire components?

Not for this job. If coverage points at a Livewire component, it adds Pest Livewire tests using the installed plugin, still without rewriting the component unless a bug is found.