操作目录中的所有文件/类

时间:2013-11-24 16:13:34

标签: php phpunit

我刚刚开始使用PHPunit所以不确定我是否遗漏了一些基本的东西,但我想要一个测试用例:

  • 扫描特定的源目录,
  • 找到扩展名为.PHP的所有文件,
  • 然后尝试实例化这些文件所代表的每个类
  • 测试每个类从特定调用返回正确的属性(此目录中的所有类都是公共基类的子类型)

有意义吗?设置代码如下所示:

protected function setUp() {
    $this->documentFiles = glob('*.php');
    $this->documentClasses = array_map(function($file) {
         return substr($file,0,count($file)-5); // strip off ".php"
    }, $this->documentFiles);
}

然后实例化测试将是:

public function testInstantiation() {
    foreach($this->documentClasses as $class) {
        try {
            $object = new $class;
        } catch (Exception $e) {
            fail("Failure to instantiate '{$class}': " + $e.getMessage());
        }
    }
}

现在测试正在通过,因为$ CWD不是正确的目录,因此它没有获取任何PHP文件。

有没有办法指定工作目录应该是什么?理想情况下,这是一种相对于项目根的方式(因此抽象出物理文件系统)。

P.S。我的项目符合PSR-0的价值

3 个答案:

答案 0 :(得分:1)

我看到至少2次Unittests: 测试找到所有带有类的php文件 测试那些类是否按预期调用。

通常你也会用测试来测试文件系统,这是一种不好的做法。当然,如果你没有这样做,你的被叫类也需要在separeted测试中进行测试。

我不知道你的类结构所以我只能猜测你至少创建了一个类来读取给定目录下的文件,一个获取类名的类(应该是一块psr-0蛋糕)和一个从该列表创建对象的类。这样你可以模拟依赖关系,并且对文件系统的访问被简化为一个简单的类,当它被模拟时不会影响其他测试。

我建议使用DirectoryIterator或FilesystemIterator,具体取决于您使用的是哪个php版本。

答案 1 :(得分:0)

  

有没有办法指定工作目录应该是什么?

您可以使用chdir。您也可以将完全限定的路径传递给glob

glob(__DIR__ . '/*.php');
但是,我不认为你的解决方案是好的。使用data provider并返回一组实例(或类名作为字符串)。测试时会得到更好的错误消息,如果更改目录结构,它将不会中断。

<?php
class SomeExampleTest extends \PHPUnit_Framework_TestCase
{
    public function nameProvider()
    {
        return array(
            array(new Vendor\Package\ClassName()),
            array(new Vendor\Package\ClassNameAgain()),
        );
    }

    /**
     * @dataProvider nameProvider
     */
    public function testSomeMethod($obj)
    {
        // do some assertions
        $this->assertEquals('something', $obj->theMethodYouWantToTest());
    }
}

答案 2 :(得分:0)

好的,我已经能够达到我想要的结果,但我想知道是否有更精明的“PHPunit”方式。如果你这样做,请告诉我。

我发现CWD是/tests/目录。这可能有点脆弱,因为它很容易从进一步进入测试链的某个地方运行,但在大多数情况下这些天对我来说都没问题。然后我可以将setUp()方法更改为:

protected function setUp() {
    $namespace = "\\path\\to\\classes\\";
    $this->documentFiles = glob('../src/path/to/classes/*.php');
    $this->documentClasses = array_map(function($file) use ($namespace) {
        if (preg_match('/.*\/(.*)\.php/',$file,$matches) === 1)
            return $namespace . $matches[1];
        else
            return null;
    }, $this->documentFiles);
}

正如我所说,它有效。我很乐意认为有更多的“内置”方式可以做这样的事情,但我对PHPunit来说是全新的。