原文地址:
https://docs.acquia.com/articles/drupal-8-unit-testing
Drupal 附带了一个 PHPUnit,但你需要确保它配置正确。我们假设你正使用 PhoStorm,但你也可以从命令行运行这些测试。
何时你应该创建单元测试?
服务最有意义做单元测试,因为它们被设计为独立存在。围绕测什么有很多争论。首先测试你的所有服务方法,之后根据需要添加测试,这样进行测试可能比较有用。
在 PhpStorm 内配置 PHPUnit
配置项目:
- 导航到 PhpStorm > Preferences > Languages & Frameworks > PHP > PHPUnit > Local
Window 操作系统是:File > Settings ... - 选择 PHPUnit Library > Use custom autoloader
- 导航到 /vendor/autoload.php
- 选择 Test Runner > Default configuration file
- 导航到 /core/phpunit.xml.dist
- 点击 Save
上面是针对项目进行的设置。你可以在右上方看到 For current project。
接下来完成下面的步骤:
- 运行: Run > Edit Configurations
- 点击 + 图标,选择 PHPUnit
- 提供一个名称,例如 Drupal 8: All Tests
- 在配置文件内选择 Test Runner > Defined
- 保存
在右上角,确保选择了你的运行配置,按下绿色箭头。也可以操作 Run > Run Drupal 8: All Tests 。
说明: 如果提示“Interpreter is not specified or invalid”, 要去 PhpStorm > Preferences > Languages & Frameworks > PHP 设置下 PHP 解释器。
如果想设置全局默认,可以去 File > Default Settings,但对于 Drupal 8 项目这不是必须的。
当你运行测试时,你会在 PhpStorm 内看到一个新窗口,列出了测试结果。默认情况,通过的测试不会显示出来。你可以操作窗口左上角的 Hide passed 图标显示通过的测试。
测试一个指定区域
PHPUnit 将运行很多测试。要把测试区域限制为一个文件夹(我们的模块)可以象下面这样做:
- 运行: Run > Edit Configurations
- 点击 + 图标选择 PHPUnit
- 提供个名称,例如 Drupal 8: Test Example
- 选择 Test Runner > Test Scope > Directory
- 浏览 test_example 模块
- 点击 Save
添加单元测试
要创建单元测试,你必须在 tests/src/Unit/ 内创建一个以 Test.php 结尾的文件。象大多数 Drupal 8 特征那样,我们通过创建一个继承 UnitTestCase 的类创建测试。我们也使用 Drupal\Tests\[module_name]\Unit 作为所有测试类的名字空间。
tests/src/Unit/TestExampleConversionsTest.php 文件:
<?php /** * @file * * Contains \Drupal\Tests\test_example\Unit\TestExampleConversionsTest. */ namespace Drupal\Tests\test_example\Unit; use Drupal\Tests\UnitTestCase; /** * Demonstrates how to write tests. * * @group test_example */ class TestExampleConversionsTest extends UnitTestCase { /** * @var \Drupal\test_example\TestExampleConversions */ public $conversionService; public function setUp() { $this->conversionService = new \Drupal\test_example\TestExampleConversions(); } /** * A simple test that tests our celsiusToFahrenheit() function. */ public function testOneConversion() { // Confirm that 0C = 32F. $this->assertEquals(32, $this->conversionService->celsiusToFahrenheit(0)); } }
- 测试方法
在这个测试里,我们只创建了一个测试和一个 setUp() 方法。每个测试是一个以 test 开头的方法。 - 断言
PHPUnit 运行每个函数,这些函数应该包含运行断言的语句。断言是测试结果,决定测试是否通过。有很多断言函数,如 assertTrue 和 assertFalse 。assertEquals 检查两参数是否相等。希望的结果作为第一个参数,测试结果作为第二个参数。例子里,我们测试服务把 0 摄氏度转换为 32 华氏度。 - setUp()
setUp 方法在每次测试之前会运行一次。我们使用它创建一个类变量(即测试的服务的实例),更复杂的测试可能需要更复杂的 set-up 方法。
运行单元测试
在 PhpStorm 里你可以使用 Run 按钮运行单元测试。只测试这个模块很快。
添加较复杂的单元测试
单元测试会变得相当复杂。减少重复的代码的一个简单的方法是使用 setUp 方法,另一个方法是使用一个数据供应者。
数据供应者
PHPUnit 中的数据供应者是为测试方法提供配置的方法。供应者返回一个测试用例数组。
本例中,我们创建一个数据供应者 providerCentimetersToInches 。
/** * Provides data for the testCentimetersToInches method. * * @return array */ public function providerCentimetersToInches() { return [ [2.54,1], [254,100], [0,0], [-2.54,-1], ]; } /** * Tests centimetersToInches method. * * @dataProvider providerCentimetersToInches */ public function testCentimetersToInches($length, $expectedValue) { $this->assertEquals($expectedValue, $this->conversionService->centimeterToInch($length)); }
- 数据供应者注解 为了连接供应者,我们在测试方法上使用 @dataProvider 注解。
- 数据供应者参数 我们现在正在使用一个数据供应者,我们可以向测试方法添加参数。我们在数组内传递两个值,所以我们的测试方法应该有两个对应的参数。
单元测试其他信息
PHPUnit 支持很多其他特征。当你的服务依赖于其他类时你可以使用 Doubles,mocks 和 stubs 。
你也可以列举依赖于其他测试的测试。使用 @depends 会等待依赖测试通过后这个测试才运行。