xp-framework/unittest

此包已被废弃,不再维护。未建议替代包。

XP框架的单元测试

v11.4.1 2023-11-19 10:29 UTC

README

Build status on GitHub XP Framework Module BSD Licence Requires PHP 7.0+ Supports PHP 8.0+ Latest Stable Version

XP框架的单元测试

编写测试

测试位于类中,并使用 @test 属性进行注释。

use unittest\{Assert, Test};

class CalculatorTest {

  #[Test]
  public function addition() {
    Assert::equals(2, 1 + 1);
  }
}

要运行测试,请使用 test 子命令

$ xp test CalculatorTest
[.]

♥: 1/1 run (0 skipped), 1 succeeded, 0 failed
Memory used: 1672.58 kB (1719.17 kB peak)
Time taken: 0.000 seconds

断言方法

unittest 包提供了以下六个断言方法

public abstract class unittest.Assert {
  public static void equals(var $expected, var $actual, string $error)
  public static void notEquals(var $expected, var $actual, string $error)
  public static void true(var $actual, string $error)
  public static void false(var $actual, string $error)
  public static void null(var $actual, string $error)
  public static void instance(string|lang.Type $type, var $actual, string $error)
  public static void throws(string|lang.Type $type, callable $block)
}

如果您需要更多,可以在该库之上使用 xp-forge/assert

设置和清理

为了在测试运行前后运行方法,请使用 @before@after 属性对方法进行注释

use unittest\{Assert, Before, After, Test};

class CalculatorTest {
  private $fixture;

  #[Before]
  public function newFixture() {
    $this->fixture= new Calculator();
  }

  #[After]
  public function cleanUp() {
    unset($this->fixture);
  }

  #[Test]
  public function addition() {
    Assert::equals(2, $this->fixture->add(1, 1));
  }
}

注意:所有测试方法都使用同一个 CalculatorTest 实例运行!

期望异常

Expect 属性是手动捕获异常并验证其类型的快捷方式。

use lang\IllegalArgumentException;
use unittest\{Test, Expect};

class CalculatorTest {

  #[Test, Expect(IllegalArgumentException::class)]
  public function cannot_divide_by_zero() {
    (new Calculator())->divide(1, 0);
  }
}

忽略测试

可以使用 Ignore 属性来忽略测试。这可能是作为临时措施或在覆盖测试基类而不想运行其方法时所需的。

use unittest\{Test, Ignore};

class EncodingTest {

  #[Test, Ignore('Does not work with all iconv implementations')]
  public function transliteration() {
    /* ... */
  }
}

参数化

可以使用 Values 属性以各种参数运行测试。

use lang\IllegalArgumentException;
use unittest\{Test, Expect, Values};

class CalculatorTest {

  #[Test, Expect(IllegalArgumentException::class), Values([1, 0, -1])]
  public function cannot_divide_by_zero($dividend) {
    (new Calculator())->divide($dividend, 0);
  }
}

操作

要执行测试前后要运行的代码,可以使用测试操作。unittest 库提供了以下内置操作

  • unittest.actions.ExtensionAvailable(string $extension) - 验证指定的 PHP 扩展是否已加载。
  • unittest.actions.IsPlatform(string $platform) - 通过对 PHP_OS 进行不区分大小写的匹配来验证测试是否在指定的平台上运行。使用 ! 前缀来反转。
  • unittest.actions.RuntimeVersion(string $version) - 验证测试是否在指定的 PHP 运行时上运行。有关有效语法,请参阅 version_compare
  • unittest.actions.VerifyThat(function(): var|string $callable) - 运行给定的函数,验证它既不抛出异常也不返回一个假值。
use unittest\actions\{IsPlatform, VerifyThat};
use unittest\{Test, Action};

class FileSystemTest {

  #[Test, Action(eval: 'new IsPlatform("!WIN")')]
  public function not_run_on_windows() {
    // ...
  }

  #[Test, Action(eval: 'new VerifyThat(fn() => file_exists("/\$Recycle.Bin");')]
  public function run_when_recycle_bin_exists() {
    // ...
  }
}

可以通过将数组传递到 @action 属性来在测试周围运行多个操作。

进一步阅读