web-dev-qa-db-fra.com

phpunit: Comment passer des valeurs entre les tests?

Je rencontre vraiment un mur de briques avec ça. Comment passez-vous les valeurs de classe entre les tests dans phpunit?

Test 1 -> définit la valeur,

Test 2 -> lit la valeur

Voici mon code:

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() n'obtient pas la valeur de $this->blockHash qui doit être définie dans testCmdGetBlockHash().

Une aide pour comprendre ce qui ne va pas serait grandement appréciée.

24
Drazisil

La méthode setUp() est toujours appelée avant les tests, donc même si vous configurez une dépendance entre deux tests, toutes les variables définies dans setUp() seront écrasées. Le fonctionnement des données PHPUnit passe de la valeur de retour d'un test au paramètre de l'autre:

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

Donc, si vous devez enregistrer plus d'état entre les tests, renvoyez plus de données dans cette méthode. Je suppose que la raison pour laquelle PHPUnit rend cela ennuyeux est de décourager les tests dépendants.

Voir la documentation officielle pour plus de détails .

40
Anonymous

Vous pouvez utiliser une variable statique dans une fonction ... PHP partage énormément les variables statiques des méthodes de classe avec toutes les instances ... Mais dans ce cas, cela peut aider: 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
}

NB: ce n'est PAS la bonne façon mais cela aide si vous avez besoin de données dans tous vos tests ...

9
quazardous

Une autre option consiste à utiliser des variables statiques.

Voici un exemple (pour les tests fonctionnels de 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'));
        //...
    }
}
0
Boštjan Biber

Cela a parfaitement fonctionné pour moi dans tous les tests: $ this-> varablename

class SignupTest extends TestCase
{
    private $testemail = "[email protected]";
    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;
    }
}
0
ShaunOReilly