About Features Downloads Getting Started Documentation Events Support GitHub

Site Tools


development:testing:unit_tests

Unit Tests

This page is aimed at developers who want to test that their changes have not broken existing VuFind functionality or who are interested in creating standard tests for new VuFind components. If you are interested in testing performance rather than functionality, see the Testing Performance page instead.

Background

The test modules provided with VuFind use the PHPUnit testing framework. The framework is installed as part of VuFind's Composer development dependencies. Once installed, you will have a vendor/bin/phpunit command line tool that you can use to run tests (as well as some convenient Phing tasks to make running the tasks more convenient).

Running Tests

Important Warnings

These tests were designed for use with VuFind's continuous integration system. As such, some tests create and destroy data. Although some safety mechanisms exist to reduce the chances of accidental data loss, THE TESTS SHOULD NEVER BE RUN ON A PRODUCTION SYSTEM.

The testing process was developed under Linux; this is the recommended platform for VuFind testing, and different procedures may need to be developed for other platforms like Windows.

Using Phing

The easiest way to run VuFind's tests is with the help of the Phing build tool. VuFind comes with a build.xml file that Phing can use to automate tasks.

1.) Create a fresh copy of VuFind (i.e. git clone the repository to a fresh directory, then run “composer install”)

2.) Create a phing.sh script to automatically pass important parameters to Phing (see build.xml for other parameters that may be set here with the -D parameter):

#!/bin/sh
$VUFIND_HOME/vendor/bin/phing -Dmysqlrootpass=mypasswd $*

If you are managing multiple VuFind test environments, it may make sense to have a different phing.sh in each VuFind directory (e.g. $VUFIND_HOME/phing.sh). In the more common scenario where you have just one test environment, it is usually more convenient to put this in your own home directory (i.e. ~/phing.sh). The examples below will assume that you are using a script in your home directory.

Running tests after setup

Follow these steps to run tests. Keep in mind that testing will create a test Solr index listening on port 8983. This may cause port conflicts if you test on a server that is already running applications on that port – plan accordingly.

1.) ~/phing.sh startup

This command will start up an instance of VuFind containing test data that may be used by some of the tests.

2.) ~/phing.sh phpunit

or

~/phing.sh phpunitfast

or

~/phing.sh phpunitfaster

(the phpunit command will run tests and generate report data for use by continuous integration; phpunitfast will run tests more quickly by skipping reports; phpunitfaster is like phpunitfast but stops upon the first test failure instead of going through the full suite)

3.) ~/phing.sh shutdown

This command will turn off the VuFind test instance created by step 1.

The Faster Version

If you don't want to run integration tests using a running VuFind, you can simply bypass the startup/shutdown steps and only execute:

~/phing.sh phpunitfast

The integration tests will be skipped, but all unit tests not depending on a running VuFind instance will still run.

Running Just One Test

Sometimes you want to run a specific test without the rest of the suite. You can use the phpunit_extra_params parameter for this:

~/phing.sh phpunitfast -Dphpunit_extra_params=$VUFIND_HOME/path/to/your/test.php

Browser Automation Tests with Mink

Some of VuFind's tests are designed to use Mink to automate a browser. These tests will be skipped unless you have properly configured your environment so the tests have a VuFind instance they can drive.

If you wish to run this portion of the test suite, revise your phing.sh script (described above) to include some additional variables:

  • extra_shutdown_cleanup - an extra command to run as part of the shutdown process; it's usually a good idea to change the ownership of the local/cache directory here since running tests will cause some files to be owned by Apache, and that will interfere with subsequent file deletion.
  • apacheconfdir - a directory from which Apache will auto-load configurations; we need this to start up a new VuFind instance by injecting a file
  • apachectl - the command to restart Apache; you'll probably need to prefix this with sudo to make it work when running tests as a different user
  • dbtype (optional) - defaults to mysql, but can be set to “pgsql” to test with PostgreSQL instead
  • mysqlrootpass (optional) - the MySQL root password (needed for building VuFind's database, when dbtype = mysql)
  • vufindurl (optional) - the URL where VuFind will be accessed (defaults to http://localhost/vufind if omitted)
  • mink_driver (optional) - the name of the Mink driver to use (e.g. “selenium” or “chrome”).

Here's an example script from an Ubuntu environment using MySQL:

#!/bin/sh
phing -Dextra_shutdown_cleanup="sudo chown -R myusername:mygroup /path/to/vufind/local/cache" -Dapacheconfdir="/etc/apache2/conf-enabled" -Dapachectl="sudo /etc/init.d/apache2" -Dmysqlrootpass=myrootpasswd -Dvufindurl=http://localhost/vufind_test -Dmink_driver=chrome $*

You will also need to install and run a few things, depending on how you want to run your tests.

Selenium Testing

:!: Selenium testing can be useful for testing a variety of browsers, but headless Chrome browsing is generally easier to set up; see below for details on that.

Before running your tests, you should download the Selenium server .jar file from here. It may also be called Grid. The Selenium Server needs to be started before you run phpunit with “java -jar [downloaded file]”.

If you want to use a browser other than Firefox with Selenium, use the -Dselenium_browser=[name] setting to switch. For example, you can use -Dselenium_browser=chrome, though this requires you to have the ChromeDriver installed on your system. Download the version that matches your installed Chrome version and place the unpacked file along your bin path, such as in /usr/bin.

When running in a continuous integration environment, you should use Xvfb to create a virtual frame buffer so that the browser driven by Selenium can run without errors. However, for manually-executed tests, you can watch the browser executing the tests, which can be useful for troubleshooting purposes.

If you don't want to monitor test results or watch the Selenium server jar's output, you can have Phing automatically start up/shut down Selenium and Xvfb by passing the -Dseleniumjar=[downloaded file] option when you startup and shutdown your test instance.

When running tests in a windowed environment, it's a good idea to open a couple of Terminal windows – that way you can run the Selenium server in one window (to watch it receive commands) while running your tests themselves in another (to see failures, etc.).

Headless Chrome Testing

:!: Headless Chrome testing was introduced in VuFind 7.

Versions of Chrome 80+ have a built-in remote debugging feature. You can run Chrome instead of the Selenium Server like so:

google-chrome --disable-gpu --headless --remote-debugging-address=0.0.0.0 --remote-debugging-port=9222 --window-size="1366,768" --disable-extensions

Then, when you run the phpunit Phing task, add the parameter -Dmink_driver=“chrome” (or make sure this is set as a default in your phing.sh script).

Troubleshooting

:!: This section contains some notes that may help you avoid problems when trying to run VuFind's test suite.

  • Some of VuFind's tests use a record ID containing a slash. In order for these tests to work, your Apache installation needs to be configured with “AllowEncodedSlashes on” set in the VirtualHost used for running the VuFind instance being tested.
  • When testing with PostgreSQL, it may be necessary to edit the pg_hba.conf file and change the line “local all all peer” to “local all all md5” to allow password-based database logins required my the test environment.

Mink Tests with Chrome on macOS

Running Chrome Headless

A command to start Chrome before running the tests:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-gpu --headless --remote-debugging-address=0.0.0.0 --remote-debugging-port=9222 --window-size=1600,900

Required GNU Utilities

:!: Note: This applies only to VuFind versions before 8.0.

VuFind's Mink tests up to version 7.x rely on options available only in GNU versions of find, sed and basename, so you will need to install those versions and make sure they are used when running Mink tests on macOS. One option is to use Homebrew to install them:

brew install findutils gnu-sed gnu-basename

Then prefix the phing command in phing.sh with a path that contains these utils. Here is an example that uses a static Apache configuration and mysql with passwordless authentication (both installed with Homebrew):

PATH="/usr/local/opt/gnu-sed/libexec/gnubin:/usr/local/opt/findutils/libexec/gnubin:$PATH" $VUFIND_HOME/vendor/bin/phing -Dmysqlrootuser=$LOGNAME -Dmysqlrootpass="" -Dvufindurl=http://localhost:8080/vufind-test -Dmink_driver=chrome $*

Writing Tests

Location

VuFind unit tests (which check the functionality of individual components) can be found in the module/VuFind/tests/unit-tests directory of your VuFind installation.

VuFind integration tests (which check the interaction of components in a real running system) can be found in the module/VuFind/tests/integration-tests directory of your VuFind installation.

VuFind support modules (VuFindHttp, etc.) have their own tests directories, but these are configured to be run automatically as part of VuFind's main test suite.

The layout of the each test directory is designed to mirror the VuFind module's src directory (module/VuFind/src/VuFind). Tests should be placed in a directory that corresponds with the component being tested. For example, the unit tests for the \VuFind\Date\Converter class are found in “module/VuFind/tests/unit-tests/src/VuFindTest/Date/ConverterTest.php”.

Support Classes/Traits

The VuFindTest namespace (code found in module/VuFind/src/VuFindTest) contains several classes and traits which may be useful in writing new tests – a fake record driver in VuFindTest\RecordDriver, some helpful traits in VuFindTest\Feature, and some base test classes containing reusable patterns in VuFindTest\Unit.

:!: When working on integration tests, pay special attention to the VuFindTest\Feature\Live* traits (introduced during VuFind 8 development), which provide helpful methods for retrieving services that provide access to the real database and Solr instances for tests where actual data needs to be manipulated. Such tests should be written with caution, and should only be run in a safe test environment, as noted elsewhere.

Mink Browser Automation

If you want to write browser automation tests, you should extend \VuFindTest\Integration\MinkTestCase. This class will automatically set up the Mink environment for you. It also provides a changeConfigs() method which can be used to reconfigure the running VuFind instance by modifying its .ini files. Any changes made by this method will be automatically rolled back at the end of the test, so you can test a variety of configurations in a single test class.

Some example Mink tests can be found in module/VuFind/tests/integration-tests/src/VuFindTest/Mink/.

Local Tests

Create a directory in your local module mimicking the current structure of the vufind tests. Then all you have to do is require the class you are testing. If you figure out a way to autoload local module classes for testing, please let us know!

Prior to vufind 2.2 this will require changes to phpunit.xml. See commit 6e2b138.

development/testing/unit_tests.txt · Last modified: 2021/06/09 11:18 by emaijala