phpunit:如何在测试之间传递值?

phpunit: How do I pass values between tests?

我真的 运行 对此一头雾水。你如何在 phpunit 中的测试之间传递 class 值?

测试 1 -> 设置值,

测试 2 -> 读取值

这是我的代码:

class JsonRpcBitcoinTest extends PHPUnit_Framework_TestCase
{
    public function setUp(){
        global $configRpcUser, $configRpcPass, $configRpcHost, $configRpcPort;

        $this->bitcoindConn = new JsonRpcBitcoin($configRpcUser, $configRpcPass, $configRpcHost, $configRpcPort);
        $this->blockHash = '';
    }

    /**
    * @depends testCanAuthenticateToBitcoindWithGoodCred
    */
    public function testCmdGetBlockHash()
    {   
        $result = (array)json_decode($this->bitcoindConn->getblockhash(20));
        $this->blockHash = $result['result'];
        $this->assertNotNull($result['result']);
    }

    /**
    * @depends testCmdGetBlockHash
    */
    public function testCmdGetBlock()
    {   
        $result = (array)json_decode($this->bitcoindConn->getblock($this->blockHash));
        $this->assertEquals($result['error'], $this->blockHash);
    }
}

testCmdGetBlock() 未获取应在 testCmdGetBlockHash().

中设置的 $this->blockHash 的值

帮助理解问题所在将不胜感激。

setUp() 方法总是在测试之前调用,因此即使您在两个测试之间设置了依赖关系,setUp() 中设置的任何变量都将被覆盖。 PHPUnit 数据传递的工作方式是从一个测试的 return 值到另一个测试的参数:

class JsonRpcBitcoinTest extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
        global $configRpcUser, $configRpcPass, $configRpcHost, $configRpcPort;

        $this->bitcoindConn = new JsonRpcBitcoin($configRpcUser, $configRpcPass, $configRpcHost, $configRpcPort);
        $this->blockHash = '';
    }


    public function testCmdGetBlockHash()
    {   
        $result = (array)json_decode($this->bitcoindConn->getblockhash(20));
        $this->assertNotNull($result['result']);

        return $result['result']; // the block hash
    }


    /**
     * @depends testCmdGetBlockHash
     */
    public function testCmdGetBlock($blockHash) // return value from above method
    {   
        $result = (array)json_decode($this->bitcoindConn->getblock($blockHash));
        $this->assertEquals($result['error'], $blockHash);
    }
}

因此,如果您需要在测试之间保存更多状态,return 该方法中的更多数据。我猜想 PHPUnit 之所以如此烦人是为了阻止相关测试。

See the official documentation for details.

您可以在函数中使用静态变量... PHP 烦人地与所有实例共享 class 方法的静态变量......但在这个 cas 中它可以帮助 :p

protected function &getSharedVar()
{
    static $value = null;
    return $value;
}

...

public function testTest1()
{
    $value = &$this->getSharedVar();

    $value = 'Hello Test 2';
}


public function testTest2()
{
    $value = &$this->getSharedVar();

    // $value should be ok
}

注意:这不是好方法,但如果您在所有测试中都需要一些数据,它会有所帮助...

这对我来说在所有测试中都非常有效:$this->varablename

class SignupTest extends TestCase
{
    private $testemail = "registerunittest@company.com";
    private $testpassword = "Mypassword";
    public $testcustomerid = 123;
    private $testcountrycode = "+1";
    private $testphone = "5005550000";

    public function setUp(): void
    {
        parent::setUp();
    }

    public function tearDown(): void 
    {
        parent::tearDown();
    }

    public function testSignup()
    {
        $this->assertEquals("5005550000", $this->testphone;
    }
}

另一种选择是使用静态变量。

这是一个例子(针对 Symfony 4 功能测试):

namespace App\Tests\Controller\Api;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;
use Symfony\Component\HttpFoundation\AcceptHeader;

class BasicApiTest extends WebTestCase
{
    // This trait provided by HautelookAliceBundle will take care of refreshing the database content to a known state before each test
    use RefreshDatabaseTrait;

    private $client = null;

    /**
     * @var string
     */
    private const APP_TOKEN = 'token-for-tests';

    /**
     * @var string
     */
    private static $app_user__email = 'tester+api+01@localhost';

    /**
     * @var string
     */
    private static $app_user__pass = 'tester+app+01+password';

    /**
     * @var null|string
     */
    private static $app_user__access_token = null;

    public function test__Authentication__Login()
    {
        $this->client->request(
            Request::METHOD_POST,
            '/api/login',
            [],
            [],
            [
                'CONTENT_TYPE' => 'application/json',
                'HTTP_App-Token' => self::APP_TOKEN
            ],
            '{"user":"'.static::$app_user__email.'","pass":"'.static::$app_user__pass.'"}'
        );
        $response = $this->client->getResponse();

        $this->assertEquals(Response::HTTP_OK, $response->getStatusCode());

        $content_type = AcceptHeader::fromString($response->headers->get('Content-Type'));
        $this->assertTrue($content_type->has('application/json'));

        $responseData = json_decode($response->getContent(), true);
        $this->assertArrayHasKey('token', $responseData);

        $this->static = static::$app_user__access_token = $responseData['token'];
    }

    /**
     * @depends test__Authentication__Login
     */
    public function test__SomeOtherTest()
    {
        $this->client->request(
            Request::METHOD_GET,
            '/api/some_endpoint',
            [],
            [],
            [
                'CONTENT_TYPE' => 'application/json',
                'HTTP_App-Token' => self::APP_TOKEN,
                'HTTP_Authorization' => 'Bearer ' . static::$app_user__access_token
            ],
            '{"user":"'.static::$app_user__email.'","pass":"'.static::$app_user__pass.'"}'
        );
        $response = $this->client->getResponse();

        $this->assertEquals(Response::HTTP_OK, $response->getStatusCode());

        $content_type = AcceptHeader::fromString($response->headers->get('Content-Type'));
        $this->assertTrue($content_type->has('application/json'));
        //...
    }
}