Unit tests: Using $fixture_file makes tests crash

<%- if @topic_view.topic.tags.present? %>
<%= t 'js.tagging.tags' %>: <%- @topic_view.topic.tags.each do |t| %> <%= t %> <%- end %>
<% end %>

Silverstripe Version: 4.3.3

Question:

Hi, consider the following simple test class:

class MyTest extends SapphireTest
{
	protected static $fixture_file = [
		'app/tests/fixtures.yml'
	];
	
	public function testSomething()
	{
		$this->assertTrue(true); // Do whatever here, as we will never make it to this point.
	}
}

If I run this test, I will get the following error message:
PHP Catchable fatal error: Argument 1 passed to SilverStripe\View\Requirements::set_backend() must be an instance of SilverStripe\View\Requirements_Backend, null given, called in /var/www/html/myproject/vendor/silverstripe/framework/src/View/Dev/RequirementsTestState.php on line 29 and defined in /var/www/html/myproject/vendor/silverstripe/framework/src/View/Requirements.php on line 116

If I remove the $fixture_file definition, the test works without any issues. And if I set $fixture_file to point to a non-existent file, the same error happens again, so I think that the content of the fixture file does not matter here.

This is really strange and I’ve been struggling with this for many hours now. Maybe it has something to do with my particular project (installed modules, custom code, whatever) but I really have no clue. Or then it’s a bug in SilverStripe, but then again it seems unlikely because $fixture_file seems to be a very common feature, so probably there would already be bug reports about it if it wouldn’t work for others. I even tried to downgrade to SilverStripe 4.2.0 to check if the issue was caused by some change in the recent version history of SilverStripe, but the same problem occurred with 4.2.0 too.

Thank you for your support!

Did you try to include the fixture file relatively? I normally put it in the same folder as my tests. It might also make problems, when the yml is not valid. This drove me crazy sometimes in the past. You can put it in a yml validator to find potential errors.

Thanks wmk! I need to try to put the file to the same folder. Maybe I already tried it, but I don’t remember. And thanks for the tip about the yml validator too, I need to check that too when I work on this issue again. I’ll post again if I’m not able to solve the problem :).

Now I validated the YAML file (was ok) and moved it to the same folder with the test and removed the file directory part from $fixture_file. Unfortunately it didn’t help.

Maybe one of the objects in your fixture is trying to manipulate Requirements in a way that maybe causes issues when running unit tests?

Thanks for the suggestion, but I don’t think that’s the case. I think I’m not using any Requirements in this project. This project is mostly about processing data and relaying it to third party services, and there’s not so much frontend stuff involved. The admin panel of course could use some custom CSS and JavaScript, but now that I think of it, I don’t think I’ve created any custom JavaScript or CSS files that would be included via Requirements - not in PHP code nor in SS template files.

And another thing is that the error happens even if I set $fixture_file to point to a non-existing file. Which leads me to think that how could I test if my fixture file is actually found while trying to be loaded? This test should be made somewhere before the point where the error occurs. Which probably means temporary edits to SilverStripe’s framework files, which is okay as it would be just temporary testing. I’m just not sure how to test this :D.

I’m not sure if a solution was ever found for this, but I hit an issue with very similar symptoms. I still have no idea what the underlying cause was, except that it seemed to be attached to building the database (it also happened with $usesDatabase = true, and it would never complete the database build). There wasn’t any obvious code cause that I could find. What I did find though, is that I could bypass the issue by running composer test with SQLite3Database ("silverstripe/sqlite3": "2.x-dev") and this line in composer scripts:

 "scripts": {
        "test": "SS_DATABASE_CLASS=SQLite3Database SS_DATABASE_PATH=':memory:' php -d memory_limit=-1 ./vendor/bin/phpunit --verbose",
},

I did also have to add a silverstripe-cache directory to get past this error:

LogicException: getItemPath returned null for SilverStripe\Dev\State\FixtureTestState. Try adding flush=1 to the test run.

If anyone did find a cause for this issue, I’d be really keen to know it.

Hi @adrexia
This is just a quick answer. I haven’t looked at this issue for a while in my project and didn’t try SQLite yet (thanks for the workaround idea, I will have to look at it some day if it works for me). But just to confirm, no solution has yet been found to the actual problem.