【问题标题】:Passing parameters to PHPUnit将参数传递给 PHPUnit
【发布时间】:2011-01-06 21:19:15
【问题描述】:

我开始编写 PHPUnit 测试,我希望在开发人员的机器和我们的服务器上运行这些测试。开发人员机器的设置与服务器不同,甚至彼此不同。

要在这些不同的地方运行,运行测试的人似乎必须指出它在哪里运行。然后测试可以查找运行它的机器的正确配置。

我在想象这样的事情:

phpunit.bat -X johns_laptop unittest.php

或在 alpha 服务器上:

phpunit -X alpha unittest.php

在测试中,如果是“X”(或其他任何参数)参数,我将能够获取该值,并且例如知道这台机器的应用程序根路径是什么。

命令行似乎不允许这样做 - 还是我错过了什么?

【问题讨论】:

    标签: php phpunit


    【解决方案1】:

    您可以为此使用 PHPUnit 的 --bootstrap 开关。

    --bootstrap <file>       A "bootstrap" PHP file that is run before the tests.
    

    然后,制作一个包含变量的 bootstrap.php 文件:

    $port = 4445;
    

    在您的测试中,您可以获取这些值:

    global $port;
    $this->setPort($port);
    

    然后运行:

    phpunit --bootstrap boot.php MyTest.php
    

    【讨论】:

    • 我认为这个解决方案比 Paulo 已经选择的答案更恰当地回答了原始问题。这就是引导文件的确切用途。
    • @WallyLawless 有时值无法硬编码,需要作为 CL 参数动态发送
    • 这当然很有用,但错过了原始问题的重点,即如何在命令行传递参数。
    • 只是为了澄清:引导文件中的任何指令必须以&lt;?php开头。
    【解决方案2】:

    一种方法是检查 $argv 和 $argc。比如:

    <?php
    
    require_once 'PHPUnit/Framework/TestCase.php';
    
    class EnvironmentTest extends PHPUnit_Framework_TestCase {
        public function testHasParam() {
                global $argv, $argc;
                $this->assertGreaterThan(2, $argc, 'No environment name passed');
                $environment = $argv[2];
        }
    }
    

    然后你可以像这样调用你的 phpunittest:

    phpunit EnvironmentTest.php my-computer
    

    【讨论】:

    • 这听起来很有希望,我会试试的
    • phpunit 也使用参数,这样你根本不能使用它们
    • 第一个方法被删除了。谢谢@jimbo。我只是想展示扩展点,但我想这是 PHPUnit 的常识
    • @Paolo , phpunit 认为 my-computer 是一个测试文件并寻找 my-computer.php
    • 仍然是一个非常好的解决方案,也不会触发“风险”警告
    【解决方案3】:

    将变量传递给引导文件和测试文件的一种优雅方式是使用环境变量:

    export MY_ENV_VAR="some value"
    
    phpunit all
    

    然后,在您的 PHP 文件中,您可以像这样访问它:

    getenv('MY_ENV_VAR')
    

    来源:http://blog.lysender.com/2010/10/phpunit-passing-environment-variable-to-your-application/

    【讨论】:

    • 我需要使用export MY_ENV_VAR="some value" 来完成这项工作。
    【解决方案4】:

    正如 Jasir 已经提到的,单行解决方案是在调用 phpunit 之前设置环境变量。

    在 Linux 上:

    X=alpha phpunit unittest.php
    

    可能在 Windows 上:

    set X=johns_laptop && phpunit.bat unittest.php
    

    在你的脚本里面使用

    getenv('X')
    

    读取值

    【讨论】:

      【解决方案5】:

      我不认为上面的答案能解决我同样的问题。

      接受的答案并不完美。这样,自定义选项应始终放在参数列表的末尾,并且没有指示符告诉它们是自定义选项。如果我需要的自定义选项的数量不固定,我应该编写很多代码来使用正则表达式或类似的东西解析自定义选项。

      环境变量解决方案不错,但不自然。看起来很奇怪。

      VAR1=aaa VAR2=bbb VAR3=ccc ./phpunit-custom-option CustomOptionTest.php
      

      shell 脚本加上 setUp() 解决方案与公认的解决方案有相同的弱点。可能您应该编写大量代码来解析文件并处理不可预测数量的自定义选项。

      我认为引导脚本不是正确的解决方案。它可以用来自动处理脏工作,每次都做同样的事情,但不能很好地处理变更部分。

      我不喜欢上面所有的答案。

      我自己也没有好主意。但也许我所做的可以给你灵感。我在 GitHub 上 fork 了 phpunit 项目,并稍微修改了代码,使其支持自定义选项功能。

      phpunit 的修改版本,可以接受这样的自定义选项:

      ./phpuint-custom-option --custom var1=value1 --custom var2=value2 CustomOptionTest.php
      

      并且在测试中,你可以通过访问超级全局变量$_SERVER来访问自定义选项

      <?php
      
      class CustomOptionTest extends PHPUnit_Framework_TestCase {
      
          public function testCustomOption() {
              $this->assertEquals('value1', $_SERVER['var1']);
              $this->assertEquals('value2', $_SERVER['var2']);
          }
      }
      

      您可以找到我的代码here,并下载修改后的版本here(点击页面上的“查看完整文件”链接)。

      仅供参考。 this article 是类似的解决方案。

      【讨论】:

        【解决方案6】:

        这里的所有解决方案都适用于该问题,但在某些情况下还有另一种方法可能更简单。 Phing 将接受以 -Dargument=value 形式传递的参数

        所以使用 phing -Dtest=MyTest.class.php

        然后您可以使用 phing 条件来处理这些参数:

        <if>
            <isset property="test" />
            <then>
                <property name="testFile" value="${test}" />
            </then>
            <else>
                <property name="testFile" value="AllTests.php" />
            </else>
        </if>
        <exec command="phpunit --bootstrap myTestFile/bootstrap.php- myTestFolder/${testFile}"
              passthru="true" returnproperty="phpunitreturn" />
        

        【讨论】:

          【解决方案7】:

          我在这个确切的问题上苦苦挣扎,并想出了一种 hacky 但又方便的解决方案:我将参数写入磁盘上的文件并在 setUp() 方法中检索它们:

          public function setUp() {
              $this->setBrowser('firefox');
              $this->base_url = file_get_contents("selenium_host");
              $this->setBrowserUrl($this->base_url);
          }
          

          我没有直接调用phpunitparatest,而是有一个shell 脚本来启动测试。这个调用paratest 并让我指定进程数以及我希望运行测试的主机。

          run_all_tests.sh

          if [ $1 ] 
          then
              threads=$1
          else
              threads=5
          fi
          if [ $2 ]
          then
              echo $2 > selenium_host
          else
              echo 'http://defaulthost.com' > selenium_host
          fi
          
          vendor/bin/paratest -p$threads -f --colors TestSuite.php
          

          然后,使用 7 个线程针对 http://adifferenthost.com 运行:

          ./run_all_tests.sh 7 'http://adifferenthost.com'

          【讨论】:

            【解决方案8】:

            如果您想在每次测试运行时改变测试参数,在命令行上传递参数是有意义的。在不同的机器上运行特定于主机的测试并不是该解决方案的最佳理由。

            为此,PHPUnit configuration file 可能被证明更合适。它使您可以控制主机甚至请求特定的变量,包括操作php.ini 设置以及定义常量、全局变量、$_ENV$_SERVER,甚至$_GET$_POST 等。这是全部在配置文件的&lt;php&gt;节点下完成,见Setting PHP INI settings, Constants and Global Variables

            Symfony2 使用这种方法并为您的单元测试提供phpunit.xml.dist(默认配置)和phpunit.xml。后者是 gitignored 允许您为每台机器自定义它而不影响 repo。然后你会运行你的测试:

            phpunit -c /path/to/phpunit.xml
            

            【讨论】:

              【解决方案9】:

              不需要环境变量或特殊脚本。您可以使用-d 选项设置php.ini 值。

              <?php // tests/IniTest.php
              use PHPUnit\Framework\TestCase;
              
              class IniTest extends TestCase
              {
                public $server;
              
                public function setUp(): void
                {
                  $this->server = ini_get('my.custom.server') ?: '127.0.0.1'; // fallback
                }
              
                public function testDummy()
                {
                  $this->assertIsString($this->server);
                }
              }
              

              像这样执行代码:

              vendor/bin/phpunit -d my.custom.server=192.168.1.15 tests/IniTest.php
              

              设置自定义php.ini 值是有效的。例如,您可以使用pdo.dsn.* 配置PDO 连接别名https://www.php.net/manual/en/pdo.construct.php

              【讨论】:

                【解决方案10】:

                如果您想在远程机器上运行测试,请使用 ssh 然后运行它。在语言环境机器上,您只需 cd 到您的根目录,然后运行 ​​phpunit。

                user@local:/path/to/your/project$ phpunit
                user@remote:/var/www/project$ phpunit
                

                编辑:您说的是与机器相关的配置。 (顺便说一句,什么样的配置?)我的解决方案是将这些配置放在相同的,而不是版本控制的地方,然后在运行时读取/解析它,例如在所需的设置方法中。

                【讨论】:

                • 我知道如何运行 phpunit。我的问题是如何将配置信息传递给它,以便它可以知道该机器的配置?
                • 我想我明白你的建议了。问题是我希望对配置进行版本控制。它们可能会随着时间而改变,我想跟踪它们。
                • @dl:这对我来说没有意义。如果你想对配置进行版本控制,那么为什么它们在不同的机器上会有所不同?
                • 它们是不同的,因为它们位于不同的人所拥有的不同机器上,这些人以自己的方式设置它们。所以我将有一个配置文件(一个 YANL 文件)分成不同的部分,每台机器一个部分。运行测试时,用户必须指定机器名称,以便可以从配置中读取正确的部分。我希望它受版本控制,例如,当我从 alpha 服务器中删除文件时,我可以从版本控制中恢复并且配置恢复。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-02-21
                • 2019-09-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多