phpunit-injector icon indicating copy to clipboard operation
phpunit-injector copied to clipboard

Ability to boot only once per class

Open drzraf opened this issue 3 years ago • 5 comments
trafficstars

Booting the kernel is slow. It may sometimes be desirable to reuse a kernel across several related tests, especially when they rely upon the same container's configuration.

drzraf avatar May 02 '22 19:05 drzraf

I'd argue that tests using the kernel/container should be rare. Each test should start with a clean state to be reliable.

However, I understand on some codebases there's no other way and one would like to save some time on booting the kernel. I think you can already do it by implementing your own trait (like SymfonyTestContainer). If you'd like to contribute to this repo, I'm open to accept a pull request adding this feature (if it doesn't change the code drastically).

jakzal avatar May 03 '22 19:05 jakzal

What I'm currently doing is to pass per-test kernel configuration as a test metadata. Eg:

    /**
     * @testWith [{"replace":{"foo":{"bar":"allowed_group"}}}]
     */
    public function testGroupsValidation() {}

And my in my trait:

    public function createContainer(): ContainerInterface
    {
        foreach ($this->getProvidedData() as $value) {
            if (isset($value['replace'])) { array_replace_recursive("blabla", $value['replace']); }
        }
        return static::bootKernel(['config' => $config]) // my test Kernel handles this `config` key
            ->getContainer()
            ->get('test.service_container');
    }

It sounds fragile but is the only way I found a test could declare per-container configuration and still be relieved from the task of initializing the container itself (and rely upon phpunit-injector)

drzraf avatar May 05 '22 18:05 drzraf

Not entirely what you're after, but maybe it will give you some ideas. Some time ago I was playing with the idea of initialising bundle configs per test case: https://github.com/jakzal/bundle-test

jakzal avatar May 23 '22 09:05 jakzal

Not entirely what you're after, but maybe it will give you some ideas. Some time ago I was playing with the idea of initialising bundle configs per test case: https://github.com/jakzal/bundle-test

That's exactly why I'm after (and I don't understand that few developers experience the same need). For now I created a homegrow annotation system that allows me to set configuration (and service's mocks) on a per-test basis, eg:

    /**
     * @testWith [{"mocks":{"mybundle.driver.my.service":"MyBundle\\Tests\\Mock\\My\\Service"}}]
     */

or

    /**
     * @testWith [{{"set":{"my.destinations.config.mc.strategy":{"class":"PostPatch","args":[]},"blah.groups":{"extra":{"forcedGroup":true},"allowed":{"optionalGroup":true}},"destinations.tags":{"extra":["forcedTag"],"allowed":["optionalTag"]}}}]
     */

where the equivalent bundle YAML is set as a JSON data annotation.

But would surely prefer to go with a clean, reliable and mainstream library to do this. Why did you archived your project? Did you find a better alternative?

drzraf avatar May 23 '22 20:05 drzraf

Why did you archived your project? Did you find a better alternative?

The only reason is I stopped developing bundles. I believe that my bundle-test was the most flexible solution out there. Feel free to take it over. Unfortunately, I don't remember in what state I have left it and if it was ready to use.

jakzal avatar May 23 '22 20:05 jakzal