Laravel provides two traits for managing database state in tests: RefreshDatabase and DatabaseTransactions. RefreshDatabase runs migrations to ensure a clean schema before each test, offering high isolation and compatibility with queues and multiple DB connections, but at the cost of speed. DatabaseTransactions wraps each test in a transaction that rolls back afterward, making it faster and lighter but unsuitable for queue-based or async tests. The recommended default is RefreshDatabase for reliability, with DatabaseTransactions reserved for simple CRUD or unit-like tests where performance matters and no async behavior is involved. Common mistakes include mixing both traits and using DatabaseTransactions with queued jobs.
Table of contents
Understanding the Core ProblemOption 1: RefreshDatabaseOption 2: DatabaseTransactionsKey DifferencesWhen to Use RefreshDatabaseWhen to Use DatabaseTransactionsCommon Mistakes (and How to Avoid Them)Real-World ExampleRecommended StrategyFinal ThoughtsTL;DRSort: