Skip to content

[12.x] Isolate compiled views per process during parallel testing#58390

Merged
taylorotwell merged 4 commits intolaravel:12.xfrom
dxnter:feat/isolate-compiled-views-parallel-testing
Jan 15, 2026
Merged

[12.x] Isolate compiled views per process during parallel testing#58390
taylorotwell merged 4 commits intolaravel:12.xfrom
dxnter:feat/isolate-compiled-views-parallel-testing

Conversation

@dxnter
Copy link
Contributor

@dxnter dxnter commented Jan 15, 2026

Fixes #58378

Overview

Addressing race conditions that can occur when running tests in parallel. I originally approached this issue with updates to the CompilerEngine and BladeCompiler in #58381, but I closed that since it was starting to involve too many changes.

Problem

When running parallel tests, multiple processes compile and read Blade views from the same directory simultaneously. This causes several types of failures:

  • FileNotFoundException when a compiled view is deleted by another process before it can be read
  • ParseError by reading a partially-written compiled view file (file_put_contents() is not atomic)
  • Livewire's RootTagMissingFromViewException when inline component templates are truncated

None of these are deterministic and can be difficult to reproduce, but become increasingly common as the number of parallel processes increases.

Solution

Following a similar pattern that's used for database isolation (TestDatabases), this PR introduces a TestViews trait that isolates compiled views per test process. Each parallel process now uses its own subdirectory.

This completely eliminates race conditions since processes no longer share compiled view files.

@dxnter dxnter force-pushed the feat/isolate-compiled-views-parallel-testing branch from 2712580 to 8fb80e8 Compare January 15, 2026 18:34
@taylorotwell
Copy link
Member

@dxnter sorry for the silly question, but I'm wondering if this issue is resolved if view:cache is run before testing?

@dxnter
Copy link
Contributor Author

dxnter commented Jan 15, 2026

@dxnter sorry for the silly question, but I'm wondering if this issue is resolved if view:cache is run before testing?

Logically that makes sense, and a commenter on the issue brought that up. In their case, that didn't fix the failures.

view:cache mostly gets you there, but the gap is that inline templates are creating the source file at runtime through Component::createBladeViewFromString(). Livewire even recommends 12 the pattern for small components, and there are likely plenty of other dependencies that ship inline Livewire/Blade components.

Because of that, there's no way to pre-compile these templates. They don't exist on disk until the component renders for the first time, which is where the parallel testing issues come in.

There are also a few other scenarios where views can't be pre-compiled:

  1. View::file() with computed paths, which Livewire uses as a fallback
  2. Dynamic view names (e.g., return view('components.'.$this->type))

Footnotes

  1. https://livewire.laravel.com/docs/3.x/components#inline-components

  2. https://livewire.laravel.com/docs/4.x/computed-properties#using-inline-templates

@iBotPeaches
Copy link
Contributor

Logically that makes sense, and a commenter on the issue brought that up. In their case, that didn't fix the failures.

Yeah I believe I made that comment and changed my build script thinking caching views prior to parallel execution would help, but it didn't.

- name: Pregenerate View Cache
   run: php artisan view:cache

I thought because every single Livewire component render method was just calling view() meant I was covered, but I'm guessing some of these inline placeholders may cause it.

    public function placeholder(): string
    {
        return '<div class="flex justify-center p-6"><flux:icon.loading /></div>';
    }

Haven't dug as far as you to be sure. I did adapt our CI to export view caches during failures to see if I can help track it further, but knowing I'm Livewire/Flux - it may be something in that realm.

@taylorotwell taylorotwell merged commit fa3b25a into laravel:12.x Jan 15, 2026
70 checks passed
@andreasnij
Copy link
Contributor

@dxnter Nice solution! This resolves my issue 🙏

One possible concern is that cached views are not cleared after the tests finish, and view:clear does not remove subdirectories. I am not sure whether this has any practical implications, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parallel testing can trigger a race condition causing "View file does not exist at path" error

4 participants