10.2 单体测试
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 。
如果想设置全局默认,可以去 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
说明:
如果提示“Interpreter is not specified or invalid”, 要去 PhpStorm > Preferences > Languages & Frameworks > PHP 设置下 PHP 解释器。
添加单体测试
要创建单体测试,你必须在 tests/src/Unit/ 内创建一个以 Test.php 结尾的文件。象大多数 Drupal 8 特征那样,我们通过创建一个继承 UnitTestCase 的类创建测试。我们也使用 Drupal\Tests\[module_name]\Unit 作为所有测试类的名字空间。
tests/src/Unit/TestExampleConversionsTest.php 文件:(见辅助内容区)
- 测试方法
在这个测试里,我们只创建了一个测试和一个 setUp() 方法。每个测试是一个以 test 开头的方法。 - 断言
PHPUnit 运行每个函数,这些函数应该包含运行断言的语句。断言是测试结果,决定测试是否通过。有很多断言函数,如assertTrue
和assertFalse
。assertEquals
检查两参数是否相等。希望的结果作为第一个参数,测试结果作为第二个参数。例子里,我们测试服务把 0 摄氏度转换为 32 华氏度。 - setUp()
setUp
方法在每次测试之前会运行一次。我们使用它创建一个类变量(即测试的服务的实例),更复杂的测试可能需要更复杂的 set-up 方法。
<?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));
}
}
运行单体测试
在 PhpStorm 里你可以使用 Run 按钮运行单体测试。只测试这个模块很快。
添加较复杂的单体测试
单元测试会变得相当复杂。减少重复的代码的一个简单的方法是使用 setUp 方法,另一个方法是使用一个数据供应者。
数据供应者
PHPUnit 中的数据供应者是为测试方法提供配置的方法。供应者返回一个测试用例数组。
本例中,我们创建一个数据供应者 providerCentimetersToInches 。(见辅助内容区)
- 数据供应者注解
为了连接供应者,我们在测试方法上使用 @dataProvider 注解。 - 数据供应者参数
我们现在正在使用一个数据供应者,我们可以向测试方法添加参数。我们在数组内传递两个值,所以我们的测试方法应该有两个对应的参数。
/**
* 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));
单体测试其他信息
PHPUnit 支持很多其他特征。当你的服务依赖于其他类时你可以使用 Doubles,mocks 和 stubs 。你也可以列举依赖于其他测试的测试。使用 @depends 会等待依赖测试通过后这个测试才运行。