Unit-Testing
PHP Unit Tests
ownCloud uses PHPUnit >= 7.5 for unit testing PHP code.
Getting PHPUnit
Running make
in your terminal from the webroot
directory will prepare
everything for testing. This will install beside necessary dependencies,
a local version of PHPUnit at <webroot>/lib/composer/phpunit/phpunit
.
-
Run
make help
to get a list of parameters -
To update your testing environment run
make clean
andmake
again. -
Take care that the php phpunit file in the path provided has the executable permission set.
Running PHP Unit tests
There are existing test options provided by ownCloud.
To run them, change into the root directory of your ownCloud installation and run grep "make test" <(make help)
to see tests and parameters available.
You should see output similar to the below example.
make test |
run all tests |
make test-php-unit |
run all PHP tests |
make test-php-style |
run PHP code style checks |
make test-php-phan |
run PHP phan static code analyzer |
make test-php-phpstan |
run PHP phpstan static code analyzer |
make test-js |
run Javascript tests |
make test-js-debug |
run Javascript tests in debug mode (continuous) |
make test-acceptance-api |
run API acceptance tests |
make test-acceptance-cli |
run CLI acceptance tests |
make test-acceptance-webui |
run webUI acceptance tests |
make test-php-unit |
TEST_DATABASE=mysql TEST_PHP_SUITE=path/to/testfile.php |
make test-php-style-fix |
run PHP code style checks and fix any issues found |
Testing Apps
To run the tests for a specific app with the provided PHPUnit version:
-
Change into one of the writable directories listed in the
apps_paths
array inconfig/config.php
, for example:cd apps-external
-
Clone the app from GitHub, for example:
git clone https://github.com/owncloud/notes.git
-
Enable the app, for example:
cd .. sudo -u www-data ./occ app:enable notes
-
Change into the newly cloned directory, for example:
cd apps-external/notes
-
Run the following command:
make test-php-unit
Here’s an example of running the command in the notes app:
php -d zend.enable_gc=0 "/home/phil/git/owncloud/core/apps-external/notes/../../lib/composer/bin/phpunit" --configuration ./phpunit.xml --testsuite unit PHPUnit 7.5.20 by Sebastian Bergmann and contributors. Runtime: PHP 7.3.16-1+ubuntu18.04.1+deb.sury.org+1 with Xdebug 2.9.3 Configuration: /home/phil/git/owncloud/core/apps-external/notes/phpunit.xml .................................. 34 / 34 (100%) Time: 541 ms, Memory: 24.00 MB OK (34 tests, 107 assertions) Generating code coverage report in Clover XML format ... done
Apps that are part of core do not have their own Makefile. Third party apps are all apps that are not distributed by ownCloud or not in the supported apps list. |
Writing PHP Unit tests
To get started, do the following:
-
Create a directory called
tests/unit
in the top level of your application -
Create a PHP file in the directory and
require_once
your class which you want to test.
Then you can run the created test with phpunit
.
Alternatively, you can use the default Makefile to automate your unit tests. |
If you use ownCloud functions in your class under test (i.e: OC::getUser()) you’ll need to bootstrap ownCloud or use dependency injection.
You’ll most likely run your tests under a different user than the Web server.
This might cause problems with your PHP settings (i.e., |
Given the class MyClass
in your app:
/srv/http/owncloud/apps/myapp/tests/lib/MyClass.php
<?php
namespace OCA\MyApp;
class MyClass {
public function addTwo($number) {
return $number + 2;
}
}
An example for a simple test would be:
/srv/http/owncloud/apps/myapp/tests/unit/MyClassTest.php
<?php
namespace OCA\Myapp\Tests;
class MyClassTest extends \Test\TestCase {
protected $myClass;
protected function setUp() {
parent::setUp();
$this->myClass = new MyClass();
}
public function testAddTwo(){
$this->assertEquals(5, $this->testMe->addTwo(3));
}
}
The class under test and the test class should share the same namespace so you do not need to use a dedicated |
In /srv/http/owncloud/apps/myapp/
you run the test with the following command:
phpunit tests/unit/MyClassTest.php
Make sure to extend the \Test\TestCase
class with your test and always call the parent methods, when overwriting setUp()
,
setUpBeforeClass()
, tearDown()
or tearDownAfterClass()
methods from the TestCase
.
These methods set up important stuff and clean up the system after the test so that the next test can run without side effects, such as clearing files and entries from the file cache, etc.
For more resources on writing tests for PHPUnit visit the writing tests section of the PHPUnit documentation.
Bootstrapping ownCloud
If you use ownCloud functions or classes in your code, you’ll need to make them available to your test by bootstrapping ownCloud.
To do this, you’ll need to provide the --bootstrap
argument when
running PHPUnit
cd /srv/http/owncloud
phpunit --bootstrap tests/bootstrap.php apps/myapp/tests/testsuite.php
If you run the test suite as a user other than your Web server, you’ll have to adjust your php.ini and file rights.
nano /etc/php/php.ini
and add open_basedir = none
cd /srv/http/owncloud
su -c "chmod a+r config/config.php"
su -c "chmod a+rx data/"
su -c "chmod a+w data/owncloud.log"
Running Unit Tests for ownCloud Core
The core project provides a script that runs all the core unit tests
using the specified database backend like sqlite
, mysql
, pgsql
,
oci
(for Oracle), the default is sqlite
To run tests on mysql
or pgsql
you need a database user called
oc_autotest
with the password owncloud
. This user needs the
privilege to create and delete the database called oc_autotest
.
MySQL Setup
CREATE DATABASE oc_autotest;
CREATE USER 'oc_autotest'@'localhost' IDENTIFIED BY 'owncloud';
GRANT ALL ON oc_autotest.* TO 'oc_autotest'@'localhost';
PostgreSQL Setup
su - postgres
# Use password "owncloud"
createuser -P oc_autotest
# Give the user the privilege to create databases
psql -c 'ALTER USER oc_autotest CREATEDB;'
To enable dropdb
add local all all trust
to pg_hba.conf
.
Run Tests
To run all tests, run the following command:
make test-php-unit
To run tests only for MySQL, run the following command:
make test-php-unit TEST_DATABASE=mysql
To run a particular test suite, use the following command as a guide:
make test-php-unit TEST_DATABASE=mysql TEST_PHP_SUITE=tests/lib/share/share.php
By default, a code coverage report is generated after the test run. To
avoid the time taken for that, specify NOCOVERAGE
:
make test-php-unit NOCOVERAGE=true TEST_DATABASE=mysql TEST_PHP_SUITE=tests/lib/share/share.php
Unit Testing JavaScript in Core
Installing Node JS
To run the JavaScript unit tests you will need to install Node JS. You can get it here: http://nodejs.org/ After that you will need to setup the Karma test environment. The easiest way to do this is to run the automatic test script first, see next section.
Running All The Tests
To run all JavaScript tests, run the following command:
make test-js
This will also automatically set up your test environment.
Debugging Tests in the Browser
To debug tests in the browser, this will run Karma in browser mode
make test-js-debug
From there, open the URL http://localhost:9876
in a web browser. On that
page, click on the Debug button. An empty page will appear, from
which you must open the browser console (F12 in Firefox/Chrome). Every
time you reload the page, the unit tests will be relaunched and will
output the results in the browser console.
Unit Test File Paths
JavaScript unit test examples can be found in apps/files/tests/js/
.
Unit tests for the core app JavaScript code can be found in core/js/tests/specs
.
Documentation
Here are some useful links about how to write unit tests with Jasmine and Sinon:
-
Karma test runner: http://karma-runner.github.io
-
Jasmine: https://jasmine.github.io
-
Sinon (for mocking and stubbing): http://sinonjs.org/