vasek-purchart/phing-tester

使用 PHPUnit 编写 Phing 组件测试的辅助工具

2.1 2022-03-24 09:53 UTC

README

Phing 是一个可以通过编写 PHP 代码来扩展的构建系统。这非常有用,尤其是对于 PHP 项目来说,因为它不需要任何额外的技术,并且可以潜在地重用现有代码。但是,当你编写这样的扩展时,你也应该测试它们。由于构建系统的本质是打印输出、操作文件和其他“系统”操作,因此编写隔离测试成为一个问题。Phing Tester 应该通过提供一种从 PHPUnit 测试中运行 Phing 目标的方式,就像它们是从命令行本身运行一样来帮助解决这个问题。

使用方法

使用 Phing Tester,您可以像往常一样使用 Phing 编写 XML 构建文件,然后从 PHP 代码中运行其目标。

<?xml version="1.0" encoding="utf-8"?>
<!-- phing-tester-example.xml -->
<project name="PhingTesterExample" default="lorem-ipsum">

	<target name="lorem-ipsum">
		<echo>Lorem ipsum dolor sit amet</echo>
	</target>

</project>
<?php

use VasekPurchart\Phing\PhingTester\PhingTester;

$tester = new PhingTester(__DIR__ . '/phing-tester-example.xml');
$tester->executeTarget('lorem-ipsum');

测试输出

在上面的例子中,目标 lorem-ipsum 在构建文件的上下文中执行,然后您可以检查目标是否达到预期,在这种情况下,它应该打印出一条消息。对于测试目的,如果实际输出被打印出来,将会有问题,因此 Phing Tester 提供了用于输出检查的方法,如:

<?php

$tester->assertLogMessage('Lorem ipsum');

assertLogMessage 搜索所有日志消息,如果其中任何包含指定的字符串。您也可以使用正则表达式搜索日志消息。如果需要指定生成消息的目标和/或其优先级,以便通过指定目标名称和输出优先级来最小化误报/漏报,这会很有用。

测试错误

如果构建失败,则 Phing 会像往常一样抛出 \BuildException。如果您只想测试异常及其消息,可以使用标准的 PHPUnits 工具。

<?php

$this->expectException(\BuildException::class);
$this->expectExceptionMessage('My error');

但是,如果您还想检查目标执行后的状态,这还不够,因为测试中的代码被异常中断了。如果您想这样做,请使用 expectFailedBuild 而不是 executeTarget,然后您可以继续使用断言。

<?php

$tester->expectFailedBuild($target);

$tester->assertLogMessage('Fail message', $target, Project::MSG_ERR);

如果您需要彻底检查抛出的异常,可以将回调传递给 expectFailedBuild,您将获得异常作为参数。

<?php

$tester->expectFailedBuild($target, function (\BuildException $e) use ($target) {
	$this->assertRegExp(sprintf('~%s.+not.+exist~', $target), $e->getMessage());
});

测试属性

当编写 Phing 测试时,您可能想检查某些属性的状态或使用它们来编写其他断言。

<?php

$this->assertSame('bar', $tester->getProject()->getProperty('foo'));

规范

没有强制执行的规范来使用此工具,您可以在测试中按自己的方式使用它,但这种方法在可读性方面对我最有用。

  1. 将一个 TestCase 与一个构建文件匹配。
  2. 构建文件中的目标表示单个测试,其名称匹配(如果没有必要重用目标或使用多个目标进行单个测试)。
  3. 当断言日志输出时,尽量更具体一些——使用目标名称和输出优先级来最小化误报/漏报。

这对可以看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<!-- phing-tester-convention-example.xml -->
<project name="PhingTesterConventionExample" default="test">

	<target name="testFoo">
		<echo>Foo</echo>
	</target>

	<target name="testBar">
		<echo>Bar</echo>
	</target>

</project>
<?php

use VasekPurchart\Phing\PhingTester\PhingTester;

class PhingTesterConventionExampleTest extends \PHPUnit\Framework\TestCase
{

	public function testFoo()
	{
		$tester = new PhingTester(__DIR__ . '/phing-tester-convention-example.xml');
		$target = __FUNCTION__;
		$tester->executeTarget($target);

		$tester->assertLogMessage('Foo', $target, Project::MSG_INFO);
	}

	public function testBar()
	{
		$tester = new PhingTester(__DIR__ . '/phing-tester-convention-example.xml');
		$target = __FUNCTION__;
		$tester->executeTarget($target);

		$tester->assertLogMessage('Bar', $target, Project::MSG_INFO);
	}

}

安装

  1. 使用 Composer 安装包 vasek-purchart/phing-tester
composer require --dev vasek-purchart/phing-tester
  1. 将 Phing 初始化添加到您的测试引导文件中(此存储库中的示例
Phing::startup();