diff --git a/.gitignore b/.gitignore
index 20cbba2092d2087678ed01049b8e43ee56db06a2..4f1a4bd06fbb01dbb0aa99b968fc0b0740dd1bef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,30 +1,19 @@
 # GNU Emacs temporary files
-.idea
-.vscode
-ChangeLog
 \#*
 .\#*
+*~
+
 .php_cs_cache
 .vagrant
 .vscode/*
-TAGS
-*~
-/data/.languages
 /downloads
+/solr/vendor
 /vendor
+ChangeLog
+TAGS
 composer.phar
 import/solrmarc.log*
-/node_modules
-/public/swagger-ui
-/.vagrant
-/import
-/solr
-/auth.json
-/core
-/lessphp_*.list
-/data
-/docker-compose.override.yml
-/docker-env.override.yml
-/.env
-**/compiled.css
-**/print.css
\ No newline at end of file
+lessphp_*.list
+module/VuFind/tests/.phpunit.result.cache
+node_modules
+public/swagger-ui
diff --git a/composer.json b/composer.json
index a5a7b4e98d5d8808637d70b16857b85921dce1e9..312d2ea801245eb4f1176e5cf7a232d670348d57 100644
--- a/composer.json
+++ b/composer.json
@@ -82,7 +82,7 @@
         "friendsofphp/php-cs-fixer": "2.16.1",
         "phploc/phploc": "4.0.1",
         "phpmd/phpmd": "2.8.1",
-        "phpunit/phpunit": "7.5.20",
+        "phpunit/phpunit": "8.5.2",
         "sebastian/phpcpd": "4.1.0",
         "squizlabs/php_codesniffer": "3.5.3",
         "dmore/chrome-mink-driver": "^2.7"
diff --git a/composer.lock b/composer.lock
index a60cd82973c2c9eaacba30498a7454effabfcb3e..ae9973c58487ae05668f8f68556b02bb60593941 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "189c69b581c42a2c33d1bcbaaaceb82f",
+    "content-hash": "0b5d6a74f9943e8177e4ca831be9dc0b",
     "packages": [
         {
             "name": "ahand/mobileesp",
@@ -6424,40 +6424,40 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "6.1.4",
+            "version": "7.0.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
+                "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
-                "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf",
+                "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-xmlwriter": "*",
-                "php": "^7.1",
-                "phpunit/php-file-iterator": "^2.0",
+                "php": "^7.2",
+                "phpunit/php-file-iterator": "^2.0.2",
                 "phpunit/php-text-template": "^1.2.1",
-                "phpunit/php-token-stream": "^3.0",
+                "phpunit/php-token-stream": "^3.1.1",
                 "sebastian/code-unit-reverse-lookup": "^1.0.1",
-                "sebastian/environment": "^3.1 || ^4.0",
+                "sebastian/environment": "^4.2.2",
                 "sebastian/version": "^2.0.1",
-                "theseer/tokenizer": "^1.1"
+                "theseer/tokenizer": "^1.1.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "^7.0"
+                "phpunit/phpunit": "^8.2.2"
             },
             "suggest": {
-                "ext-xdebug": "^2.6.0"
+                "ext-xdebug": "^2.7.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "6.1-dev"
+                    "dev-master": "7.0-dev"
                 }
             },
             "autoload": {
@@ -6483,7 +6483,7 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2018-10-31T16:06:48+00:00"
+            "time": "2019-11-20T13:55:58+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
@@ -6676,53 +6676,52 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "7.5.20",
+            "version": "8.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
+                "reference": "018b6ac3c8ab20916db85fa91bf6465acb64d1e0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
-                "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/018b6ac3c8ab20916db85fa91bf6465acb64d1e0",
+                "reference": "018b6ac3c8ab20916db85fa91bf6465acb64d1e0",
                 "shasum": ""
             },
             "require": {
-                "doctrine/instantiator": "^1.1",
+                "doctrine/instantiator": "^1.2.0",
                 "ext-dom": "*",
                 "ext-json": "*",
                 "ext-libxml": "*",
                 "ext-mbstring": "*",
                 "ext-xml": "*",
-                "myclabs/deep-copy": "^1.7",
-                "phar-io/manifest": "^1.0.2",
-                "phar-io/version": "^2.0",
-                "php": "^7.1",
-                "phpspec/prophecy": "^1.7",
-                "phpunit/php-code-coverage": "^6.0.7",
-                "phpunit/php-file-iterator": "^2.0.1",
+                "ext-xmlwriter": "*",
+                "myclabs/deep-copy": "^1.9.1",
+                "phar-io/manifest": "^1.0.3",
+                "phar-io/version": "^2.0.1",
+                "php": "^7.2",
+                "phpspec/prophecy": "^1.8.1",
+                "phpunit/php-code-coverage": "^7.0.7",
+                "phpunit/php-file-iterator": "^2.0.2",
                 "phpunit/php-text-template": "^1.2.1",
-                "phpunit/php-timer": "^2.1",
-                "sebastian/comparator": "^3.0",
-                "sebastian/diff": "^3.0",
-                "sebastian/environment": "^4.0",
-                "sebastian/exporter": "^3.1",
-                "sebastian/global-state": "^2.0",
+                "phpunit/php-timer": "^2.1.2",
+                "sebastian/comparator": "^3.0.2",
+                "sebastian/diff": "^3.0.2",
+                "sebastian/environment": "^4.2.2",
+                "sebastian/exporter": "^3.1.1",
+                "sebastian/global-state": "^3.0.0",
                 "sebastian/object-enumerator": "^3.0.3",
-                "sebastian/resource-operations": "^2.0",
+                "sebastian/resource-operations": "^2.0.1",
+                "sebastian/type": "^1.1.3",
                 "sebastian/version": "^2.0.1"
             },
-            "conflict": {
-                "phpunit/phpunit-mock-objects": "*"
-            },
             "require-dev": {
                 "ext-pdo": "*"
             },
             "suggest": {
                 "ext-soap": "*",
                 "ext-xdebug": "*",
-                "phpunit/php-invoker": "^2.0"
+                "phpunit/php-invoker": "^2.0.0"
             },
             "bin": [
                 "phpunit"
@@ -6730,7 +6729,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "7.5-dev"
+                    "dev-master": "8.5-dev"
                 }
             },
             "autoload": {
@@ -6756,7 +6755,7 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2020-01-08T08:45:45+00:00"
+            "time": "2020-01-08T08:49:49+00:00"
         },
         {
             "name": "sebastian/code-unit-reverse-lookup",
@@ -7088,23 +7087,26 @@
         },
         {
             "name": "sebastian/global-state",
-            "version": "2.0.0",
+            "version": "3.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/global-state.git",
-                "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
+                "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
-                "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4",
+                "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.0"
+                "php": "^7.2",
+                "sebastian/object-reflector": "^1.1.1",
+                "sebastian/recursion-context": "^3.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^6.0"
+                "ext-dom": "*",
+                "phpunit/phpunit": "^8.0"
             },
             "suggest": {
                 "ext-uopz": "*"
@@ -7112,7 +7114,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-master": "3.0-dev"
                 }
             },
             "autoload": {
@@ -7135,7 +7137,7 @@
             "keywords": [
                 "global state"
             ],
-            "time": "2017-04-27T15:39:26+00:00"
+            "time": "2019-02-01T05:30:01+00:00"
         },
         {
             "name": "sebastian/object-enumerator",
@@ -7375,6 +7377,52 @@
             "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
             "time": "2018-10-04T04:07:39+00:00"
         },
+        {
+            "name": "sebastian/type",
+            "version": "1.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/type.git",
+                "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3",
+                "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.2"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Collection of value objects that represent the types of the PHP type system",
+            "homepage": "https://github.com/sebastianbergmann/type",
+            "time": "2019-07-02T08:10:15+00:00"
+        },
         {
             "name": "sebastian/version",
             "version": "2.0.1",
diff --git a/module/VuFind/src/VuFindTest/Unit/ILSDriverTestCase.php b/module/VuFind/src/VuFindTest/Unit/ILSDriverTestCase.php
index ae243edeae1e4a1ba434eb58b509726f073c2031..596e9542ffc825f412664bf7bc9cabb5d454bc57 100644
--- a/module/VuFind/src/VuFindTest/Unit/ILSDriverTestCase.php
+++ b/module/VuFind/src/VuFindTest/Unit/ILSDriverTestCase.php
@@ -51,10 +51,11 @@ abstract class ILSDriverTestCase extends TestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\ILS
      */
     public function testMissingConfiguration()
     {
+        $this->expectException(\VuFind\Exception\ILS::class);
+
         $this->driver->init();
     }
 }
diff --git a/module/VuFind/src/VuFindTest/Unit/MinkTestCase.php b/module/VuFind/src/VuFindTest/Unit/MinkTestCase.php
index 671fe354be655fd3ca77cf5d6616764d38bebd2b..df3025e53799c62f052dbfa745d1f233190a7320 100644
--- a/module/VuFind/src/VuFindTest/Unit/MinkTestCase.php
+++ b/module/VuFind/src/VuFindTest/Unit/MinkTestCase.php
@@ -362,11 +362,12 @@ abstract class MinkTestCase extends DbTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
 
         // Reset the modified configs list.
@@ -378,7 +379,7 @@ abstract class MinkTestCase extends DbTestCase
      *
      * @return void
      */
-    public function tearDown()
+    public function tearDown(): void
     {
         $this->stopMinkSession();
         $this->restoreConfigs();
@@ -389,7 +390,7 @@ abstract class MinkTestCase extends DbTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         // No teardown actions at this time.
     }
diff --git a/module/VuFind/src/VuFindTest/Unit/MockContainerTest.php b/module/VuFind/src/VuFindTest/Unit/MockContainerTest.php
index 995f5b1073ff8d6d8c64ccffc4b1bf1dc00a081d..6d50e19975011f761954e09be20a2c20348e9415 100644
--- a/module/VuFind/src/VuFindTest/Unit/MockContainerTest.php
+++ b/module/VuFind/src/VuFindTest/Unit/MockContainerTest.php
@@ -52,7 +52,7 @@ abstract class MockContainerTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->container = new MockContainer($this);
     }
diff --git a/module/VuFind/src/VuFindTest/Unit/UserCreationTrait.php b/module/VuFind/src/VuFindTest/Unit/UserCreationTrait.php
index 7e7477ccb72189b22e4c33ebe7b200fe94552e8e..7959b0c20a487820cfc4cf5081b4351a99c2ff54 100644
--- a/module/VuFind/src/VuFindTest/Unit/UserCreationTrait.php
+++ b/module/VuFind/src/VuFindTest/Unit/UserCreationTrait.php
@@ -47,9 +47,9 @@ trait UserCreationTrait
      * Static setup support function to fail if users already exist in the database.
      * We want to ensure a clean state for each test!
      *
-     * @return mixed
+     * @return void
      */
-    protected static function failIfUsersExist()
+    protected static function failIfUsersExist(): void
     {
         // If CI is not running, all tests were skipped, so no work is necessary:
         $test = new static();   // create instance of current class
@@ -60,9 +60,10 @@ trait UserCreationTrait
         // on a real system -- it's only meant for the continuous integration server)
         $userTable = $test->getTable('User');
         if (count($userTable->select()) > 0) {
-            return self::fail(
+            self::fail(
                 'Test cannot run with pre-existing user data!'
             );
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/DatabaseTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/DatabaseTest.php
index ce187cdeaab304f3fb7035a6525a2866052eef3e..02004a41beec53d776ffbaa3600d7351fc0be1d0 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/DatabaseTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/DatabaseTest.php
@@ -52,11 +52,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -64,11 +64,12 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
         $this->auth = $this->getAuthManager()->get('Database');
     }
@@ -137,10 +138,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testCreationWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getAccountCreationRequest(['username' => '']);
         $this->auth->create($request);
     }
@@ -150,10 +152,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testCreationWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getAccountCreationRequest(['password' => '']);
         $this->auth->create($request);
     }
@@ -163,10 +166,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testCreationWithPasswordMismatch()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getAccountCreationRequest(['password2' => '']);
         $this->auth->create($request);
     }
@@ -176,10 +180,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testCreationWithInvalidEmail()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getAccountCreationRequest(['email' => 'garbage']);
         $this->auth->create($request);
     }
@@ -206,10 +211,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testCreationWithDuplicateUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getAccountCreationRequest(['email' => 'user2@test.com']);
         $this->auth->create($request);
     }
@@ -219,10 +225,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testCreationWithDuplicateEmail()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getAccountCreationRequest(['username' => 'testuser2']);
         $this->auth->create($request);
     }
@@ -232,10 +239,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => '']);
         $this->auth->authenticate($request);
     }
@@ -245,10 +253,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => '']);
         $this->auth->authenticate($request);
     }
@@ -258,10 +267,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithUnrecognizedUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => 'unknown']);
         $this->auth->authenticate($request);
     }
@@ -271,10 +281,11 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBadPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => "' OR 1=1 LIMIT 1"]);
         $this->auth->authenticate($request);
     }
@@ -296,7 +307,7 @@ class DatabaseTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers('testuser');
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ILSTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ILSTest.php
index d93d89382ee57191922354c4959f20c77074a00f..acc429c582b917432dd821f9c76085f3002f4719 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ILSTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ILSTest.php
@@ -47,11 +47,11 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -59,11 +59,12 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -152,10 +153,11 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => '']);
         $this->getAuth()->authenticate($request);
     }
@@ -165,10 +167,11 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => '']);
         $this->getAuth()->authenticate($request);
     }
@@ -178,10 +181,11 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testBadLoginResponse()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         // VuFind requires the ILS driver to return a value in cat_username
         // by default -- if that is missing, we should fail.
         $response = [];
@@ -217,11 +221,12 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage authentication_error_technical
      */
     public function testLoginWithMissingCatId()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('authentication_error_technical');
+
         $response = [
             'cat_username' => 'testuser', 'cat_password' => 'testpass',
             'email' => 'user@test.com'
@@ -243,11 +248,12 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage Password cannot be blank
      */
     public function testUpdateUserPasswordWithEmptyValue()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('Password cannot be blank');
+
         $patron = ['cat_username' => 'testuser'];
         $request = $this->getLoginRequest(
             [
@@ -264,11 +270,12 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage authentication_error_technical
      */
     public function testUpdateUserPasswordWithoutLoggedInUser()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('authentication_error_technical');
+
         $request = $this->getLoginRequest(
             [
                 'oldpwd' => 'foo',
@@ -284,11 +291,12 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage Passwords do not match
      */
     public function testUpdateUserPasswordWithMismatch()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('Passwords do not match');
+
         $request = $this->getLoginRequest(
             [
                 'oldpwd' => 'foo',
@@ -354,7 +362,7 @@ class ILSTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['1234', 'testuser']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ShibbolethTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ShibbolethTest.php
index d92f1398dcffbefb62e9a5f269b9db8d9306694d..4affd469b963ea17b4abf6a660f701c8b5a8b00e 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ShibbolethTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Auth/ShibbolethTest.php
@@ -46,11 +46,11 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -58,11 +58,12 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -138,10 +139,11 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => '']);
         $this->getAuthObject()->authenticate($request);
     }
@@ -151,10 +153,11 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => '']);
         $this->getAuthObject()->authenticate($request);
     }
@@ -164,10 +167,11 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithMissingAttributeValue()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->Shibboleth->userattribute_value_1);
         $this->getAuthObject($config)->authenticate($this->getLoginRequest());
@@ -178,10 +182,11 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithoutUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->Shibboleth->username);
         $this->getAuthObject($config)->authenticate($this->getLoginRequest());
@@ -192,10 +197,11 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithoutLoginSetting()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->Shibboleth->login);
         $this->getAuthObject($config)->getSessionInitiator('http://target');
@@ -231,7 +237,7 @@ class ShibbolethTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers('testuser');
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrAuthTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrAuthTest.php
index 640542685d14bb716ac10f9953b46788e3e151ff..0321cc1974213f3d6a17cf0545cd5c5f7903351b 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrAuthTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrAuthTest.php
@@ -45,11 +45,12 @@ class SolrAuthTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrTest.php
index af6c4b71a71bbb34bdfefd0b01405cc65959e92b..6d375baae902fb324291eda3ad0d2a38d33201b9 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Connection/SolrTest.php
@@ -45,11 +45,12 @@ class SolrTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Db/Table/ChangeTrackerTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Db/Table/ChangeTrackerTest.php
index 55462d130e8ff88237f045a4e58761d850dd4f67..400ed4476e2a023bc086e03807063b29ac0b82ff 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Db/Table/ChangeTrackerTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Db/Table/ChangeTrackerTest.php
@@ -45,11 +45,12 @@ class ChangeTrackerTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountActionsTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountActionsTest.php
index 01fefbb74d81f29822a65e64e9b2851eb903a320..9ea461aa89054db88d06ef49d8d61c7b597a69cd 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountActionsTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountActionsTest.php
@@ -45,11 +45,11 @@ class AccountActionsTest extends \VuFindTest\Unit\MinkTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -57,11 +57,12 @@ class AccountActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -221,7 +222,7 @@ class AccountActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php
index 30c779077d5bce52fd204cdeaaf26ee14d3aee68..d2d413ecc24200661ea332cf6b1e0161be67cfa9 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php
@@ -46,11 +46,11 @@ class AccountMenuTest extends \VuFindTest\Unit\MinkTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -58,11 +58,12 @@ class AccountMenuTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
         // Setup config
         $this->changeConfigs([
@@ -446,7 +447,7 @@ class AccountMenuTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BulkTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BulkTest.php
index c27b0c9e8f489040de3f71045f6f9503878c8667..6766c39c227446cf7ce2e746350ef9e06ecee21c 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BulkTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BulkTest.php
@@ -47,11 +47,11 @@ class BulkTest extends \VuFindTest\Unit\MinkTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -290,7 +290,7 @@ class BulkTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers('username1');
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CallnumberBrowseTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CallnumberBrowseTest.php
index 97896df502f4b58f9c14f6c736f79bf28b26a4fa..5dc9de0a2e032ebd0ea0cc59cdc5f44862b2e441 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CallnumberBrowseTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CallnumberBrowseTest.php
@@ -53,11 +53,12 @@ class CallnumberBrowseTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -99,9 +100,9 @@ class CallnumberBrowseTest extends \VuFindTest\Unit\MinkTestCase
     {
         $this->assertTrue(is_object($link));
         $href = $link->getAttribute('href');
-        $this->assertContains($type, $href);
+        $this->assertStringContainsString($type, $href);
         $this->assertNotEquals('', $link->getText());
-        $this->assertContains($link->getText(), $href);
+        $this->assertStringContainsString($link->getText(), $href);
     }
 
     protected function setupMultipleCallnumbers()
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php
index 60155c12a27d9824b4d53dec7e7834bd783df29f..48efd44c7229380d7219d56c9bd9efed8bd6407c 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php
@@ -47,11 +47,11 @@ class CartTest extends \VuFindTest\Unit\MinkTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -801,7 +801,7 @@ class CartTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers('username1');
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ChoiceAuthTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ChoiceAuthTest.php
index 9cf1cdd90ccafe3d7e98f3eb5d299f4e12f1883a..b6575dc74c492cb95f18c2eee2dbb5cd2e37efc0 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ChoiceAuthTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ChoiceAuthTest.php
@@ -47,9 +47,9 @@ class ChoiceAuthTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -57,11 +57,12 @@ class ChoiceAuthTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -181,7 +182,7 @@ class ChoiceAuthTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1', 'catuser']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FavoritesTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FavoritesTest.php
index 26e2767c2d0566d803ba36a3ed30214d96c47b59..61d9177dd9d1187ecb617d36671107561ce98b88 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FavoritesTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FavoritesTest.php
@@ -47,11 +47,11 @@ class FavoritesTest extends \VuFindTest\Unit\MinkTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -59,11 +59,12 @@ class FavoritesTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -629,7 +630,7 @@ class FavoritesTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1', 'username2']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FeedbackTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FeedbackTest.php
index 42e1df94789997aefc56877613314a28b480087e..4af18df2b1a6a66a81986b88f9387ac8dc864bd0 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FeedbackTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/FeedbackTest.php
@@ -48,11 +48,12 @@ class FeedbackTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/IlsActionsTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/IlsActionsTest.php
index d38774fcceeed6ca6348417fa1797d055484b915..8e68d5fb8b167d79869e48a6520685910fef4065 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/IlsActionsTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/IlsActionsTest.php
@@ -50,9 +50,9 @@ class IlsActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -60,11 +60,12 @@ class IlsActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -566,7 +567,7 @@ class IlsActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1', 'username2']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php
index a188b4674c152aadc5f80ca229f777377fffc104..d60552654f4fd419eee90e1e0e875518aef3ac14 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php
@@ -48,11 +48,12 @@ class LinkResolverTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ListViewsTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ListViewsTest.php
index 28260bc8075d5d662fbf15763fc36c089c759fe4..37b9f30d1ee3d7e745c3ffd9caebfc50fe138a2c 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ListViewsTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/ListViewsTest.php
@@ -47,11 +47,11 @@ class ListViewsTest extends \VuFindTest\Unit\MinkTestCase
     /**
      * Standard setup method.
      *
-     * @return mixed
+     * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -59,11 +59,12 @@ class ListViewsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -245,7 +246,7 @@ class ListViewsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/NextPrevNavTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/NextPrevNavTest.php
index 8b33761f4117df6b0d12e10a59bd32634971c4b1..0d12af5060298ac691250e0f06cea4feb6f8cbf3 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/NextPrevNavTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/NextPrevNavTest.php
@@ -65,6 +65,6 @@ class NextPrevNavTest extends \VuFindTest\Unit\MinkTestCase
         $session->visit($this->getVuFindUrl() . "/Record/geo20001");
 
         // should fail if exception is thrown
-        $this->assertContains("Test Publication 20001", $this->findCss($page, "div.media-body > h1[property=name]")->getText());
+        $this->assertStringContainsString("Test Publication 20001", $this->findCss($page, "div.media-body > h3[property=name]")->getText());
     }
 }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/RecordActionsTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/RecordActionsTest.php
index 3835313dcb47347ae98012d3057a2d7e97b706ed..dca04a80d8381195cf932084e3cae53829896255 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/RecordActionsTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/RecordActionsTest.php
@@ -47,9 +47,9 @@ class RecordActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -57,11 +57,12 @@ class RecordActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -452,7 +453,7 @@ class RecordActionsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1', 'username2', 'emailmaniac']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SavedSearchesTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SavedSearchesTest.php
index f63e4ddca411e231b4c14b1962c47dc29f1fdb36..d1423204d8945d68bbea4ee03a4883438ca537e7 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SavedSearchesTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SavedSearchesTest.php
@@ -47,9 +47,9 @@ class SavedSearchesTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
-        return static::failIfUsersExist();
+        static::failIfUsersExist();
     }
 
     /**
@@ -57,11 +57,12 @@ class SavedSearchesTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
@@ -263,7 +264,7 @@ class SavedSearchesTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         static::removeUsers(['username1', 'username2']);
     }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SearchFacetsTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SearchFacetsTest.php
index e469283c2cc858aa2416bec93ca6eab93c11dfb6..3bc917c01ba9961c47eaf36bc9e6b2a56b911a3c 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SearchFacetsTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/SearchFacetsTest.php
@@ -53,11 +53,12 @@ class SearchFacetsTest extends \VuFindTest\Unit\MinkTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/VisualizationTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/VisualizationTest.php
index 8861230498164d456178518a983cfbb13672b792..d0d1bfa977bafa8db6851eff955240ed6eddf7b4 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/VisualizationTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/VisualizationTest.php
@@ -68,6 +68,6 @@ class VisualizationTest extends \VuFindTest\Unit\MinkTestCase
         $text = $this->findCss($page, '#visualResults')->getText();
         // Confirm that some content has been dynamically loaded into the
         // visualization area:
-        $this->assertContains('A - General Works', $text);
+        $this->assertStringContainsString('A - General Works', $text);
     }
 }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/View/Helper/Root/ResultFeedTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/View/Helper/Root/ResultFeedTest.php
index f5646150fda616ec31eafd54f04e69fb1e6aa139..2ef78a9997e76496275f8f7566f9b118850bfe6c 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/View/Helper/Root/ResultFeedTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/View/Helper/Root/ResultFeedTest.php
@@ -45,11 +45,12 @@ class ResultFeedTest extends \VuFindTest\Unit\ViewHelperTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Give up if we're not running in CI:
         if (!$this->continuousIntegrationRunning()) {
-            return $this->markTestSkipped('Continuous integration not running.');
+            $this->markTestSkipped('Continuous integration not running.');
+            return;
         }
     }
 
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ChoiceAuthTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ChoiceAuthTest.php
index b38066da576f5fa04cc70dae2f493309e1998519..74708d2df3f74b147bacc98550bbfc92aa9c5f63 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ChoiceAuthTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ChoiceAuthTest.php
@@ -49,11 +49,12 @@ class ChoiceAuthTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \VuFind\Exception\Auth
-     * @expectedExceptionMessage One or more ChoiceAuth parameters are missing.
      */
     public function testBadConfiguration()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('One or more ChoiceAuth parameters are missing.');
+
         $ca = new ChoiceAuth($this->getSessionContainer());
         $ca->setConfig(new Config([]));
     }
@@ -63,11 +64,12 @@ class ChoiceAuthTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Plugin manager missing.
      */
     public function testMissingPluginManager()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Plugin manager missing.');
+
         $ca = new ChoiceAuth($this->getSessionContainer());
         $ca->getPluginManager();
     }
@@ -179,11 +181,12 @@ class ChoiceAuthTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Illegal setting: foo
      */
     public function testIllegalMethod()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Illegal setting: foo');
+
         $request = new Request();
         $request->getQuery()->set('auth_method', 'foo');
         $ca = $this->getChoiceAuth();
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/DatabaseUnitTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/DatabaseUnitTest.php
index e2d2b85d3f33782e08f2804d3c2e12c209107741..8f82fb61dbce231de56370d9d3121a03d967b18a 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/DatabaseUnitTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/DatabaseUnitTest.php
@@ -47,11 +47,12 @@ class DatabaseUnitTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage Username cannot be blank
      */
     public function testEmptyCreateRequest()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('Username cannot be blank');
+
         $db = new Database();
         $db->create($this->getRequest());
     }
@@ -61,11 +62,12 @@ class DatabaseUnitTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage Password cannot be blank
      */
     public function testEmptyPasswordCreateRequest()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('Password cannot be blank');
+
         $db = new Database();
         $arr = $this->getCreateParams();
         $arr['password'] = $arr['password2'] = '';
@@ -77,11 +79,12 @@ class DatabaseUnitTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage Passwords do not match
      */
     public function testMismatchedPasswordCreateRequest()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('Passwords do not match');
+
         $db = new Database();
         $arr = $this->getCreateParams();
         $arr['password2'] = 'bad';
@@ -93,11 +96,12 @@ class DatabaseUnitTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage DB table manager missing.
      */
     public function testCreateWithMissingTableManager()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('DB table manager missing.');
+
         $db = new Database();
         $db->create($this->getRequest($this->getCreateParams()));
     }
@@ -107,11 +111,12 @@ class DatabaseUnitTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage That email address is already used
      */
     public function testCreateDuplicateEmail()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('That email address is already used');
+
         // Fake services:
         $table = $this->getMockTable(['getByEmail', 'getByUsername']);
         $table->expects($this->once())->method('getByEmail')
@@ -131,11 +136,12 @@ class DatabaseUnitTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Auth
-     * @expectedExceptionMessage That username is already taken
      */
     public function testCreateDuplicateUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('That username is already taken');
+
         // Fake services:
         $table = $this->getMockTable(['getByUsername']);
         $table->expects($this->any())->method('getByUsername')
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ILSAuthenticatorTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ILSAuthenticatorTest.php
index 77ea52b3e29025f6b9152bd36b2972139b3d5dc7..3f7cf1d80a6cb7e5a8ba1e284042b9bc6a6ee23e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ILSAuthenticatorTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ILSAuthenticatorTest.php
@@ -83,11 +83,12 @@ class ILSAuthenticatorTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\ILS
-     * @expectedExceptionMessage kaboom
      */
     public function testNewCatalogFailureByException()
     {
+        $this->expectException(\VuFind\Exception\ILS::class);
+        $this->expectExceptionMessage('kaboom');
+
         $manager = $this->getMockManager();
         $connection = $this->getMockConnection(['patronLogin']);
         $connection->expects($this->once())->method('patronLogin')->with($this->equalTo('user'), $this->equalTo('pass'))->will($this->throwException(new \VuFind\Exception\ILS('kaboom')));
@@ -157,11 +158,12 @@ class ILSAuthenticatorTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\ILS
-     * @expectedExceptionMessage kaboom
      */
     public function testExceptionDuringStoredLoginAttempt()
     {
+        $this->expectException(\VuFind\Exception\ILS::class);
+        $this->expectExceptionMessage('kaboom');
+
         $user = $this->getMockUser(['__get', '__isset', 'clearCredentials', 'getCatPassword']);
         $user->expects($this->any())->method('__get')->with($this->equalTo('cat_username'))->will($this->returnValue('user'));
         $user->expects($this->any())->method('__isset')->with($this->equalTo('cat_username'))->will($this->returnValue(true));
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/LDAPTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/LDAPTest.php
index 855ffe854b8a062449ff50d0cc8bf9cd87098181..6d0ead39f37385d29c2ec672dc8638c56f96f0e7 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/LDAPTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/LDAPTest.php
@@ -81,10 +81,11 @@ class LDAPTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithMissingHost()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->LDAP->host);
         $this->getAuthObject($config)->getConfig();
@@ -95,10 +96,11 @@ class LDAPTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithMissingPort()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->LDAP->port);
         $this->getAuthObject($config)->getConfig();
@@ -109,10 +111,11 @@ class LDAPTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithMissingBaseDN()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->LDAP->basedn);
         $this->getAuthObject($config)->getConfig();
@@ -123,10 +126,11 @@ class LDAPTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithMissingUid()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->LDAP->username);
         $this->getAuthObject($config)->getConfig();
@@ -188,10 +192,11 @@ class LDAPTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => '']);
         $this->getAuthObject()->authenticate($request);
     }
@@ -201,10 +206,11 @@ class LDAPTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => '']);
         $this->getAuthObject()->authenticate($request);
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ManagerTest.php
index ec66ea344099f020db77edbbc0cd6f08431175cb..30b85dc7ffabb8548a7d7d7a46e43f089564b757 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/ManagerTest.php
@@ -200,11 +200,12 @@ class ManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Illegal authentication method: MultiILS
      */
     public function testSwitchingFailure()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Illegal authentication method: MultiILS');
+
         $config = ['Authentication' => ['method' => 'ChoiceAuth']];
         $manager = $this->getManager($config);
         $this->assertEquals('ChoiceAuth', $manager->getAuthMethod());
@@ -358,11 +359,12 @@ class ManagerTest extends \VuFindTest\Unit\TestCase
      * Test CSRF failure (same setup as successful login, but minus token)
      *
      * @return void
-     * @expectedException        \VuFind\Exception\Auth
-     * @expectedExceptionMessage authentication_error_technical
      */
     public function testMissingCsrf()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('authentication_error_technical');
+
         $user = $this->getMockUser();
         $request = $this->getMockRequest();
         $pm = $this->getMockPluginManager();
@@ -374,11 +376,12 @@ class ManagerTest extends \VuFindTest\Unit\TestCase
      * Test CSRF failure (same setup as successful login, but with bad token)
      *
      * @return void
-     * @expectedException        \VuFind\Exception\Auth
-     * @expectedExceptionMessage authentication_error_technical
      */
     public function testIncorrectCsrf()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('authentication_error_technical');
+
         $user = $this->getMockUser();
         $request = $this->getMockRequest();
         $pm = $this->getMockPluginManager();
@@ -392,11 +395,12 @@ class ManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \VuFind\Exception\PasswordSecurity
-     * @expectedExceptionMessage Boom
      */
     public function testPasswordSecurityException()
     {
+        $this->expectException(\VuFind\Exception\PasswordSecurity::class);
+        $this->expectExceptionMessage('Boom');
+
         $e = new \VuFind\Exception\PasswordSecurity('Boom');
         $request = $this->getMockRequest();
         $pm = $this->getMockPluginManager();
@@ -412,11 +416,12 @@ class ManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \VuFind\Exception\Auth
-     * @expectedExceptionMessage Blam
      */
     public function testAuthException()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('Blam');
+
         $e = new \VuFind\Exception\Auth('Blam');
         $request = $this->getMockRequest();
         $pm = $this->getMockPluginManager();
@@ -432,11 +437,12 @@ class ManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \VuFind\Exception\Auth
-     * @expectedExceptionMessage authentication_error_technical
      */
     public function testUnanticipatedException()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+        $this->expectExceptionMessage('authentication_error_technical');
+
         $e = new \Exception('It is normal to see this in the error log during testing...');
         $request = $this->getMockRequest();
         $pm = $this->getMockPluginManager();
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/MultiAuthTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/MultiAuthTest.php
index 24d3f1a26c47f076c7624649a20821e465ec3694..8fccaa13eaf3e4f48aaae757b857d7fb11383fd0 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/MultiAuthTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/MultiAuthTest.php
@@ -79,10 +79,11 @@ class MultiAuthTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testWithMissingMethodOrder()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $config = $this->getAuthConfig();
         unset($config->MultiAuth->method_order);
         $this->getAuthObject($config)->getConfig();
@@ -111,10 +112,11 @@ class MultiAuthTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException Zend\ServiceManager\Exception\ServiceNotFoundException
      */
     public function testLoginWithBadService()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\ServiceNotFoundException::class);
+
         $config = $this->getAuthConfig();
         $config->MultiAuth->method_order = 'InappropriateService,Database';
 
@@ -129,10 +131,11 @@ class MultiAuthTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException Zend\ServiceManager\Exception\InvalidServiceException
      */
     public function testLoginWithBadClass()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+
         $config = $this->getAuthConfig();
         $config->MultiAuth->method_order = get_class($this) . ',Database';
 
@@ -145,10 +148,11 @@ class MultiAuthTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => '']);
         $this->getAuthObject()->authenticate($request);
     }
@@ -158,10 +162,11 @@ class MultiAuthTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => '']);
         $this->getAuthObject()->authenticate($request);
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/PluginManagerTest.php
index e82670cbf903da9d8e9a0417de7f26bbc0a181ef..106547e0a8ad631f0e96fe4f2f10bab4b52240ee 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Auth\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Auth\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/SIP2Test.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/SIP2Test.php
index 47961b07b2111d3f666f1d92813b1d4e064a4fba..f1e1f1331740239a184fa8151832885f4ff4d27e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/SIP2Test.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Auth/SIP2Test.php
@@ -97,10 +97,11 @@ class SIP2Test extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankUsername()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['username' => '']);
         $this->getAuthObject()->authenticate($request);
     }
@@ -110,10 +111,11 @@ class SIP2Test extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\Auth
      */
     public function testLoginWithBlankPassword()
     {
+        $this->expectException(\VuFind\Exception\Auth::class);
+
         $request = $this->getLoginRequest(['password' => '']);
         $this->getAuthObject()->authenticate($request);
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/PluginManagerTest.php
index 24c3016e8fef315a4e5888d6cf9ab2c5839ea74f..a9969abb1a7be9ecc36e32e723ed07a0053d3061 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Autocomplete\AutocompleteInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Autocomplete\\AutocompleteInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/TagTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/TagTest.php
index 00dcc4af575be984645a96ec01e824c098d3dfd8..1b7ed9c4b9fbf0720006fdd5fbada22138268b94 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/TagTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Autocomplete/TagTest.php
@@ -45,11 +45,12 @@ class TagTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage DB table manager missing.
      */
     public function testMissingDependency()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('DB table manager missing.');
+
         $tag = new Tag();
         $tag->getSuggestions('foo');
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/CartTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/CartTest.php
index 756a517751c1b744d9f4575bf51cff8d10ba00df..88c53c6c02403aa4521ce26a320abc384e9c26c4 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/CartTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/CartTest.php
@@ -52,7 +52,7 @@ class CartTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->loader = $this->getMockBuilder(\VuFind\Record\Loader::class)
             ->setMethods([])
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/PluginFactoryTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/PluginFactoryTest.php
index 0c5250109b3ef9a1869c12cae98634e37ec2566a..b07963d00ec8d39fc6bd3d7fefa8c4f3bf57637d 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/PluginFactoryTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/PluginFactoryTest.php
@@ -67,7 +67,7 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
         // Create test files:
         $parentPath = Locator::getLocalConfigPath('unit-test-parent.ini', null, true);
@@ -120,7 +120,7 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->factory = new \VuFind\Config\PluginFactory();
     }
@@ -236,7 +236,7 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
      * Test that the plugin factory omits the Parent_Config section from the
      * merged configuration.
      *
-     * @void
+     * @return void
      */
     public function testParentConfigOmission()
     {
@@ -252,10 +252,11 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException Zend\Config\Exception\RuntimeException
      */
     public function testReadOnlyConfig()
     {
+        $this->expectException(\Zend\Config\Exception\RuntimeException::class);
+
         if (self::$writeFailed) {
             $this->markTestSkipped('Could not write test configurations.');
         }
@@ -268,7 +269,7 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         // Clean up test files:
         array_map('unlink', self::$filesToDelete);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php
index 1571d1990d880d58683ce58ee812a33647dba679..ca4ebc4821012c75e5094961e88ce7b932018ce6 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php
@@ -61,7 +61,7 @@ class SearchSpecsReaderTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
         // Create test files:
         $parentPath = Locator::getLocalConfigPath('top.yaml', null, true);
@@ -188,7 +188,7 @@ class SearchSpecsReaderTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         // Clean up test files:
         array_map('unlink', self::$filesToDelete);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/VersionTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/VersionTest.php
index 12ef1994a0a43e42176d99f06eadbd692d1e44c1..1ef2547b9cf7d4c652c89a87d35e7d72db87d4bf 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/VersionTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/VersionTest.php
@@ -60,11 +60,12 @@ class VersionTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Cannot load /will/never/exist/ever/ever/build.xml.
      */
     public function testMissingFile()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Cannot load /will/never/exist/ever/ever/build.xml.');
+
         Version::getBuildVersion('/will/never/exist/ever/ever');
     }
 
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/AuthorNotes/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/AuthorNotes/PluginManagerTest.php
index 42fcd571553f420cc2d8b47b2d035e81930136f2..e032ed4d80905a4654fe52a2e01f6e306023150a 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/AuthorNotes/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/AuthorNotes/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Content\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Content\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/PluginManagerTest.php
index 1fa58849f1030619d36d907cc662ef99ead7c080..36a92613b023855a4d35585d4403e6c11227479e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Content\AbstractCover
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Content\\AbstractCover');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Excerpts/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Excerpts/PluginManagerTest.php
index 3472a32850a73a320e636bca90d0effdbf3fbcd9..233d3e515e6c3611f61eb435d8c71cbc61251d98 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Excerpts/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Excerpts/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Content\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Content\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/PluginManagerTest.php
index 8d42bbe68dfa0da7bdf355b83735c5bc058c8e80..35fe3b7ff79b2f8c15b7f3492fcfd0896bd32284 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Content\Loader
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Content\\Loader');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Reviews/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Reviews/PluginManagerTest.php
index 7bd4ea03659f0b4ec2bcacbfec4542caebcb3373..580ef954b81706c7f308d220d3b7a31c4609af76 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Reviews/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Reviews/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Content\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Content\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Cookie/ContainerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Cookie/ContainerTest.php
index c6ada1dd2879be23649ae6cad48bdf94c7c07792..552870285ce0c8959d77af69c4e677e670f5d81e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Cookie/ContainerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Cookie/ContainerTest.php
@@ -47,7 +47,7 @@ class ContainerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setup()
+    public function setUp(): void
     {
         $this->container = new Container('test');
     }
@@ -57,7 +57,7 @@ class ContainerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function tearDown()
+    public function tearDown(): void
     {
         foreach ($this->container->getAllValues() as $k => $v) {
             unset($this->container->$k);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Cover/LoaderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Cover/LoaderTest.php
index 163f17835e36c395c7bdf24406ac21facddef1ee..7146a608274386e4ddc9b1648536c5f699850720 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Cover/LoaderTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Cover/LoaderTest.php
@@ -54,11 +54,12 @@ class LoaderTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Could not load default fail image.
      */
     public function testUtterFailure()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Could not load default fail image.');
+
         $theme = $this->getMockBuilder(\VuFindTheme\ThemeInfo::class)
             ->setConstructorArgs(['foo', 'bar'])->getMock();
         $theme->expects($this->once())->method('findContainingTheme')->with($this->equalTo(['images/noCover2.gif']))->will($this->returnValue(false));
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/PluginManagerTest.php
index 529a1781056b6dfd68ac2f70d875eb2300f5dd7f..73b6f28dbfbb15f4a0df3a7cba3ce1d79543853e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Db\Table\Gateway
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Db\\Table\\Gateway');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/UserListTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/UserListTest.php
index 2eb49650aab0f38c545db55929335d9783ac0f4c..b185d07ecbfd66447c2fe7ea63a4845338dc941f 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/UserListTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Db/Table/UserListTest.php
@@ -46,10 +46,11 @@ class UserListTest extends \VuFindTest\Unit\DbTestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\LoginRequired
      */
     public function testLoginRequiredToCreateList()
     {
+        $this->expectException(\VuFind\Exception\LoginRequired::class);
+
         $table = $this->getTable('UserList');
         $list = $table->getNew(false);
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/DoiLinker/UnpaywallTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/DoiLinker/UnpaywallTest.php
index f04a453e305340522b0dee5badb29775aabf12f1..1d6d1539a014039551cb0194fbceaee86d5cb139 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/DoiLinker/UnpaywallTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/DoiLinker/UnpaywallTest.php
@@ -47,11 +47,12 @@ class UnpaywallTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Missing configuration for Unpaywall DOI linker: unpaywall_email
      */
     public function testConfigValidation()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Missing configuration for Unpaywall DOI linker: unpaywall_email');
+
         new Unpaywall(new \Zend\Config\Config([]));
     }
 
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Form/FormTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Form/FormTest.php
index 0706f6ad9ae430e729309f22ea9f07dc2a2b89c2..036362b6ffeb4bb574cbafa3cb924f3e9ace5716 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Form/FormTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Form/FormTest.php
@@ -92,11 +92,12 @@ class FormTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\RecordMissing
-     * @expectedExceptionMessage Form 'foo' not found
      */
     public function testUndefinedFormId()
     {
+        $this->expectException(\VuFind\Exception\RecordMissing::class);
+        $this->expectExceptionMessage('Form \'foo\' not found');
+
         $form = new Form(new YamlReader());
         $form->setFormId('foo');
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/Driver/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/Driver/PluginManagerTest.php
index c107beec8677a662ecedba35175362cac7348830..934978b2b86b9fff0e0f607933f87d1dbc486521 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/Driver/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/Driver/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Hierarchy\Driver\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Hierarchy\\Driver\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeDataSource/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeDataSource/PluginManagerTest.php
index 49bd6222b0d609f4a7d58e659b5a8dec99f66f9b..c51395ee0a3d357ae94c082a14148c992f4fc92d 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeDataSource/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeDataSource/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Hierarchy\TreeDataSource\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Hierarchy\\TreeDataSource\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeRenderer/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeRenderer/PluginManagerTest.php
index d9d9db51281da279ab9fe81bc068c49071f4aa47..193c7a6b6736c3c6e34a55423d2dc4488f8e63ab 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeRenderer/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Hierarchy/TreeRenderer/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Hierarchy\TreeRenderer\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Hierarchy\\TreeRenderer\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php
index 25799d6672db52d478ee649f6228921935c6979a..7bf0b35cf99fa603db61dfd5c3923cf23b9325d6 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php
@@ -158,11 +158,12 @@ class ExtendedIniTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\I18n\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Ini file 'en.ini' not found
      */
     public function testMissingPathStack()
     {
+        $this->expectException(\Zend\I18n\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Ini file \'en.ini\' not found');
+
         $loader = new ExtendedIni();
         $loader->load('en', null);
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AlephTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AlephTest.php
index 8126dff8e8abc93f7d765c1a40ecb95a3cbf9e5b..05162d0ec9f410607e4dba6b1f0f53d6740c16ab 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AlephTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AlephTest.php
@@ -45,7 +45,7 @@ class AlephTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Aleph(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AmicusTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AmicusTest.php
index 9d0555b006ee2493c307c9bd5f1bb4319bd56524..354f3921b604d8cd90467def54b6189f9b790df5 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AmicusTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/AmicusTest.php
@@ -45,7 +45,7 @@ class AmicusTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Amicus();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DAIATest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DAIATest.php
index c1850ee7d630506b6afce9a00fb9c818b208ee65..c278d8344950f999b894da420d3bce878be205e9 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DAIATest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DAIATest.php
@@ -141,7 +141,7 @@ class DAIATest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = $this->createConnector();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DemoTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DemoTest.php
index 9f94c7867a817af1a2c0ee28219fe981082e1acf..e657a9749d89c8590f3575cff8f4ac766d1c50ab 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DemoTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/DemoTest.php
@@ -52,7 +52,7 @@ class DemoTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $session = $this->getMockBuilder(\Zend\Session\Container::class)
             ->disableOriginalConstructor()->getMock();
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/EvergreenTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/EvergreenTest.php
index 13a1f98a08ac58ebec6d6210e5b699cce55dbaff..4c17bfae12bbb74087f6fca775e81eae205d19c3 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/EvergreenTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/EvergreenTest.php
@@ -45,7 +45,7 @@ class EvergreenTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Evergreen();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonTest.php
index 195293e333f327e364997b1c4af58a476b20ee90..54ab0018fae07a6248fa95624e645058b957b273 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonTest.php
@@ -45,7 +45,7 @@ class HorizonTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Horizon(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonXMLAPITest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonXMLAPITest.php
index 0f1dfba14a3f83e6339cec525bdeb741d20a83bc..23eaf056b482bd2ac3dd8b9ae68a3dee7ba7ee95 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonXMLAPITest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/HorizonXMLAPITest.php
@@ -45,7 +45,7 @@ class HorizonXMLAPITest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new HorizonXMLAPI(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/InnovativeTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/InnovativeTest.php
index bf4f803cf02fbe396a59d54a9b99b483339c1794..a16322836294db8ccdb31488ccb74dbcb1bc683d 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/InnovativeTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/InnovativeTest.php
@@ -45,7 +45,7 @@ class InnovativeTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Innovative();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/KohaTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/KohaTest.php
index af5838dc422f0f48ce5a7afb95cc17a1c73ee602..e1041df92bcde58ee24449766b8b0e15f9ce6063 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/KohaTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/KohaTest.php
@@ -45,7 +45,7 @@ class KohaTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Koha(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/MultiBackendTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/MultiBackendTest.php
index b24510e4e5058038989c29c8daa2e695bfafbffd..7b31f319ed9ed8ad3dfee2c6e33368b43f427d6a 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/MultiBackendTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/MultiBackendTest.php
@@ -49,10 +49,11 @@ class MultiBackendTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException VuFind\Exception\ILS
      */
     public function testMissingConfiguration()
     {
+        $this->expectException(\VuFind\Exception\ILS::class);
+
         $test = new MultiBackend(
             new \VuFind\Config\PluginManager($this->getServiceManager()),
             $this->getMockILSAuthenticator(),
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NewGenLibTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NewGenLibTest.php
index e7951bedd699afdebfcad9f59a38e19cb1f630a1..c1ed90befbb6f92871361aeae233bf314fa80707 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NewGenLibTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NewGenLibTest.php
@@ -45,7 +45,7 @@ class NewGenLibTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new NewGenLib();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NoILSTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NoILSTest.php
index 0e36604525e0873839bdce9b57237ed0a419ede8..066b9dc0e8c63859b7b71bdc73a9fc03e7b5b036 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NoILSTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/NoILSTest.php
@@ -59,7 +59,7 @@ class NoILSTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->loader = $this->getMockBuilder(\VuFind\Record\Loader::class)
             ->setConstructorArgs(
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PAIATest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PAIATest.php
index 20e0e523d656e6a10644faf1a92ffaa8808ce6a3..d2034039a462f4fb640d05a942be6cffdcf5560e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PAIATest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PAIATest.php
@@ -339,7 +339,7 @@ class PAIATest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = $this->createConnector();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PluginManagerTest.php
index 41b9397c0c8db1f0b2b1b7fc031191f3c00a178a..c6d182feea2f5f7e2a605c6af0d20ef638df7b2b 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\ILS\Driver\DriverInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\ILS\\Driver\\DriverInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PolarisTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PolarisTest.php
index ea4c93d9e40902af004f2861ba3b03e2140f1c10..a4e2a38c45161e987146942598ea738975e96b4b 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PolarisTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/PolarisTest.php
@@ -45,7 +45,7 @@ class PolarisTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Polaris();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SampleTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SampleTest.php
index c478eda1c110f54caba608e2a7ea890bfdee38ed..d14a8f5e3c9f1b2f065b1da3e4da5e3fb09d9a76 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SampleTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SampleTest.php
@@ -52,7 +52,7 @@ class SampleTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Sample();
         $this->driver->init();
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SierraRestTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SierraRestTest.php
index 32f962bba9d82141d04de755d8e8aa194a8512a9..e6312c8f598fa39929188b6399872955ebbefb2c 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SierraRestTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SierraRestTest.php
@@ -59,7 +59,7 @@ class SierraRestTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $sessionFactory = function ($namespace) {
             return new \Zend\Session\Container($namespace);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SymphonyTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SymphonyTest.php
index 88434bb9ce9b1bb90aa6c51bea172cd0ada3fb98..d3fccb9b59ac58f73a70da7ebd0cda415cbda6a8 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SymphonyTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/SymphonyTest.php
@@ -52,7 +52,7 @@ class SymphonyTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $loader = $this->getMockBuilder(\VuFind\Record\Loader::class)
             ->disableOriginalConstructor()->getMock();
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/UnicornTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/UnicornTest.php
index e99608f905cc79ff332b588eb27c78cab84c60ab..130a9640ff7d766757d31c256f4d1895af356355 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/UnicornTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/UnicornTest.php
@@ -45,7 +45,7 @@ class UnicornTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Unicorn(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VirtuaTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VirtuaTest.php
index f63a87060112340b5f2e02b4ed916a4ffd83d95e..842318df9b1c5b294998eb0fefb76b9f089f5841 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VirtuaTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VirtuaTest.php
@@ -45,7 +45,7 @@ class VirtuaTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Virtua();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerRestfulTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerRestfulTest.php
index 7226c5c8da3d961cc6bc141e8d8e967980932caa..a2fbfdab5e4602ebe0233783a903070aab99b906 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerRestfulTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerRestfulTest.php
@@ -45,7 +45,7 @@ class VoyagerRestfulTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new VoyagerRestful(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerTest.php
index 947c5c74b1a2043da070916154c00b903027c2a6..7ba1c214aa3aee069a5c8fc81acbe4f3ee0d136c 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/VoyagerTest.php
@@ -45,7 +45,7 @@ class VoyagerTest extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new Voyager(new \VuFind\Date\Converter());
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/XCNCIP2Test.php b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/XCNCIP2Test.php
index 799088000b19b1ffb3c03985fe7ae6b9745c1496..328cdb5cdf7a4dab0a45aaf9b930818759a1ab17 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/XCNCIP2Test.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/ILS/Driver/XCNCIP2Test.php
@@ -45,7 +45,7 @@ class XCNCIP2Test extends \VuFindTest\Unit\ILSDriverTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->driver = new XCNCIP2();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Mailer/MailerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Mailer/MailerTest.php
index a5d49a5128b7bee186f377fadd3fde760e640001..e24d67222f3dc29ab504f12d4d093110938a164f 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Mailer/MailerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Mailer/MailerTest.php
@@ -238,11 +238,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Invalid Recipient Email Address
      */
     public function testBadTo()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Invalid Recipient Email Address');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $mailer = new Mailer($transport);
         $mailer->send('bad@bad', 'from@example.com', 'subject', 'body');
@@ -253,11 +254,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Invalid Reply-To Email Address
      */
     public function testBadReplyTo()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Invalid Reply-To Email Address');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $mailer = new Mailer($transport);
         $mailer->send(
@@ -270,11 +272,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Invalid Recipient Email Address
      */
     public function testEmptyTo()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Invalid Recipient Email Address');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $mailer = new Mailer($transport);
         $mailer->send('', 'from@example.com', 'subject', 'body');
@@ -285,11 +288,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Too Many Email Recipients
      */
     public function testTooManyRecipients()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Too Many Email Recipients');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $mailer = new Mailer($transport);
         $mailer->send('one@test.com;two@test.com', 'from@example.com', 'subject', 'body');
@@ -300,11 +304,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Invalid Sender Email Address
      */
     public function testBadFrom()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Invalid Sender Email Address');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $mailer = new Mailer($transport);
         $mailer->send('to@example.com', 'bad@bad', 'subject', 'body');
@@ -315,11 +320,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Invalid Sender Email Address
      */
     public function testBadFromInAddressObject()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Invalid Sender Email Address');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $mailer = new Mailer($transport);
         $mailer->send('to@example.com', new Address('bad@bad'), 'subject', 'body');
@@ -330,11 +336,12 @@ class MailerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Boom
      */
     public function testTransportException()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Boom');
+
         $transport = $this->createMock(\Zend\Mail\Transport\TransportInterface::class);
         $transport->expects($this->once())->method('send')->will($this->throwException(new \Exception('Boom')));
         $mailer = new Mailer($transport);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/QRCode/LoaderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/QRCode/LoaderTest.php
index 6277b28eb2d0c66c06f40181341773ad285b22f9..32cd2b4d48ec8a2b927eb152445079ff21ce3b89 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/QRCode/LoaderTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/QRCode/LoaderTest.php
@@ -54,11 +54,12 @@ class LoaderTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Could not load default fail image.
      */
     public function testUtterFailure()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Could not load default fail image.');
+
         $theme = $this->getMockBuilder(\VuFindTheme\ThemeInfo::class)
             ->setConstructorArgs(['foo', 'bar'])->getMock();
         $theme->expects($this->once())->method('findContainingTheme')->with($this->equalTo(['images/noQRCode.gif']))->will($this->returnValue(false));
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/PluginManagerTest.php
index f6113819add427f16966aa3acc240a489f69da82..c2bbb1c52d2436ffd633e7f9d6f16a77ee3be895 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Recommend\RecommendInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Recommend\\RecommendInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php
index c114544a7cc9b5a50c80ffe29a8d0a460f1895f7..22f1e3726e443fbf03eb5987082fbda214fe9471 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php
@@ -28,7 +28,6 @@
  */
 namespace VuFindTest\Recommend;
 
-use PHPUnit\Framework\Assert;
 use VuFind\Recommend\RandomRecommend as Random;
 use VuFindTest\Unit\TestCase as TestCase;
 
@@ -48,7 +47,7 @@ class RandomRecommendTest extends TestCase
      *
      * @return void
      */
-    public function setup()
+    public function setUp(): void
     {
         $this->recommend = new Random(
             $this->createMock(\VuFindSearch\Service::class),
@@ -66,22 +65,22 @@ class RandomRecommendTest extends TestCase
         //[backend]:[limit]:[display mode]:[random mode]:[minimumset]:[facet1]:[facetvalue1]
         $this->recommend->setConfig("SolrWeb:5:mixed:disregard:20:facet1:value1:facet2:value2");
         $this->assertEquals(
-            "SolrWeb", Assert::readAttribute($this->recommend, 'backend')
+            "SolrWeb", $this->getProperty($this->recommend, 'backend')
         );
         $this->assertEquals(
-            "5", Assert::readAttribute($this->recommend, 'limit')
+            "5", $this->getProperty($this->recommend, 'limit')
         );
         $this->assertEquals(
-            "mixed", Assert::readAttribute($this->recommend, 'displayMode')
+            "mixed", $this->getProperty($this->recommend, 'displayMode')
         );
         $this->assertEquals(
-            "disregard", Assert::readAttribute($this->recommend, 'mode')
+            "disregard", $this->getProperty($this->recommend, 'mode')
         );
         $this->assertEquals(
-            "20", Assert::readAttribute($this->recommend, 'minimum')
+            "20", $this->getProperty($this->recommend, 'minimum')
         );
-        $filters = Assert::readAttribute($this->recommend, 'filters');
-        $this->assertInternalType("array", $filters);
+        $filters = $this->getProperty($this->recommend, 'filters');
+        $this->assertIsArray($filters);
         $this->assertCount(2, $filters);
         $this->assertEquals("facet1:value1", $filters[0]);
         $this->assertEquals("facet2:value2", $filters[1]);
@@ -97,22 +96,22 @@ class RandomRecommendTest extends TestCase
         //[backend]:[limit]:[display mode]:[random mode]:[minimumset]:[facet1]:[facetvalue1]
         $this->recommend->setConfig('');
         $this->assertEquals(
-            "Solr", Assert::readAttribute($this->recommend, 'backend')
+            "Solr", $this->getProperty($this->recommend, 'backend')
         );
         $this->assertEquals(
-            "10", Assert::readAttribute($this->recommend, 'limit')
+            "10", $this->getProperty($this->recommend, 'limit')
         );
         $this->assertEquals(
-            "standard", Assert::readAttribute($this->recommend, 'displayMode')
+            "standard", $this->getProperty($this->recommend, 'displayMode')
         );
         $this->assertEquals(
-            "retain", Assert::readAttribute($this->recommend, 'mode')
+            "retain", $this->getProperty($this->recommend, 'mode')
         );
         $this->assertEquals(
-            "0", Assert::readAttribute($this->recommend, 'minimum')
+            "0", $this->getProperty($this->recommend, 'minimum')
         );
         $this->assertEquals(
-            [], Assert::readAttribute($this->recommend, 'filters')
+            [], $this->getProperty($this->recommend, 'filters')
         );
     }
 
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/SideFacetsTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/SideFacetsTest.php
index f8427d2b9500b6fd91d1a917858d21a6cf6d2ec4..c9579dd5f71300d7020c8f69c4fdbaf5a0dd35ea 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/SideFacetsTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/SideFacetsTest.php
@@ -77,11 +77,12 @@ class SideFacetsTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage VuFind\Recommend\SideFacets: hierarchical facet helper unavailable
      */
     public function testMissingHierarchicalFacetHelper()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('VuFind\\Recommend\\SideFacets: hierarchical facet helper unavailable');
+
         $configLoader = $this->getMockConfigLoader(
             [
                 'Results' => [
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Record/CacheTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Record/CacheTest.php
index 3afbad93a918fed84c0f9b67554ac88b4fdb697c..ddc0686f64d178af6d190939faeb9e543aa6329e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Record/CacheTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Record/CacheTest.php
@@ -52,7 +52,7 @@ class CacheTest extends TestCase
      *
      * @return void
      */
-    protected function setUp()
+    protected function setUp(): void
     {
         $cache = $this->getRecordCache();
         $this->recordTable = [
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Record/LoaderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Record/LoaderTest.php
index 6e61abdf37c850c46a616a78c4bb58bef7416932..7aa5a44f3ec4c07f4ef0b515403c30a121decde8 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Record/LoaderTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Record/LoaderTest.php
@@ -54,11 +54,12 @@ class LoaderTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\RecordMissing
-     * @expectedExceptionMessage Record Solr:test does not exist.
      */
     public function testMissingRecord()
     {
+        $this->expectException(\VuFind\Exception\RecordMissing::class);
+        $this->expectExceptionMessage('Record Solr:test does not exist.');
+
         $collection = $this->getCollection([]);
         $service = $this->createMock(\VuFindSearch\Service::class);
         $service->expects($this->once())->method('retrieve')
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/PluginManagerTest.php
index 77dd971ab6f69a9f04f6b143bf461dc796ce04c5..23ae0b2c2f10db80873287f3285d4f36639866f6 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\RecordDriver\AbstractBase
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\RecordDriver\\AbstractBase');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/PluginManagerTest.php
index dfe106bbe6af6f61fbbea19de4ec47a87d278938..71de0e2c854d841d14132ca3d14780388146b3fe 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\RecordTab\TabInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\RecordTab\\TabInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/PluginManagerTest.php
index 1da043032ecdc53dc9dca5c4e0b4350e95751cec..affc0acdc1f641d6e982289d8300380271111060 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Related\RelatedInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Related\\RelatedInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Reserves/CsvReaderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Reserves/CsvReaderTest.php
index 59e451a69825c181984b29b7887ba056bf76f1da..2fbf8d2217f5d9e4e88620a9eda8e2d3208cda8c 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Reserves/CsvReaderTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Reserves/CsvReaderTest.php
@@ -137,11 +137,12 @@ class CsvReaderTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Could not find valid data. Details:
      */
     public function testEmptyFile()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Could not find valid data. Details:');
+
         $this->getReader('empty.csv')->getReserves();
     }
 
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/PluginManagerTest.php
index 44369aced8f110d8f9a9ed6582d3053a86f1ca8c..d38cd537d6b7334b8586df2d6c3f69a6466c1587 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Resolver\Driver\DriverInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Resolver\\Driver\\DriverInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php
index d56ae165f6bd84201c2f0c4d076e6356afa4b8af..a0029539c8e0bb7eafafe258779651ed6aa0650f 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Role\PermissionProvider\PermissionProviderInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Role\\PermissionProvider\\PermissionProviderInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php
index 33febe51c4704bc9932618a511dadd714ed7b422..6dbd76adce6e0ff7f13cd62d58f3afb7fc9f6f9c 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php
@@ -45,7 +45,7 @@ class ClickatellTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // Without SOAP functionality, we can't proceed:
         if (!function_exists('iconv')) {
@@ -93,11 +93,12 @@ class ClickatellTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage badbadbad
      */
     public function testUnexpectedResponse()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('badbadbad');
+
         $client = $this->getMockClient();
         $expectedUri = 'https://api.clickatell.com/http/sendmsg?api_id=api_id&user=user&password=password&to=1234567890&text=hello';
         $response = new \Zend\Http\Response();
@@ -115,11 +116,12 @@ class ClickatellTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Problem sending text.
      */
     public function testFailureResponse()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Problem sending text.');
+
         $client = $this->getMockClient();
         $expectedUri = 'https://api.clickatell.com/http/sendmsg?api_id=api_id&user=user&password=password&to=1234567890&text=hello';
         $response = new \Zend\Http\Response();
@@ -136,11 +138,12 @@ class ClickatellTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFind\Exception\Mail
-     * @expectedExceptionMessage Foo
      */
     public function testClientException()
     {
+        $this->expectException(\VuFind\Exception\Mail::class);
+        $this->expectExceptionMessage('Foo');
+
         $client = $this->getMockClient();
         $expectedUri = 'https://api.clickatell.com/http/sendmsg?api_id=api_id&user=user&password=password&to=1234567890&text=hello';
         $client->expects($this->once())->method('setMethod')->with($this->equalTo('GET'))->will($this->returnValue($client));
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/BackendManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/BackendManagerTest.php
index a12d93cdc5a5c864de9925e6b5148782e5e27ac4..fa35d2f5b8cee25d74febaffc31a28c8dfef4cf6 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/BackendManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/BackendManagerTest.php
@@ -49,11 +49,12 @@ class BackendManagerTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        UnexpectedValueException
-     * @expectedExceptionMessage Expected backend registry to return object
      */
     public function testGetThrowsOnNonObject()
     {
+        $this->expectException(\UnexpectedValueException::class);
+        $this->expectExceptionMessage('Expected backend registry to return object');
+
         $registry = $this->getMockForAbstractClass('Zend\ServiceManager\ServiceLocatorInterface');
         $registry->expects($this->once())
             ->method('get')
@@ -67,11 +68,12 @@ class BackendManagerTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        UnexpectedValueException
-     * @expectedExceptionMessage does not implement the expected interface
      */
     public function testGetThrowsOnNonBackend()
     {
+        $this->expectException(\UnexpectedValueException::class);
+        $this->expectExceptionMessage('does not implement the expected interface');
+
         $registry = $this->getMockForAbstractClass('Zend\ServiceManager\ServiceLocatorInterface');
         $registry->expects($this->once())
             ->method('get')
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Options/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Options/PluginManagerTest.php
index 4cd57405f2e66bdc908c015a56158d2f40ae3cb6..4fe0afb6c4841d6fab3ea034afef6426661f4930 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Options/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Options/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Search\Base\Options
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Search\\Base\\Options');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Params/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Params/PluginManagerTest.php
index e4621b55386509e2f3144f04126b535e77a5012b..0e4783afa1a9f8a3d67435b9db8c95943ab047e7 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Params/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Params/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Search\Base\Params
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Search\\Base\\Params');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/OnCampusListenerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/OnCampusListenerTest.php
index c187af11321bd97e48e6ea3a9942eaad2ea94e0d..c65adb3c154bc645f8a06c8bfb8ec1041041a2cc 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/OnCampusListenerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/OnCampusListenerTest.php
@@ -59,7 +59,7 @@ class OnCampusListenerTest extends TestCase
      *
      * @return void
      */
-    protected function setup()
+    protected function setUp(): void
     {
         $connector      = new Connector('http://example.org/', 'sample', 'none');
         $this->backend  = new Backend($connector);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/PrimoPermissionHandlerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/PrimoPermissionHandlerTest.php
index 92cf6336c4c902bffb1fe57ca5286891a77f8388..da295191bb211df276399db89ef652f735231ac8 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/PrimoPermissionHandlerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Primo/PrimoPermissionHandlerTest.php
@@ -130,7 +130,7 @@ class PrimoPermissionHandlerTest extends TestCase
      *
      * @return void
      */
-    protected function setup()
+    protected function setUp(): void
     {
     }
 
@@ -140,11 +140,12 @@ class PrimoPermissionHandlerTest extends TestCase
      *
      * @return void
      *
-     * @expectedException Exception
-     * @expectedExceptionMessage No institutionCode found.
      */
     public function testWithoutConfig()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('No institutionCode found.');
+
         new PrimoPermissionHandler(null);
     }
 
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Results/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Results/PluginManagerTest.php
index 8ab15d6a4ced92eca778f208d1d73ee008d40964..1f38219a792af8cae2bda055d8648cb27ea2d8b5 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Results/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Results/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Search\Base\Results
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Search\\Base\\Results');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/ConditionalFilterListenerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/ConditionalFilterListenerTest.php
index dffe9fe5068ffac755afb5c51ca6e2937a5425bd..c96f63e20b7ec94e04853f48a110cc246d8750a5 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/ConditionalFilterListenerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/ConditionalFilterListenerTest.php
@@ -77,7 +77,7 @@ class ConditionalFilterListenerTest extends TestCase
      *
      * @return void
      */
-    protected function setup()
+    protected function setUp(): void
     {
         $handlermap     = new HandlerMap(['select' => ['fallback' => true]]);
         $connector      = new Connector('http://example.org/', $handlermap);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/HierarchicalFacetHelperTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/HierarchicalFacetHelperTest.php
index 4911c02966f5ec84d8582e3335d547da62c0340d..994db6ecd47ceb8f9f6d69906637e4340097d236 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/HierarchicalFacetHelperTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/HierarchicalFacetHelperTest.php
@@ -112,7 +112,7 @@ class HierarchicalFacetHelperTest extends TestCase
      *
      * @return void
      */
-    protected function setup()
+    protected function setUp(): void
     {
         $this->helper = new HierarchicalFacetHelper();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/MultiIndexListenerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/MultiIndexListenerTest.php
index 58e59a5d07e267081aebc4e109d409c777fbcd4a..d374ac20576e7e635854afc456e35ec3b5857ec7 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/MultiIndexListenerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/MultiIndexListenerTest.php
@@ -121,7 +121,7 @@ class MultiIndexListenerTest extends TestCase
      *
      * @return void
      */
-    protected function setup()
+    protected function setUp(): void
     {
         $handlermap     = new HandlerMap(['select' => ['fallback' => true]]);
         $connector      = new Connector('http://example.org/', $handlermap);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/SpellingProcessorTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/SpellingProcessorTest.php
index 6c9e6303cd5db813a613f7e6172a508cf39267cc..3f0a9dda9f72fe04f91f56303a30191e041738be 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/SpellingProcessorTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/Solr/SpellingProcessorTest.php
@@ -466,11 +466,12 @@ class SpellingProcessorTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Unexpected suggestion format; spellcheck.extendedResults must be set to true.
      */
     public function testDetectionOfMissingExtendedResultsSetting()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Unexpected suggestion format; spellcheck.extendedResults must be set to true.');
+
         $sp = new SpellingProcessor(new Config([]));
         $spelling = $this->getFixture('spell5');
         $query = $this->getFixture('query5');
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Session/FileTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Session/FileTest.php
index 1e51b0d01bf1dd5be4e7967dc572a032f079b441..e17248ca85b73e9877e602042eacf5cc7230e965 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Session/FileTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Session/FileTest.php
@@ -52,7 +52,7 @@ class FileTest extends \VuFindTest\Unit\SessionHandlerTestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $tempdir = function_exists('sys_get_temp_dir')
             ? sys_get_temp_dir() : DIRECTORY_SEPARATOR . 'tmp';
@@ -64,7 +64,7 @@ class FileTest extends \VuFindTest\Unit\SessionHandlerTestCase
      *
      * @return void
      */
-    public function tearDown()
+    public function tearDown(): void
     {
         rmdir($this->path);
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Session/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Session/PluginManagerTest.php
index 99408faeaaad21028c2354b4f0c2c564c0079bc4..bd4a942a7f35daece4e317bbf1f93a98b48ff56c 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Session/PluginManagerTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Session/PluginManagerTest.php
@@ -58,11 +58,12 @@ class PluginManagerTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\ServiceManager\Exception\InvalidServiceException
-     * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Session\HandlerInterface
      */
     public function testExpectedInterface()
     {
+        $this->expectException(\Zend\ServiceManager\Exception\InvalidServiceException::class);
+        $this->expectExceptionMessage('Plugin ArrayObject does not belong to VuFind\\Session\\HandlerInterface');
+
         $pm = new PluginManager(
             $this->createMock(\Interop\Container\ContainerInterface::class)
         );
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/TagsTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/TagsTest.php
index 8d35f5a9666c3eeecab4caabec09ad07f7487eb5..2e1fc226489f1c81044baccbc14c29e84b0a4756 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/TagsTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/TagsTest.php
@@ -50,7 +50,7 @@ class TagsTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->parser = new \VuFind\Tags();
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/DatabaseTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/DatabaseTest.php
index 43ea7065d211bbb9ad0c0c0eaf5c694b50f39c25..b3a11234af01a784bad1ef3a9a3b53b6de0ba122 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/DatabaseTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/DatabaseTest.php
@@ -111,11 +111,12 @@ class DatabaseTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Shortlink could not be resolved: B
      */
     public function testResolutionOfBadInput()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Shortlink could not be resolved: B');
+
         $table = $this->getMockTable(['select']);
         $mockResults = $this->getMockBuilder(\Zend\Db\ResultSet::class)
             ->setMethods(['count'])
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/NoneTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/NoneTest.php
index 1b978f255e3da2641169abc5a446af9aee2b5338..010ea7a65910e6f8a1c8357fd2539de9849a79a1 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/NoneTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/UrlShortener/NoneTest.php
@@ -57,11 +57,12 @@ class NoneTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage UrlShortener None is unable to resolve shortlinks.
      */
     public function testNoResolution()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('UrlShortener None is unable to resolve shortlinks.');
+
         $none = new None();
         $none->resolve('foo');
     }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/PermissionTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/PermissionTest.php
index b6e4a301ba0a0b9239b16dd1c253d7826c4e24b6..77d9c909edb494b174555b03a4df1acae94ac532 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/PermissionTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/PermissionTest.php
@@ -100,10 +100,11 @@ class PermissionTest  extends \VuFindTest\Unit\ViewHelperTestCase
      *
      * @return void
      *
-     * @expectedException Zend\View\Exception\RuntimeException
      */
     public function testTemplateDisplay()
     {
+        $this->expectException(\Zend\View\Exception\RuntimeException::class);
+
         // Template does not exist, expect an exception, though
         $mockPmd = $this->getMockPmd(
             [
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php
index f9c6467564429c9f1161bc76703db57086814e2b..4b390054ca14f7c4464ed7c469bae84cf9bad75e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php
@@ -46,11 +46,12 @@ class RecordTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        Zend\View\Exception\RuntimeException
-     * @expectedExceptionMessage Cannot find RecordDriver/AbstractBase/core.phtml template for class: VuFind\RecordDriver\SolrMarc
      */
     public function testMissingTemplate()
     {
+        $this->expectException(\Zend\View\Exception\RuntimeException::class);
+        $this->expectExceptionMessage('Cannot find RecordDriver/AbstractBase/core.phtml template for class: VuFind\\RecordDriver\\SolrMarc');
+
         $record = $this->getRecord($this->loadRecordFixture('testbug1.json'));
         $record->getView()->resolver()->expects($this->at(0))->method('resolve')
             ->with($this->equalTo('RecordDriver/SolrMarc/core.phtml'))
@@ -439,11 +440,12 @@ class RecordTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Invalid URL array.
      */
     public function testGetLinkDetailsFailure()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Invalid URL array.');
+
         $driver = new \VuFindTest\RecordDriver\TestHarness();
         $driver->setRawData(
             [
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/SafeMoneyFormatTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/SafeMoneyFormatTest.php
index a879de3f5cd2dafc51abc56e2e8debf8eacb0e78..ca18f1f57e9eec72453bfdc31bc6cfd3215ded9e 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/SafeMoneyFormatTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/SafeMoneyFormatTest.php
@@ -52,7 +52,7 @@ class SafeMoneyFormatTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         // store current default and set a value for consistency in testing
         $this->locale = setlocale(LC_MONETARY, 0);
@@ -67,7 +67,7 @@ class SafeMoneyFormatTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      */
-    public function tearDown()
+    public function tearDown(): void
     {
         // restore current default
         setlocale(LC_MONETARY, $this->locale);
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/TranslateTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/TranslateTest.php
index db2c99a5879f00fc8c2bb8d511b447ed939e947e..e8beecb50067e9b2fcbc407b8c0f88183c8322bc 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/TranslateTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/TranslateTest.php
@@ -60,11 +60,12 @@ class TranslateTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Unexpected value sent to translator!
      */
     public function testTranslateWithEmptyArray()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Unexpected value sent to translator!');
+
         $translate = new Translate();
         $translate->__invoke([]);
     }
@@ -74,11 +75,12 @@ class TranslateTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Unexpected value sent to translator!
      */
     public function testTranslateWithOverfilledArray()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Unexpected value sent to translator!');
+
         $translate = new Translate();
         $translate->__invoke([1, 2, 3]);
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/BackendTest.php
index 30925a9b5595d94d95fb0f8ab182ece7ff88992d..9e137d08b59f927d98d2c167032f4d9e74a72d3f 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/BackendTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/BackendTest.php
@@ -53,11 +53,12 @@ class BackendTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage retrieve() not supported by BrowZine.
      */
     public function testRetrieve()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('retrieve() not supported by BrowZine.');
+
         $conn = $this->getConnector();
         $back = new Backend($conn, $this->getRCFactory());
         $back->retrieve('foo');
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/QueryBuilderTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/QueryBuilderTest.php
index 571b7ee3e478336d7d9cd0be85416d83c931a0f2..f1961ba0489bbc12e960d84e2c79217f0f55902d 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/QueryBuilderTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/QueryBuilderTest.php
@@ -63,11 +63,12 @@ class QueryBuilderTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Query groups not supported
      */
     public function testAdvanced()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Query groups not supported');
+
         $qb = new QueryBuilder();
         $qb->build(new QueryGroup('AND', []));
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/Response/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/Response/RecordCollectionFactoryTest.php
index 17d2c81f0f30f9ded8dee46645f17d4136fbe931..28378543d411820506d7e1edadee22726ef08b08 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/Response/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/BrowZine/Response/RecordCollectionFactoryTest.php
@@ -60,11 +60,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testInvalidInput()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $fact = new RecordCollectionFactory();
         $coll = $fact->factory('garbage');
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/Response/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/Response/RecordCollectionFactoryTest.php
index 979587af30676e1d5b6174f268958f2ffd377caa..9aea6cc4397b492578351be8907fc2dd1860c5ad 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/Response/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/Response/RecordCollectionFactoryTest.php
@@ -47,11 +47,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Record factory must be callable.
      */
     public function testConstructorRequiresFactoryFunction()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Record factory must be callable.');
+
         $factory = new RecordCollectionFactory(null);
     }
 
@@ -60,11 +61,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testFactoryRequiresArray()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $factory = new RecordCollectionFactory(
             function () {
             }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EIT/Response/XML/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EIT/Response/XML/RecordCollectionFactoryTest.php
index bca3ea77c1e3a1fdbb2892f8f31e78018e618ce0..eea6d5a4d57887976055a16fdbe97fe06f8efb65 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EIT/Response/XML/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EIT/Response/XML/RecordCollectionFactoryTest.php
@@ -47,11 +47,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Record factory must be callable.
      */
     public function testConstructorRequiresValidFactoryFunction()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Record factory must be callable.');
+
         $factory = new RecordCollectionFactory(12345);
     }
 
@@ -60,11 +61,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testInvalidInput()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $fact = new RecordCollectionFactory(
             function () {
             }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/BackendTest.php
index ba33c125ce9c59073a5ead26cca35451cb4c3248..fd2d39d97b33e3a5f3ca0d2150cd96e22958efcf 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/BackendTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/BackendTest.php
@@ -54,11 +54,12 @@ class BackendTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage retrieve() not supported by LibGuides.
      */
     public function testRetrieve()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('retrieve() not supported by LibGuides.');
+
         $conn = $this->getConnector();
         $back = new Backend($conn, $this->getRCFactory());
         $back->retrieve('foo');
@@ -144,10 +145,11 @@ class BackendTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException VuFindSearch\Backend\Exception\BackendException
      */
     public function testSearchWrapsLibGuidesException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+
         $conn = $this->getConnectorMock(['query']);
         $conn->expects($this->once())
             ->method('query')
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/QueryBuilderTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/QueryBuilderTest.php
index e1ec7c1c2c21b76201805b9a63b84f86a1f0416f..719e3112b9aaf3491f375cf56c68824eb8787c66 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/QueryBuilderTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/QueryBuilderTest.php
@@ -63,11 +63,12 @@ class QueryBuilderTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Advanced search not supported.
      */
     public function testAdvanced()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Advanced search not supported.');
+
         $qb = new QueryBuilder();
         $qb->build(new QueryGroup('AND', []));
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/Response/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/Response/RecordCollectionFactoryTest.php
index 45ded837971b6b242176674adccb1a6cb3f69793..814dbe8452e7963e447203a39c24def831b0f204 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/Response/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/LibGuides/Response/RecordCollectionFactoryTest.php
@@ -60,11 +60,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testInvalidInput()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $fact = new RecordCollectionFactory();
         $coll = $fact->factory('garbage');
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/BackendTest.php
index 205c71762c0bb540ca0a62b153ad5d7f88647f7e..9f30aeb1b7d0e25bd0978d131fe790934c0900d8 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/BackendTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/BackendTest.php
@@ -133,10 +133,11 @@ class BackendTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException VuFindSearch\Backend\Exception\BackendException
      */
     public function testSearchWrapsPrimoException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+
         $conn = $this->getConnectorMock(['query']);
         $conn->expects($this->once())
             ->method('query')
@@ -150,10 +151,11 @@ class BackendTest extends \VuFindTest\Unit\TestCase
      *
      * @return void
      *
-     * @expectedException VuFindSearch\Backend\Exception\BackendException
      */
     public function testRetrieveWrapsPrimoException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+
         $conn = $this->getConnectorMock(['getRecord']);
         $conn->expects($this->once())
             ->method('getRecord')
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/ConnectorTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/ConnectorTest.php
index c2cd04ca7a369e6712befac595e3447d528da45b..1bff6c91b7f74074e6cd2f78bae0a8acf87f83e4 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/ConnectorTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/ConnectorTest.php
@@ -125,11 +125,12 @@ class ConnectorTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        \Exception
-     * @expectedExceptionMessage Unauthorized access
      */
     public function testErrorInSuccessfulResponse()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Unauthorized access');
+
         $conn = $this->createConnector('error-with-success-http');
         $terms = [
             ['index' => 'Title', 'lookfor' => 'dummy query'],
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/Response/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/Response/RecordCollectionFactoryTest.php
index 3c7443ae189cf931bec39975fc3fe88756c093a2..4e50e11ffa4ebb429dd43e75072d6b5f581cb838 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/Response/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Primo/Response/RecordCollectionFactoryTest.php
@@ -47,11 +47,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Record factory must be callable.
      */
     public function testConstructorRequiresValidFactoryFunction()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Record factory must be callable.');
+
         $factory = new RecordCollectionFactory(12345);
     }
 
@@ -60,11 +61,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testInvalidInput()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $fact = new RecordCollectionFactory();
         $coll = $fact->factory('garbage');
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/BackendTest.php
index 6518657b158718f563ecb65b7edef2e91a079bc4..eeee821fb9399e6658f5c0314f3c6d86b1c7ad7d 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/BackendTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/BackendTest.php
@@ -172,11 +172,12 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage JSON decoding error: 4 -- bad {
      */
     public function testBadJson()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('JSON decoding error: 4 -- bad {');
+
         $conn = $this->getConnectorMock(['query']);
         $conn->expects($this->once())
             ->method('query')
@@ -190,11 +191,12 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Invalid response writer type: xml
      */
     public function testInjectResponseWriterThrownOnIncompabileResponseWriter()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Invalid response writer type: xml');
+
         $conn = $this->getConnectorMock();
         $back = new Backend($conn);
         $back->retrieve('foobar', new ParamBag(['wt' => ['xml']]));
@@ -205,11 +207,12 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Invalid named list implementation type: bad
      */
     public function testInjectResponseWriterThrownOnIncompabileNamedListSetting()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Invalid named list implementation type: bad');
+
         $conn = $this->getConnectorMock();
         $back = new Backend($conn);
         $back->retrieve('foobar', new ParamBag(['json.nl' => ['bad']]));
@@ -283,11 +286,12 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\RemoteErrorException
-     * @expectedExceptionMessage Alphabetic Browse index missing.
      */
     public function testRefineAlphaBrowseException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\RemoteErrorException::class);
+        $this->expectExceptionMessage('Alphabetic Browse index missing.');
+
         $this->runRefineExceptionCall('does not exist');
     }
 
@@ -296,11 +300,12 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\RemoteErrorException
-     * @expectedExceptionMessage Alphabetic Browse index missing.
      */
     public function testRefineAlphaBrowseExceptionWithAltString()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\RemoteErrorException::class);
+        $this->expectExceptionMessage('Alphabetic Browse index missing.');
+
         $this->runRefineExceptionCall('couldn\'t find a browse index');
     }
 
@@ -309,11 +314,12 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\RemoteErrorException
-     * @expectedExceptionMessage not a browse error
      */
     public function testRefineAlphaBrowseExceptionWithNonBrowseString()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\RemoteErrorException::class);
+        $this->expectExceptionMessage('not a browse error');
+
         $this->runRefineExceptionCall('not a browse error');
     }
 
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/ConnectorTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/ConnectorTest.php
index 915cb709a05816361dfd8a1de332732ea7dfea67..1c1e9dc7767a0711c364f4af99fae0591ff51109 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/ConnectorTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/ConnectorTest.php
@@ -64,7 +64,7 @@ class ConnectorTest extends TestCase
     {
         $conn = $this->createConnector('single-record');
         $resp = $conn->retrieve('id');
-        $this->assertInternalType('string', $resp);
+        $this->assertIsString($resp);
         json_decode($resp, true);
         $this->assertEquals(\JSON_ERROR_NONE, json_last_error());
     }
@@ -78,7 +78,7 @@ class ConnectorTest extends TestCase
     {
         $conn = $this->createConnector('no-match');
         $resp = $conn->retrieve('id');
-        $this->assertInternalType('string', $resp);
+        $this->assertIsString($resp);
     }
 
     /**
@@ -86,11 +86,12 @@ class ConnectorTest extends TestCase
      *
      * @return void
      *
-     * @expectedException     VuFindSearch\Backend\Exception\RemoteErrorException
-     * @expectedExceptionCode 500
      */
     public function testInternalServerError()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\RemoteErrorException::class);
+        $this->expectExceptionCode(500);
+
         $conn = $this->createConnector('internal-server-error');
         $resp = $conn->retrieve('id');
     }
@@ -100,11 +101,12 @@ class ConnectorTest extends TestCase
      *
      * @return void
      *
-     * @expectedException     VuFindSearch\Backend\Exception\RequestErrorException
-     * @expectedExceptionCode 400
      */
     public function testBadRequestError()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\RequestErrorException::class);
+        $this->expectExceptionCode(400);
+
         $conn = $this->createConnector('bad-request');
         $resp = $conn->retrieve('id');
     }
@@ -114,11 +116,12 @@ class ConnectorTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        InvalidArgumentException
-     * @expectedExceptionMessage AdapterInterface
      */
     public function testSetAdapterThrowsInvalidObject()
     {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('AdapterInterface');
+
         $conn = $this->createConnector('single-record');
         $conn->setAdapter($this);
     }
@@ -128,11 +131,12 @@ class ConnectorTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        InvalidArgumentException
-     * @expectedExceptionMessage Unable to serialize
      */
     public function testSaveThrowsUnknownFormat()
     {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unable to serialize');
+
         $conn = $this->createConnector();
         $document = $this->createMock(\VuFindSearch\Backend\Solr\Document\UpdateDocument::class);
         $conn->write($document, 'unknown', 'update');
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/HandlerMapTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/HandlerMapTest.php
index d57e9e5ba01847b154c175219a6dd0d7661a5553..e65a186b10a5985a35cd4e2010fa3570b010d83f 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/HandlerMapTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/HandlerMapTest.php
@@ -28,11 +28,8 @@
  */
 namespace VuFindTest\Backend\Solr;
 
-use InvalidArgumentException;
-
 use PHPUnit\Framework\TestCase;
 
-use RuntimeException;
 use VuFindSearch\Backend\Solr\HandlerMap;
 
 /**
@@ -51,11 +48,12 @@ class HandlerMapTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        InvalidArgumentException
-     * @expectedExceptionMessage Duplicate fallback
      */
     public function testSetHandlerMapThrowsOnDuplicateFallback()
     {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Duplicate fallback');
+
         $map = [
             'h1' => ['fallback' => true],
             'h2' => ['fallback' => true],
@@ -68,11 +66,12 @@ class HandlerMapTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        InvalidArgumentException
-     * @expectedExceptionMessage Handler for function already defined
      */
     public function testSetHandlerMapThrowsOnDuplicateFunctionHandler()
     {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Handler for function already defined');
+
         $map = [
             'h1' => ['functions' => ['foo']],
             'h2' => ['functions' => ['foo']],
@@ -85,11 +84,12 @@ class HandlerMapTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        RuntimeException
-     * @expectedExceptionMessage Undefined function handler
      */
     public function testGetHandlerThrowsOnUndefinedFunctionHandler()
     {
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionMessage('Undefined function handler');
+
         $map = new HandlerMap([]);
         $map->getHandler('search');
     }
@@ -99,11 +99,12 @@ class HandlerMapTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        InvalidArgumentException
-     * @expectedExceptionMessage Invalid parameter key: bad
      */
     public function testGetParametersThrowsOnUndefinedType()
     {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Invalid parameter key: bad');
+
         $map = new HandlerMap(['h1' => ['functions' => ['foo']]]);
         $map->getParameters('h1', 'bad');
     }
@@ -113,11 +114,12 @@ class HandlerMapTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        InvalidArgumentException
-     * @expectedExceptionMessage Invalid parameter key: bad
      */
     public function testSetParametersThrowsOnUndefinedType()
     {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Invalid parameter key: bad');
+
         $map = new HandlerMap(['h1' => ['functions' => ['foo']]]);
         $map->setParameters('h1', 'bad', []);
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/Response/Json/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/Response/Json/RecordCollectionFactoryTest.php
index 87a84a7a8b68a84b07c99ae65649241e8cc292db..44bbb1aa5496dbbedd81db6d315db38a26df860f 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/Response/Json/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/Response/Json/RecordCollectionFactoryTest.php
@@ -60,11 +60,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testInvalidInput()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $fact = new RecordCollectionFactory();
         $coll = $fact->factory('garbage');
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/BackendTest.php
index f4aaf0fa213a39e237e159c2c3a17ce03fd3df03..6f3d992234350fd6b40ed0d7bb8d16509815b4d8 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/BackendTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/BackendTest.php
@@ -54,7 +54,7 @@ class BackendTest extends TestCase
      *
      * @return void
      */
-    protected function setup()
+    protected function setUp(): void
     {
         if (!class_exists('SerialsSolutions_Summon_Exception', true)) {
             $this->markTestIncomplete('Unable to autoload class: SerialsSolutions\Summon\Exception');
@@ -121,10 +121,11 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException VuFindSearch\Backend\Exception\BackendException
      */
     public function testRetrieveWrapsSummonException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+
         $fact = $this->createMock(\VuFindSearch\Response\RecordCollectionFactoryInterface::class);
         $conn = $this->getConnectorMock(['getRecord']);
         $conn->expects($this->once())
@@ -173,10 +174,11 @@ class BackendTest extends TestCase
      *
      * @return void
      *
-     * @expectedException VuFindSearch\Backend\Exception\BackendException
      */
     public function testSearchWrapsSummonException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+
         $fact = $this->createMock(\VuFindSearch\Response\RecordCollectionFactoryInterface::class);
         $conn = $this->getConnectorMock(['query']);
         $conn->expects($this->once())
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/Response/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/Response/RecordCollectionFactoryTest.php
index 6c151d2398086d11cb75bfe4a01467436b2d67f9..ecfb188f38f531eea24795c1d145653ddd4d2b9b 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/Response/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Summon/Response/RecordCollectionFactoryTest.php
@@ -47,11 +47,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Record factory must be callable.
      */
     public function testConstructorRequiresFactoryFunction()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Record factory must be callable.');
+
         $factory = new RecordCollectionFactory(12345);
     }
 
@@ -60,11 +61,12 @@ class RecordCollectionFactoryTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testFactoryRequiresArray()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $factory = new RecordCollectionFactory(
             function () {
             }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php
index 6c0ead00634393a858baf0fc1019456c8f3ce400..a17eac3d914fa2a6deb289787d7038c37454d0c2 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php
@@ -73,10 +73,11 @@ class ConnectorTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException VuFindSearch\Backend\Exception\RequestErrorException
      */
     public function testGetHoldingsHttpFailure()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\RequestErrorException::class);
+
         $client = $this->createMock(\Zend\Http\Client::class);
         $connector = new Connector('key', $client);
         $client->expects($this->once())->method('setMethod')
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php
index e17574701328461c17392ae1a29a5f1a8ead7b7d..d20c7e6ccc528631eddf64d2e3d9b20f7585d95a 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php
@@ -46,11 +46,12 @@ class RecordCollectionFactoryTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Record factory must be callable.
      */
     public function testBadCallback()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Record factory must be callable.');
+
         $x = new RecordCollectionFactory('bad');
     }
 
@@ -59,11 +60,12 @@ class RecordCollectionFactoryTest extends \PHPUnit\Framework\TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unexpected type of value: Expected array, got string
      */
     public function testBadFactoryInput()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unexpected type of value: Expected array, got string');
+
         $x = new RecordCollectionFactory();
         $x->factory('bad');
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Query/QueryGroupTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Query/QueryGroupTest.php
index 5a01351f7dc95dd3eea0f50328abb1ece8c2df0a..ea415abaf129cd2edf098f8fab5fcd5a62f33515 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Query/QueryGroupTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Query/QueryGroupTest.php
@@ -140,11 +140,12 @@ class QueryGroupTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Unknown or invalid boolean operator: fizz
      */
     public function testIllegalOperator()
     {
+        $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unknown or invalid boolean operator: fizz');
+
         $q = $this->getSampleQueryGroup();
         $q->setOperator('fizz');
     }
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php
index c3db870f68725691823df88558666ecda4b0bbbe..4fd0429edc25def2d31efa39a32ee2e48a7c2105 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php
@@ -86,11 +86,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRetrieveException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $service = $this->getService();
         $backend = $this->getBackend();
         $params = new ParamBag(['x' => 'y']);
@@ -111,11 +112,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testSearchException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $service = $this->getService();
         $backend = $this->getBackend();
         $exception = new BackendException('test');
@@ -136,11 +138,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testGetIdsProxyingSearchException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $service = $this->getService();
         $backend = $this->getBackend();
         $exception = new BackendException('test');
@@ -161,11 +164,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testGetIdsException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         // Use a special backend for this test...
         $this->backend = $this->createMock(\VuFindTest\TestClassForGetIdsInterface::class);
 
@@ -246,11 +250,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRetrieveBatchInterfaceException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         // Use a special backend for this test...
         $this->backend = $this->createMock(\VuFindTest\TestClassForRetrieveBatchInterface::class);
 
@@ -279,11 +284,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRetrieveBatchNoInterfaceException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $service = $this->getService();
         $backend = $this->getBackend();
         $params = new ParamBag(['x' => 'y']);
@@ -339,11 +345,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRandomInterfaceWithException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         // Use a special backend for this test...
         $this->backend = $this->createMock(\VuFindTest\TestClassForRandomInterface::class);
 
@@ -511,11 +518,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRandomNoInterfaceWithExceptionAtFirstSearch()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $service = $this->getService();
         $backend = $this->getBackend();
         $exception = new BackendException('test');
@@ -538,11 +546,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRandomNoInterfaceWithExceptionAtItemSearch()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $limit = 10;
         $total = 20;
         $service = $this->getService();
@@ -581,11 +590,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testRandomNoInterfaceExceptionWithLessResultsThanLimit()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         $limit = 10;
         $total = 5;
         $service = $this->getService();
@@ -654,11 +664,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage foo does not support similar()
      */
     public function testSimilarOnNonSupportingBackend()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('foo does not support similar()');
+
         $service = $this->getService();
         $params = new ParamBag(['x' => 'y']);
         $service->similar('foo', 'bar', $params);
@@ -669,11 +680,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Backend\Exception\BackendException
-     * @expectedExceptionMessage test
      */
     public function testSimilarException()
     {
+        $this->expectException(\VuFindSearch\Backend\Exception\BackendException::class);
+        $this->expectExceptionMessage('test');
+
         // Use a special backend for this test...
         $this->backend = $this->createMock(\VuFindTest\TestBackendClassForSimilar::class);
 
@@ -700,11 +712,12 @@ class SearchServiceTest extends TestCase
      *
      * @return void
      *
-     * @expectedException        VuFindSearch\Exception\RuntimeException
-     * @expectedExceptionMessage Unable to resolve backend: retrieve, junk
      */
     public function testFailedResolve()
     {
+        $this->expectException(\VuFindSearch\Exception\RuntimeException::class);
+        $this->expectExceptionMessage('Unable to resolve backend: retrieve, junk');
+
         $mockResponse = $this->createMock(\Zend\EventManager\ResponseCollection::class);
         $mockResponse->expects($this->any())->method('stopped')->will($this->returnValue(false));
         $em = $this->createMock(\Zend\EventManager\EventManagerInterface::class);
diff --git a/module/VuFindTheme/tests/unit-tests/src/VuFindTest/LessCompilerTest.php b/module/VuFindTheme/tests/unit-tests/src/VuFindTest/LessCompilerTest.php
index 733fcdeaf8ce01f40b800c5c8195597424fe0da3..46830e90c1c29f3fcc8bea1bb869a25433de5fac 100644
--- a/module/VuFindTheme/tests/unit-tests/src/VuFindTest/LessCompilerTest.php
+++ b/module/VuFindTheme/tests/unit-tests/src/VuFindTest/LessCompilerTest.php
@@ -54,7 +54,7 @@ class LessCompilerTest extends Unit\TestCase
      */
     protected $compiler;
 
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
         $temp = sys_get_temp_dir();
         $testDest = $temp . '/vufind_less_comp_test/';
@@ -93,7 +93,7 @@ class LessCompilerTest extends Unit\TestCase
         );
     }
 
-    public function setUp()
+    public function setUp(): void
     {
         $temp = sys_get_temp_dir();
         $perms = fileperms($temp);
@@ -106,7 +106,7 @@ class LessCompilerTest extends Unit\TestCase
         $this->compiler->setTempPath($temp . '/vufind_less_comp_test/cache');
     }
 
-    public static function tearDownAfterClass()
+    public static function tearDownAfterClass(): void
     {
         $temp = sys_get_temp_dir();
         $testDest = $temp . '/vufind_less_comp_test/';
diff --git a/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeCompilerTest.php b/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeCompilerTest.php
index 1638647c8dce8ce40761d78aadfc4194422a42da..67a48c8f07c51b5b31b50213fffc8c21e5d6e010 100644
--- a/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeCompilerTest.php
+++ b/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeCompilerTest.php
@@ -67,14 +67,14 @@ class ThemeCompilerTest extends Unit\TestCase
      *
      * @return void
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->fixturePath = realpath(__DIR__ . '/../../fixtures/themes');
         $this->info = new ThemeInfo($this->fixturePath, 'parent');
         $this->targetPath = $this->info->getBaseDir() . '/compiled';
         // Give up if the target directory already exists:
         if (is_dir($this->targetPath)) {
-            return $this->markTestSkipped('compiled theme already exists.');
+            $this->markTestSkipped('compiled theme already exists.');
         }
     }
 
@@ -224,7 +224,7 @@ class ThemeCompilerTest extends Unit\TestCase
      *
      * @return void
      */
-    public function tearDown()
+    public function tearDown(): void
     {
         $this->getThemeCompiler()->removeTheme('compiled');
     }
diff --git a/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeInfoTest.php b/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeInfoTest.php
index cebb80d60eec6002fa37aa99e3532ac8c0061cfe..2cdec12c7156a9c27bf7389e9fab76fdb4e99c0f 100644
--- a/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeInfoTest.php
+++ b/module/VuFindTheme/tests/unit-tests/src/VuFindTest/ThemeInfoTest.php
@@ -50,7 +50,7 @@ class ThemeInfoTest extends Unit\TestCase
     /**
      * Constructor
      */
-    public function setUp()
+    public function setUp(): void
     {
         $this->fixturePath = realpath(__DIR__ . '/../../fixtures/themes');
     }
@@ -83,11 +83,12 @@ class ThemeInfoTest extends Unit\TestCase
      *
      * @return void
      *
-     * @expectedException        Exception
-     * @expectedExceptionMessage Cannot load theme: invalid
      */
     public function testInvalidTheme()
     {
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Cannot load theme: invalid');
+
         $this->getThemeInfo()->setTheme('invalid');
     }
 
diff --git a/tests/vufind.php_cs b/tests/vufind.php_cs
index 8920407197e1a5c6c3b16265bd796e8fe41ecd89..db7e362db19bebe563b7fdaa64197b72e0fcb21c 100644
--- a/tests/vufind.php_cs
+++ b/tests/vufind.php_cs
@@ -59,6 +59,11 @@ $rules = [
     'non_printable_character' => true,
     'ordered_imports' => true,
     'phpdoc_no_access' => true,
+    'php_unit_dedicate_assert_internal_type' => true,
+    'php_unit_expectation' => true,
+    'php_unit_method_casing' => true,
+    'php_unit_mock' => true,
+    'php_unit_no_expectation_annotation' => true,
     'single_blank_line_at_eof' => true,
     'single_class_element_per_statement' => true,
     'single_import_per_statement' => true,