treshugart/testes

非常简单的单元和故事测试框架。

这个包的规范存储库似乎已消失,因此该包已被冻结。

1.1.0 2013-09-27 05:00 UTC

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));
    }
}

设置和清理

在您的测试类中,您可以定义setUptearDown方法,分别在测试方法执行前后执行代码。您可以在测试之前准备任何必要的代码,并在测试之后清理。

固定数据

通常,您会使用这些方法来准备测试的数据。这种测试数据通常称为固定数据或固定数据。固定数据的存在是为了模拟您的测试数据,并自动在其中的setUptearDown中执行,而不是让您在测试类中定义它。

一个固定数据至少必须定义一个生成其数据的方法

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

特此授予任何获得此软件及其相关文档文件(“软件”)副本的任何人无限制地使用该软件的许可,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许向软件提供者提供软件的人这样做,前提是符合以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何形式的保证,明示或暗示,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论这些责任是由于合同、侵权或其他行为引起的,无论这些责任是由于软件或其使用或其他任何方式引起的。