treshugart / testes
非常简单的单元和故事测试框架。
这个包的规范存储库似乎已消失,因此该包已被冻结。
Requires
- php: >=5.4.0
Requires (Dev)
- ext-xdebug: *
- devco/event-emitter: 1.0.*-dev
This package is not auto-updated.
Last update: 2022-07-23 02:52:04 UTC
README
Testes - 原谅我的用词 - 是一个用PHP 5.4编写的非常简单的测试框架。其目标是实现简单、快速和可维护的测试。
设置
要设置Testes,您只需确保您的测试与psr-0
自动加载器兼容,并且您的测试所在的目录已注册为自动加载路径。
如果您喜欢,Testes附带了可以为您做这件事的自动加载器
require '../lib/Testes/Autoloader/Autoloader.php';
Testes\Autoloader\Autoloader::register('./tests');
之后,您只需要设置您的测试层次结构。实际上,您需要做的只是确保您已经组织好了测试,以便您和您的同事可以轻松浏览测试。
- tests
- 测试
- 子文件夹
- SomeTest.php
- 子文件夹
- 测试
SomeTest
类可以定义为
namespace Test\Subfolder;
use Testes\Test\UnitAbstract;
class SomeTest extends UnitAbstract
{
...
}
测试方法
测试方法是任何不属于任何父类或实现接口的公共方法。这意味着像setUp()
和tearDown()
这样的公共方法不是有效的测试方法,不会作为测试的一部分运行。
一些好的测试名称
- makeSureAllPropertiesAreSetWhenHydrating()
- testAssertionAggregation()
- completeRequestDispatchingTest()
您不能将测试方法定义为测试套件的一部分。它们必须在测试类中存在。
有两种类型的测试:单元测试和故事。
单元测试
单元测试从Testes\Test\UnitAbstract
类派生。这通常是您测试小代码单元而不是行为的时候。
故事
故事从Testes\Test\StoryAbstract
派生。它们遵循“给定 ... 当 ... 然后 ...”的约定来描述测试用例。定义这些场景的方法应该是public
。处理场景各个部分的方法应该是protected
。
<?php
namespace Test;
use Testes\Test\StoryAbstract;
class MyStory extends StoryAbstract
{
private $request;
private $error;
public function ensureProperError()
{
$this->given('a bad request')->when('an error occurs')->then('an error should be returned');
}
protected function givenABadRequest()
{
$this->request = ...;
}
protected function whenAnErrorOccurs()
{
if (!$this->request) {
$this->error = 'Some error message.';
}
}
protected function thenAnErrorShouldBeReturned()
{
$this->assert($this->error && is_string($this->error));
}
}
设置和清理
在您的测试类中,您可以定义setUp
和tearDown
方法,分别在测试方法执行前后执行代码。您可以在测试之前准备任何必要的代码,并在测试之后清理。
固定数据
通常,您会使用这些方法来准备测试的数据。这种测试数据通常称为固定数据或固定数据。固定数据的存在是为了模拟您的测试数据,并自动在其中的setUp
和tearDown
中执行,而不是让您在测试类中定义它。
一个固定数据至少必须定义一个生成其数据的方法
class MyFixture extends Testes\Fixture\FixtureAbstract
{
public static function generateData()
{
return [
'id' => 1,
'name' => 'value'
];
}
}
现在,您将使用测试类中的setUp
方法将此固定数据添加到测试中
$this->setFixture('myfixture', new MyFixture);
此固定数据在测试方法中可访问
$data = $this->getFixture('myfixture');
$name = $data->name;
$value = 'value';
$this->assert($name === $value, 'The data is not valid.');
但是,您可以在测试方法之外访问固定数据。您可能需要这样做,以便将两个固定数据相关联
class SomeOtherFixture extends Testes\Fixture\FixtureAbstract
{
public static function generateData()
{
return [
'id' => 2,
'link' => MyFixture::id(),
'name' => 'value'
];
}
}
断言
您的测试类包含一个名为assert
的单个断言方法。
$this->assert($something, $message);
您可能会问为什么没有更多的断言方法。以下是一个示例:
assert($value === true, 'message');
assertEquals($value, true, 'message');
前面的断言实际上比后面的更易读,甚至更短。
运行测试
我们使用查找器来查找我们的测试
$finder = new Testes\Finder\Finder('/path/to/tests');
然后我们使用查找器运行测试,它返回已运行的测试套件
$suite = $finder->run();
我们可以使用套件来获取有关测试的信息
echo sprintf(
'Tests were completed in "%d" milliseconds and used "%s" bytes of memory.',
$suite->getTime(),
$suite->getMemory()
);
如果您只想运行特定的测试子集,可以向查找器传递一个命名空间
$finder = new Testes\Finder\Finder('/path/to/tests', 'Test/Subfolder');
分析覆盖率
可以在启动覆盖率分析后运行测试来完成覆盖率分析。
$coverage = new Testes\Coverage\Coverage;
$coverage->start();
// run tests
...
$analyzer = $coverage->stop();
您需要告诉分析器基于哪些文件进行覆盖率分析。一种方法是将文件目录添加进去
$analyzer->addDirectory('/path/to/code/needing/coverage');
您还可以添加特定的文件
$analyzer->addFile('/path/to/single/file/to/analyze.php');
一旦添加了一些文件,您可以根据需要过滤它们
$analyzer->is('.php$');
分析器提供了大量信息,例如哪些行没有被测试
// percent tested
echo $analyzer->getPercentTested(2) . PHP_EOL . PHP_EOL;
// untested files are files that are not 100% tested
foreach ($analyzer->getUntestedFiles() as $file) {
foreach ($analyzer->getUntestedLines() as $line) {
echo $line . PHP_EOL;
}
}
渲染输出
很多时候,您需要将结果以某种格式输出,以便像构建服务器这样的工具可以消费。为此,我们提供了JUnit格式。
$renderer = new Testes\Renderer\Junit;
$rendered = $renderer->render($suite);ch
file_put_contents('junit.xml', $rendered);
许可
版权(c)2005-2013 Trey Shugart
特此授予任何获得此软件及其相关文档文件(“软件”)副本的任何人无限制地使用该软件的许可,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许向软件提供者提供软件的人这样做,前提是符合以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何形式的保证,明示或暗示,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论这些责任是由于合同、侵权或其他行为引起的,无论这些责任是由于软件或其使用或其他任何方式引起的。