使用 Composer 和 autoload.php 在 PHPUnit 中自动加载类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15710410/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:48:36  来源:igfitidea点击:

Autoloading classes in PHPUnit using Composer and autoload.php

phpnamespacesphpunitautoloadcomposer-php

提问by Jasdeep Khalsa

I have just installed PHPUnit version 3.7.19 by Sebastian Bergmann via Composer and have written a class I would like to unit test.

我刚刚通过 Composer 安装了 Sebastian Bergmann 的 PHPUnit 3.7.19 版,并编写了一个我想进行单元测试的类。

I would like to have all my classes autoloaded into each unit test withouthaving to use includeor requireat the top of my test but this is proving to be difficult!

我希望将我所有的类自动加载到每个单元测试中,不必使用includerequire在我的测试顶部,但这被证明是困难的!

This is what my directory structure looks like (a trailing / slash indicates a directory, not a file):

这是我的目录结构的样子(尾部 / 斜杠表示目录,而不是文件):

  • composer.json
  • composer.lock
  • composer.phar
  • lib/
    • returning.php
  • tests/
    • returningTest.php
  • vendor/
    • bin/
      • phpunit
    • composer/
    • phpunit/
    • symfony/
    • autoload.php
  • 作曲家.json
  • composer.lock
  • 作曲家.phar
  • 库/
    • 返回.php
  • 测试/
    • 返回测试.php
  • 小贩/
    • 仓/
      • phpunit
    • 作曲家/
    • phpunit/
    • symfony/
    • 自动加载.php

My composer.jsonfile includes the following:

我的composer.json文件包括以下内容:

"require": {
    "phpunit/phpunit": "3.7.*",
    "phpunit/phpunit-selenium": ">=1.2"
}

My returning.phpclass file includes the following:

我的returning.php类文件包括以下内容:

<?php
class Returning {
    public $var;
    function __construct(){
        $this->var = 1;
    }
}
?>

My returningTest.phptest file includes the following:

我的ReturningTest.php测试文件包括以下内容:

<?php
class ReturningTest extends PHPUnit_Framework_TestCase
{
    protected $obj = null;

    protected function setUp()
    {
        $this->obj = new Returning;
    }

    public function testExample()
    {   
        $this->assertEquals(1, $this->obj->var);
    }

    protected function tearDown()
    {

    }
}
?>

However, when I run ./vendor/bin/phpunit testsfrom the command-line, I get the following error:

但是,当我从命令行运行时./vendor/bin/phpunit tests,出现以下错误:

PHP Fatal error: Class 'Returning' not found in /files/code/php/db/tests/returningTest.php on line 8

PHP 致命错误:在第 8 行的 /files/code/php/db/tests/returningTest.php 中找不到“Returning”类

I noticed that composerproduced an autoload.phpfile in vendor/autoload.phpbut not sure if this is relevant for my problem.

我注意到composer生成了一个autoload.php文件,vendor/autoload.php但不确定这是否与我的问题有关。

Also, in some other answers on Stack Overflow people have mentioned something about using PSR-0in composer and the namespacecommand in PHP, but I have not been successful in using either one.

此外,在 Stack Overflow 的其他一些答案中,人们提到了在Composer 中使用PSR-0namespace在 PHP 中使用命令的一些内容,但我没有成功使用任何一个。

Please help! I just want to autoload my classes in PHPUnit so I can just use them to create objects without worrying about includeor require.

请帮忙!我只想在 PHPUnit 中自动加载我的类,这样我就可以使用它们来创建对象而不必担心includerequire



Update: 14th of August 2013

更新:2013 年 8 月 14 日

I have now created an Open Source project called PHPUnit Skeletonto help you get up and running with PHPUnit testing easily for your project.

我现在创建了一个名为PHPUnit Skeleton 的开源项目,以帮助您轻松启动和运行 PHPUnit 测试项目。

回答by Wouter J

Well, at first. You need to tell the autoloader where to find the php file for a class. That's done by following the PSR-0 standard.

嗯,一开始。您需要告诉自动加载器在哪里可以找到类的 php 文件。这是通过遵循 PSR-0 标准完成的。

The best way is to use namespaces. The autoloader searches for a Acme/Tests/ReturningTest.phpfile when you requested a Acme\Tests\ReturningTestclass. There are some great namespace tutorials out there, just search and read. Please note that namespacing is notsomething that came into PHP for autoloading, it's something that can be used for autoloading.

最好的方法是使用命名空间。Acme/Tests/ReturningTest.php当您请求一个Acme\Tests\ReturningTest类时,自动加载器会搜索一个文件。那里有一些很棒的命名空间教程,只需搜索和阅读即可。请注意,命名空间不是PHP 用于自动加载的东西,它可以用于自动加载。

Composer comes with a standard PSR-0 autoloader (the one in vendor/autoload.php). In your case you want to tell the autoloader to search for files in the libdirectory. Then when you use ReturningTestit will look for /lib/ReturningTest.php.

Composer 带有一个标准的 PSR-0 自动加载器(在 中的那个vendor/autoload.php)。在您的情况下,您想告诉自动加载器搜索目录中的lib文件。然后当你使用ReturningTest它时会寻找/lib/ReturningTest.php.

Add this to your composer.json:

将此添加到您的composer.json

{
    ...
    "autoload": {
        "psr-0": { "": "lib/" }
    }
}

More information in the documentation.

文档中的更多信息。

Now the autoloader can find your classes you need to let PHPunit know there is a file to execute before running the tests: a bootstrap file. You can use the --bootstrapoption to specify where the bootstrap file is located:

现在自动加载器可以找到您需要让 PHPunit 知道在运行测试之前要执行的文件的类:引导文件。您可以使用该--bootstrap选项来指定引导文件所在的位置:

$ ./vendor/bin/phpunit tests --bootstrap vendor/autoload.php

However, it's nicer to use a PHPunit configuration file:

但是,使用PHPunit 配置文件更好:

<!-- /phpunit.xml.dist -->
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="./vendor/autoload.php">

    <testsuites>
        <testsuite name="The project's test suite">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>

</phpunit>

Now, you can run the command and it will automatically detect the configuration file:

现在,您可以运行该命令,它会自动检测配置文件:

$ ./vendor/bin/phpunit

If you put the configuration file into another directory, you need to put the path to that directory in the command with the -coption.

如果将配置文件放到另一个目录中,则需要在带有-c选项的命令中放置该目录的路径。

回答by Chuan Ma

[Update2] Another simpler alternative approach is to use the autoload-devdirective in composer.json(reference). The benefit is that you don't need to maintain two bootstrap.php (one for prod, one for dev) just in order to autoload different classes.

[ UPDATE2另一简单的替代方法是使用autoload-dev在指令composer.json参考)。好处是你不需要为了自动加载不同的类而维护两个 bootstrap.php(一个用于生产,一个用于开发)。

{
  "autoload": {
    "psr-4": { "MyLibrary\": "src/" }
  },
  "autoload-dev": {
    "psr-4": { "MyLibrary\Tests\": "tests/" }
  }
}

[Update] Wouter J's answer is more complete. But mine can help people who want to set up PSR-0 autoloading in tests/folder.
Phpunit scans all files with this pattern *Test.php. So we don't need to autoload them ourselves. But we still want to autoload other supporting classes under tests/such as fixture/stub or some parent classes.

[更新] Wouter J 的回答更完整。但是我的可以帮助想要在tests/文件夹中设置 PSR-0 自动加载的人。
Phpunit 使用此模式扫描所有文件*Test.php。所以我们不需要自己自动加载它们。但是我们仍然希望自动加载其他支持类,tests/例如夹具/存根或某些父类。

An easy way is to look at how Composer project itself is setting up the phpunit test. It's actually very simple. Note the line with "bootstrap".

一个简单的方法是查看 Composer 项目本身如何设置 phpunit 测试。其实很简单。注意带有“bootstrap”的那一行。

reference: https://github.com/composer/composer/blob/master/phpunit.xml.dist

参考:https: //github.com/composer/composer/blob/master/phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
         bootstrap="tests/bootstrap.php"
>
    <testsuites>
        <testsuite name="Composer Test Suite">
            <directory>./tests/Composer/</directory>
        </testsuite>
    </testsuites>

    <groups>
        <exclude>
            <group>slow</group>
        </exclude>
    </groups>

    <filter>
        <whitelist>
            <directory>./src/Composer/</directory>
            <exclude>
                <file>./src/Composer/Autoload/ClassLoader.php</file>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

reference: https://github.com/composer/composer/blob/master/tests/bootstrap.php

参考:https: //github.com/composer/composer/blob/master/tests/bootstrap.php

<?php

/*
* This file is part of Composer.
*
* (c) Nils Adermann <[email protected]>
* Jordi Boggiano <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

error_reporting(E_ALL);

$loader = require __DIR__.'/../src/bootstrap.php';
$loader->add('Composer\Test', __DIR__);

The last line above is autoloading phpunit test classes under the namespace Composer\Test.

上面的最后一行是在命名空间 Composer\Test 下自动加载 phpunit 测试类。

回答by Josh Ribakoff

None of these answers were what I was looking for. Yes PHPUnit loads test files, but not stubs/fixtures. Chaun Ma's answer doesn't cut it because running vendor/bin/phpunitalready includes the autoload, so there's no way to get an instance of the autoloader to push more paths to it's stack at that point.

这些答案都不是我想要的。是的 PHPUnit 加载测试文件,但不加载存根/夹具。Chaun Ma 的回答并没有削减它,因为运行vendor/bin/phpunit已经包括自动加载,因此此时无法获得自动加载器的实例以将更多路径推送到它的堆栈。

I eventually found this in the docs:

我最终在文档中找到了这个:

If you need to search for a same prefix in multiple directories, you can specify them as an array as such:

{
    "autoload": {
        "psr-0": { "Monolog\": ["src/", "lib/"] }
    }
}

如果您需要在多个目录中搜索相同的前缀,您可以将它们指定为一个数组,如下所示:

{
    "autoload": {
        "psr-0": { "Monolog\": ["src/", "lib/"] }
    }
}

回答by suspectus

There is a really simpleway to set up phpunit with autoloading and bootstap. Use phpunit's --generate-configurationoption to create your phpunit.xmlconfiguration in a few seconds-:

有一种非常简单的方法可以使用自动加载和引导程序来设置 phpunit。使用 phpunit 的--generate-configuration选项在几秒钟内创建您的phpunit.xml配置-:

vendor/bin/phpunit --generate-configuration

(Or just phpunit --generate-configurationif phpunit is set in your PATH). This option has been available from version phpunit5 and upwards.

(或者只是phpunit --generate-configuration在您的 PATH 中设置了 phpunit)。此选项从 phpunit5 及更高版本开始可用。

This option will prompt you for your bootstrap file (vendor/autoload.php), tests and source directories. If your project is setup with composer defaults (see below directory structure) the default options will be all you need. Just hit RETURN three times!

此选项将提示您输入引导程序文件 ( vendor/autoload.php)、测试和源目录。如果您的项目使用作曲家默认设置(请参见下面的目录结构),则默认选项将是您所需要的。只需按三下 RETURN 即可!

project-dir
   -- src
   -- tests
   -- vendor

You get a default phpunit.xml which is good to go. You can of course edit to include any specialisms (e.g. colors="true") you require-:

你会得到一个默认的 phpunit.xml,这是很好的。您当然可以编辑以包括您需要的任何专业(例如colors="true"):

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.1/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         executionOrder="depends,defects"
         forceCoversAnnotation="true"
         beStrictAboutCoversAnnotation="true"
         beStrictAboutOutputDuringTests="true"
         beStrictAboutTodoAnnotatedTests="true"
         verbose="true">
    <testsuites>
        <testsuite name="default">
            <directory suffix="Test.php">tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">src</directory>
        </whitelist>
    </filter>
</phpunit>

回答by yesnik

If you are using PHPUnit 7you can make your classes from src/folder to autoload in tests like this:

如果您使用的是PHPUnit 7,您可以使您的类从src/文件夹自动加载到这样的测试中:

  1. Ensure that your composer.jsonfile looks similar to this:

    {
        "autoload": {
            "classmap": [
                "src/"
            ]
        },
        "require-dev": {
            "phpunit/phpunit": "^7"
        }
    }
    
  2. To apply changesin composer.jsonrun command:

    composer install
    
  3. Finally you can run tests in tests/folder:

    ./vendor/bin/phpunit tests/
    
  1. 确保您的composer.json文件类似于以下内容:

    {
        "autoload": {
            "classmap": [
                "src/"
            ]
        },
        "require-dev": {
            "phpunit/phpunit": "^7"
        }
    }
    
  2. 更改应用composer.json运行命令:

    composer install
    
  3. 最后,您可以在tests/文件夹中运行测试:

    ./vendor/bin/phpunit tests/