orchestral / testbench-core

Testing Helper for Laravel Development
https://github.com/orchestral/testbench
MIT License
259 stars 41 forks source link

Unable to resolve migration path when using `#[WithMigration('jobs')]` #248

Open duncanmcclean opened 2 hours ago

duncanmcclean commented 2 hours ago

Description:

In my package, I'm using Laravel's job batches feature to keep track of jobs relating to a specific import.

Since the job batches feature requires its own database table, I've uncommented the in-memory SQLite database in my phpunit.xml file and added the DatabaseMigrations trait to the test which calls the Bus::batch() code.

However, since Testbench doesn't ship with the queue migrations out-of-the-box, I reviewed the docs and tried to use the WithMigration attribute to load them, like this:

use Orchestra\Testbench\Attributes\WithMigration; 

#[WithMigration('jobs')]
class TestCase extends \Orchestra\Testbench\TestCase
{
    //
}

As a side note: the docs suggest both jobs and job as values for the attribute. I tried both of them.

However, that gives me this error:

InvalidArgumentException: Unable to resolve migration path for type [jobs]

/path/to/my/package/vendor/orchestra/testbench-core/src/functions.php:263
/path/to/my/package/vendor/orchestra/testbench-core/src/Attributes/WithMigration.php:41
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/Arr.php:605
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/Collection.php:791
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/Collection.php:1714
/path/to/my/package/vendor/orchestra/testbench-core/src/Attributes/WithMigration.php:41
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/HandlesAttributes.php:34
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/Arr.php:605
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/Collection.php:791
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/HandlesAttributes.php:32
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/HandlesDatabases.php:46
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/helpers.php:236
/path/to/my/package/vendor/orchestra/testbench-core/src/Features/TestingFeature.php:49
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/HandlesDatabases.php:44
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/Testing.php:118
/path/to/my/package/vendor/orchestra/testbench-core/src/TestCase.php:70
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/Testing.php:44
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/ApplicationTestingHooks.php:89
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/Testing.php:43
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/helpers.php:236
/path/to/my/package/vendor/orchestra/testbench-core/src/functions.php:118
/path/to/my/package/vendor/laravel/framework/src/Illuminate/Collections/helpers.php:236
/path/to/my/package/vendor/orchestra/testbench-core/src/Concerns/Testing.php:57
/path/to/my/package/vendor/orchestra/testbench-core/src/TestCase.php:49
/path/to/my/package/vendor/statamic/cms/src/Testing/AddonTestCase.php:21
/path/to/my/package/tests/WordPress/GutenbergTest.php:25

I did some digging and it's trying to load/publish the migrations from this directory: "/path/to/my/package/vendor/orchestra/testbench-core/laravel/migrations/jobs

However, that directory doesn't exist. Directories only exist for notifications and queue (but queue is essentially empty).

I assume it should be loading/publishing the 0001_01_01_000002_testbench_create_jobs_table migration in the parent directory?

I'm happy to contribute a fix, if it'd be helpful.

Steps To Reproduce:

  1. Create a package and test suite using Testbench
  2. Add the WithMigration attribute to your TestCase class, like so:
use Orchestra\Testbench\Attributes\WithMigration; 

#[WithMigration('jobs')]
class TestCase extends \Orchestra\Testbench\TestCase
{
    //
}
  1. Add the DatabaseMigrations trait to one of your tests, like so:
use Illuminate\Foundation\Testing\DatabaseMigrations;
use PHPUnit\Framework\Attributes\Test;

class ImporterTest extends TestCase
{
    use DatabaseMigrations;

    #[Test]
    public function it_can_do_something()
    {
        $this->assertTrue();
    }
}
duncanmcclean commented 2 hours ago

As a workaround for the time being, I've added this to my TestCase (I know the command name changed in Laravel 11, but I'm still supporting Laravel 10 in my package):

protected function defineDatabaseMigrations()
{
+    artisan($this, 'queue:batches-table');

    artisan($this, 'migrate', ['--database' => 'testing']);

    $this->beforeApplicationDestroyed(
        fn () => artisan($this, 'migrate:rollback', ['--database' => 'testing'])
    );
}
duncanmcclean commented 2 hours ago

Could this be something to do with the fact the jobs migration now ships with new Laravel 11 apps, where it didn't previously? 🤔

crynobone commented 2 hours ago

Sorry, the name should have been queue and not job: https://github.com/orchestral/testbench-core/tree/7.x/laravel/migrations

crynobone commented 2 hours ago

Just updated the doc as well: https://github.com/orchestral/toolkit-docs/commit/7836c8a753deb50d1b74b7f0ba6157e328374a9f

thanks for the report

duncanmcclean commented 2 hours ago

Thanks for the quick response!

Changing it to queue fixes my Laravel 10 tests 🎉.

However, now I'm running into a new issue with my Laravel 11 tests where it'll publish the migration to the vendor/orchestra/testbench-core/laravel/database/migrations directory, but the job_batches table doesn't exist.

Then, if I re-run my test suite again, the table will be created fine. 🤔

duncanmcclean commented 1 hour ago

For context, we're using this version constraint in our package:

"orchestra/testbench": "^8.0 || ^9.0.2",

When testing Laravel 10, it uses ^8.0 and when testing Laravel 11, it'll use ^9.0.2.

crynobone commented 1 hour ago

I will need to debug your package directly to understand what's going on. WithMigration doesn't publish any migration to database/migrations but instead load migrations from migrations path which mimic publishing migrations via available artisan commands.