Force reload of entity metadatas
I have extended WebTestCase and implemented my tests the same as usual. However when running 'all' tests as a batch I came across a problem.
The code I'm testing uses a custom metadata driver. This drivers getAllClassNames method will return a subset of the defined entities depending on the bundles configuration. In practice, this works perfectly, in testing it does not. I've tracked the problem down to WebTestCase::loadFixtures, which loads the metadatas and stores them in a private static array. This means I cannot change which metadatas are loaded once the tests have started.
The easiest fix for this would be to declare WebTestCase::$cachedMetadatas as protected, that way I can reset it from my derived class.
Can anybody suggest a way around this problem?
Maybe you can use the class annotation @runTestsInSeparateProcesses as in the tests: https://github.com/liip/LiipFunctionalTestBundle/blob/23a229daa3a4880a6fd659a24d64639427ed1e7d/Tests/Test/WebTestCaseConfigTest.php#L24 It creates isolated environments for each test class. It requires that each test class load specific fixtures.
@alexislefebvre I ended up writing my own fixture loader.
I will leave this thread open since I believe this to be a bug. The metadatas are stored using only the orm name, it doesn't take into account the environment being used (which, as in my case, may use a different schema). The key used, for $cachedMetadatas, should be a combination of the environment and the orm.
Did your tests worked when you launched only one test class at a time? You suggest to use the environment when creating the cache, are you thinking to dev, test, etc.?
@alexislefebvre Yes, they work when run one at a time. The problem is when loading for different environments across multiple tests classes.
Then I suggest you to try to use @runTestsInSeparateProcesses, it will create kernels with their own configuration, but I'm not sure it will solve problems with the cache...
@alexislefebvre That would work, but it also has a downside. I have something in the region of 15 test classes, at the moment, and 3 configurations. A single configuration may be used in one or more tests. Sometimes all 3 configurations are used in the same test. By using threads, I will lose the cache though the sqlite database files will remain.
Like I mentioned above, I rewrote the loadFixtures method to store the metadatas using $this->environment . $orm; as the key, which works perfectly.
I see this thread has been closed a few times. The simple fact is, you cannot rely on loadFixtures to create, or use, the correct schema when using mixed environments.
@twifty I'm sorry for closing this issue, I misclicked, then reopened it but an automatic script or GitHub tool closed the issue with lsmith77's account.
LiipFunctionalTestBundle is designed to run in test environment, this environment is usually a mirror of the prod environment with specific changes for test. I never heard about the use of other environments (except dev), it seems to be an edge case.
I'll see if we can apply the change you suggested (store the metadatas using $this->environment . $orm; as the key), not by changing the current code but by refactoring the existing code and add a method that you'll be able to override.
@alexislefebvre TBH, using an environment other than the standard 'test' is the easiest method of loading a specific set of bundle configurations. Granted, in most cases a test suit would simulate the different config values. In my case, using a custom metadata driver which produces different schemas, it is far less problematic to allow the kernel and doctrine to parse different configuration files than it would be to try to simulate it just for the purpose of testing.
I have the same issue. In my case, my test suite creates different kernel in different environments and I am using default entity manager. I had to change the key cache as you say and it works.
@alexislefebvre what idea of the feature are you thinking? Maybe I can do it.
@alexislefebvre ping, some feedback about this, I would like to try to do it.