-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[11.x] Improved Performance for Testing with In-Memory Databases #47912
Conversation
I like the idea, and I think it could work, but there is a bug in your implementation. Copy pasting the trait breaks my entire test suite. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably 11.x is the best place for this, as this could break things for people doing funky things such as DDL in their tests.
Thank you for the feedback. I have rebased on @JurianArie Can you please be more specific here is what I just did:
|
@AJenbo I copy pasted the trait (directly in the vendor folder) from this PR into a project that uses a in memory DB for testing. It looks like the database never gets migrated. Error output
|
I can confirm a good speedup as well on our test suite with these changes 👍 Without change: PHPUnit 10.2.6 with PHP 8.2.8 |
I can also confirm an increase in speed. 182 tests PHPUnit 10.2.6 (+ with some Pest) @AJenbo |
This breaks my testsuite as well, running a single test or test file works fine, but running the whole suite breaks all tests that rely on the database. Hope this helps. |
@axlon Can you please provide a test case or steps to reproduce it. |
I don't think I can provide a test case because every single test case passes in isolation, it only fails when running all my tests. Obviously I can't post my entire project. Could it be that running tests that don't use the DB at all alongside tests that do maybe breaks the internal state? I also use |
Please mark as ready for review when cause of breakages has been found and fixed. |
Hi, I tried out the trait and got the same error, reported earlier. I switched phpunit.xml: <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheResult="true"
backupGlobals="false"
colors="true"
cacheDirectory="coverage/cache"
backupStaticProperties="false"
>
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
</source>
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit> .env.testing [...]
DB_CONNECTION=sqlite_testing
DB_HOST=127.0.0.1
DB_PORT=3306
[...] database.php (config) [...]
'connections' => [
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
'foreign_key_constraints' => true,
],
],
[...] Error in the console after running SQLSTATE[HY000]: General error: 1 no such table: roles (Connection: sqlite_testing, SQL: insert into "roles" [...] I'm using pest version Hope that helps to narrow down the error a bit more. |
Results using Vapor is test suite: Apple M1 Pro 16 GB | 851 tests
|
@nunomaduro sorry I'm not sure I follow. Are you saying that using Vapor in a project will trigger the issue, or that the test suite for the Vaport project displays the issue? |
@AJenbo Just saying that the changes on this pull request makes the Vapor's test suite to fail. |
@AJenbo I also get the same exception that a table is not found. It doesn't happen if you have only one feature test with |
I managed to track down a project that exhibited the described issue and have applied the needed changes to fix it. Turns out the difference is that it worked when Thank you to everyone who assisted in testing. |
@AJenbo can confirm it is now working as expected! 👍 |
@AJenbo Laravel.io's codebase might be a good candidate as well to try these changes: https://github.com/laravelio/laravel.io |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can confirm that it now works!
This provides a significant performance increase for running tests when using an in memory database.
@AJenbo Sorry - it's been a while since I wrote this code. What happens currently (without this PR) if you try to treat SQLite in-memory databases like MySQL databases and let the |
@taylorotwell By doing so, we would encounter a The changes introduced by this PR involve retaining a persistent PDO instance in the |
Thanks! |
@AJenbo is there any documentation on how to migrate a Laravel 10 package to adapt to this change? |
@mokhosh does this behave differently for you depending if you use MySQL or SQLite? Was that also the case prior? In Laravel 10 You might want to use DatabaseMigrations or DatabaseTruncation if your tests require that the database is reset between each test. See: https://laravel.com/docs/10.x/dusk#resetting-the-database-after-each-test It could also happen if you manually start a transaction in a way that isn't done though |
@AJenbo Thanks for your reply. If I don't touch anything except changing the driver to
|
Ok that's a good indication that your tests are not compatible with I would suggest you switch to Alternatively you could try calling |
This pull request aims to enhance the performance and developer experience when running tests with an in-memory database in Laravel. By keeping a reference to the PDO object and restoring it for connections, we enable transaction-based database refresh, resulting in a significant performance boost. Test suites that used to take minutes to run are now completed in just seconds, providing a much smoother testing process.
I believe this change is non-breaking as it replicates the same database operations that would occur with a persisted database configuration. However, if there are any concerns, please let me know, and I can rebase and retarget the pull request on the master branch.
Please feel free to provide any feedback or preferences regarding the implementation or coding style. Your input is greatly appreciated.
Thank you.