Drupal 8 模块开发 10.2 : 单元测试

蒲公英 提交于 周四, 08/17/2017 - 17:27
Drupal8模块开发

原文地址:
https://docs.acquia.com/articles/drupal-8-unit-testing  


Drupal 附带了一个 PHPUnit,但你需要确保它配置正确。我们假设你正使用 PhoStorm,但你也可以从命令行运行这些测试。  

何时你应该创建单元测试?

服务最有意义做单元测试,因为它们被设计为独立存在。围绕测什么有很多争论。首先测试你的所有服务方法,之后根据需要添加测试,这样进行测试可能比较有用。  

在 PhpStorm 内配置 PHPUnit

配置项目:

  1. 导航到 PhpStorm > Preferences > Languages & Frameworks > PHP > PHPUnit > Local
    Window 操作系统是:File > Settings ...
  2. 选择 PHPUnit Library > Use custom autoloader
  3. 导航到 /vendor/autoload.php
  4. 选择 Test Runner > Default configuration file
  5. 导航到 /core/phpunit.xml.dist
  6. 点击 Save

上面是针对项目进行的设置。你可以在右上方看到 For current project
接下来完成下面的步骤:

  1. 运行: Run > Edit Configurations
  2. 点击 + 图标,选择 PHPUnit
  3. 提供一个名称,例如 Drupal 8: All Tests
  4. 在配置文件内选择 Test Runner > Defined
  5. 保存

在右上角,确保选择了你的运行配置,按下绿色箭头。也可以操作 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 将运行很多测试。要把测试区域限制为一个文件夹(我们的模块)可以象下面这样做:

  1. 运行: Run > Edit Configurations
  2. 点击 + 图标选择 PHPUnit
  3. 提供个名称,例如 Drupal 8: Test Example
  4. 选择 Test Runner > Test Scope > Directory
  5. 浏览 test_example 模块
  6. 点击 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 会等待依赖测试通过后这个测试才运行。