Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon How do I test feature flags in Laravel Pennant when using Laravel Octane


How do I test feature flags in Laravel Pennant when using Laravel Octane


When testing feature flags in Laravel Pennant while using Laravel Octane, you need to be mindful of Octane's persistent worker processes, which can cause state to carry over between requests and tests. This persistence can affect how feature flags behave in tests, especially since Pennant caches feature flag states in memory by default.

Here is a detailed approach to effectively test feature flags in this environment:

Redefining Feature Flags in Tests

Laravel Pennant allows you to redefine feature flags during tests to control their returned values explicitly. This is the simplest and most direct way to ensure predictable behavior in your tests.

For example, if you have a feature flag defined like this in your service provider:

php
Feature::define('purchase-button', fn () => Arr::random(['blue-sapphire', 'seafoam-green', 'tart-orange']));

You can redefine it in your test to always return a specific value:

php
use Laravel\Pennant\Feature;

test('it can control feature values', function () {
    Feature::define('purchase-button', 'seafoam-green');

    expect(Feature::value('purchase-button'))->toBe('seafoam-green');
});

Similarly, for class-based feature flags:

php
use App\Features\NewApi;
use Laravel\Pennant\Feature;

test('it can control feature values', function () {
    Feature::define(NewApi::class, true);

    expect(Feature::value(NewApi::class))->toBeTrue();
});

This approach overrides the original feature flag definition within the test scope, ensuring consistent results regardless of the underlying logic[2].

Handling Laravel Octane’s Persistent State

Since Laravel Octane keeps application state in memory between requests, feature flag states and definitions might persist across tests, potentially causing flaky or incorrect test results.

To handle this:

- Reset or clear feature flag definitions between tests: You can redefine feature flags at the start of each test to ensure a clean state.
- Use Octane's lifecycle hooks: Laravel Octane provides hooks to reset application state between requests or workers. You can leverage these to clear or reset Pennant's feature flag cache or definitions.
- Avoid relying on in-memory state persistence: Since Pennant stores feature flag states in memory by default, consider using a persistent driver (like database-backed) during testing or explicitly reset the state.

Example Test Setup with Laravel Octane

php
use Laravel\Pennant\Feature;
use PHPUnit\Framework\TestCase;

class FeatureFlagTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        // Redefine feature flags to ensure clean state for each test
        Feature::define('new-feature', false);
    }

    public function test_feature_flag_enabled()
    {
        Feature::define('new-feature', true);

        $this->assertTrue(Feature::active('new-feature'));
    }

    public function test_feature_flag_disabled()
    {
        $this->assertFalse(Feature::active('new-feature'));
    }
}

In this example, redefining the feature flag in `setUp` and in individual tests ensures that each test runs with a known feature flag state[2].

Summary

- Redefine feature flags inside your tests to control their values explicitly.
- Be aware of Laravel Octane’s persistent worker processes that may retain in-memory state.
- Reset or redefine feature flags between tests to avoid state leakage.
- Consider using Octane lifecycle hooks to reset Pennant’s state if necessary.
- For class-based flags, redefine the class flag similarly in tests.

This approach ensures reliable and predictable testing of feature flags in Laravel Pennant when running under Laravel Octane[2].

Citations:
[1] https://www.honeybadger.io/blog/a-guide-to-feature-flags-in-laravel/
[2] https://laravel.com/docs/11.x/pennant
[3] https://laravel-news.com/feature-flags-with-laravel-pennant
[4] https://dev.to/saurabh-dhariwal/how-to-manage-feature-flags-with-laravel-pennant-in-2024-1phb
[5] https://bmehul.com/articles/laravel-pennant-a-guide-to-feature-flags
[6] https://www.linkedin.com/pulse/implementing-feature-flags-laravel-guide-progressive-delivery-ishaq-lfduf
[7] https://hackernoon.com/how-to-manage-feature-flags-with-laravel-pennant
[8] https://www.youtube.com/watch?v=EjLAaeHSPWY