Integration tests in Nextcloud 20: Your test case is not allowed to access the database

I am struggling to understand how autoloading works when running integration tests in Nextcloud 20 and get the error Your test case is not allowed to access the database.

The “stable” documentation (same as NC 19?) still mentions the bootstrap.php which I also use, but the Nextcloud 20 documentation has no mention of it. How do integration tests work now?

Problem

In my app I implemented IBootstrap already and deleted app.php. When i run my integration tests I get:

$ vendor/phpunit/phpunit/phpunit -c phpunit.xml.dist
PHPUnit 9.4.0 by Sebastian Bergmann and contributors.

…FFFFF.FFFFFFFFFFF…F 44 / 44 (100%)

Time: 00:00.349, Memory: 24.00 MB

There were 17 failures:

  1. OCA\UserBackendSqlRaw\Tests\Integration\UserBackendTest::testExistingUserIsRecognizedByUsername
    Your test case is not allowed to access the database.

/var/www/nextcloud/tests/lib/TestCase.php:131
/var/www/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php:155
/var/www/nextcloud/3rdparty/pimple/pimple/src/Pimple/Container.php:118
/var/www/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php:122
/var/www/nextcloud/lib/private/ServerContainer.php:156
/var/www/nextcloud/lib/private/Server.php:1703
/var/www/nextcloud/lib/private/AllConfig.php:95
/var/www/nextcloud/lib/private/AllConfig.php:416
/var/www/nextcloud/lib/private/AllConfig.php:319
/var/www/nextcloud/lib/private/User/User.php:104
/var/www/nextcloud/lib/private/User/Manager.php:176
/var/www/nextcloud/lib/private/User/Manager.php:153
/var/www/nextcloud/lib/private/User/Manager.php:190
/var/www/nextcloud/apps/user_backend_sql_raw/tests/Integration/UserBackendTest.php:102

Questions

  1. Do I even need the autoload directives in composer.json or should Nextcloud’s tests/bootstrap.php take care of this?
  2. Did something change in Nextcloud 20 regarding bootstrap.php’s capabilities?
  3. Is there more documentation or an app that would be a good example on how to do this in Nextcloud 20?
  4. I checked out nextcloud/server at tag v20.0.0 and then my app as a submodule in apps. There is also a proper config.php. Is this a wrong setup to develop apps?

The IRC channel seems dead, no message for the past three days. Hoping that any of the devs can help me out here. :neutral_face:

Files

phpunit.xml.dist

<phpunit bootstrap="../../tests/bootstrap.php" colors="true">
    <testsuites>
        <testsuite name="unit">
            <directory>./tests/Unit</directory>
        </testsuite>
        <testsuite name="integration">
            <directory>./tests/Integration</directory>
        </testsuite>
    </testsuites>
</phpunit>

The path to bootrap.php is correct AFAICS, since phpunit.xml.dist is in the main app folder.

composer.json

...
  "autoload": {
    "psr-4": {
      "OCA\\UserBackendSqlRaw\\" : "lib/"
    }
  },
	"autoload-dev": {
		"psr-4": {
			"OCA\\UserBackendSqlRaw\\Tests\\" : "tests/"
		}
	},
...

OK, so I found that it is Nextcloud’s extension of PhpUnits TestCase that only allows database access on certain conditions, i.e. set TRAVIS environment variable and some kind of annotations

$annotations['class']['group']

Why would Nextcloud do this? I have used the normal TestCase by PhpUnit until now which “just worked”, I assumed I would gain something from using Nextcloud’s variant, but I am on the verge of abandoning it.

Can anyone shed some light on this?

Add @group DB to your test class to make it work. I guess the annotations are to split the test suites into tests with a DB dependency and without.

1 Like

Thanks. It took some fiddling and I was about to write that it doesn’t work. But then I realized that I have to annotate the class and not test methods. It works now. Here, for future reference:

/**
 * @group DB
 */
class UserBackendTest extends TestCase {
...

Can you help with any of the other questions? All this autoloading magic is really hard to follow.

@ChristophWurst @rullzer

1 Like

I’m not so much an expert with Nextcloud’s test abstractions. For my apps I use a tiny wrapper around phpunit https://packagist.org/packages/christophwurst/nextcloud_testing and that works almost identical to when you use phpunit directly.

Does it bootstrap Nextcloud in a way that i can use all the DI magic, i.e.$context->get('someClass')?

I had stumbled upon your testing framework already since it was mentioned here and some apps use it. AFAIR, I was not able to understand the advantage over Nextcloud task classes (for me personally) so i did not pursue it further. You write that it is more light-weight and improves the speed of tests, but since my tests run quickly anyway, I am not sure what I would gain from using it.

You’re free to use the Nextcloud test cases. But as you’ve seen they are quite complex and I’ve run into some issue before.

So I guess the most significant difference is that my abstraction is less magical and you simply know what you get.