Order of execution of unit tests

0

Is there any way to set the order of execution of test methods?

When I put the code for the testSelectDaInsercao function inside testInsercaoDeDados the tests run successfully, but this way the test fails. I believe it's due to the order of execution.

I looked in the documentation and saw only something about depends and it made it clear that this would not change the order. I already invested the order of the methods, but the test also failed!

use Application\Conn;
use Application\operacao;
use PHPUnit\Framework\TestCase;

class PHPTest extends TestCase 
{
    private $conn;

    public function setUp()
    {
        $this->conn = new Conn();
        $this->conn = $this->conn->retornaConexao();
    }

    public function testInsercaoDeDados()
    {      
        $stmt = $this->conn->prepare("INSERT INTO usuario values (?, ?)");

        $stmt->bindValue(1, 'teste', \PDO::PARAM_STR);
        $stmt->bindValue(2, '123456', \PDO::PARAM_STR);

        $resul = $stmt->execute();
        $this->assertTrue($resul);  
    }

    public function testSelectDaInsercao()
    {
        $resul = $this->conn->query("SELECT count(usuario.nome) as id 
                                    FROM usuario WHERE nome = 'teste' 
                                    AND senha = '123456'");

        $resul = $resul->fetch(\PDO::FETCH_ASSOC);

        $resul = (int) $resul['id'];

        $this->assertEquals(1, $resul, 'erro ao comparar insercao'); 
    }

    public function tearDown()
    {           
        $this->conn->query("truncate table usuario");
    }

}

using depends /** * @depends testInsercaoDeDados **/

    
asked by anonymous 22.06.2017 / 03:57

2 answers

1

Your problem is not in the order of execution, it is in the tearDown method.

PHPUnit will execute the methods setUp and tearDown after executing every method of your class .

Since your tearDown is giving a truncate in the whole table (which is correct), executing the next test of this class will begin with the table zeroed again.

To address this, two approaches can be taken:

Unify both tests into one:

use Application\Conn;
use Application\operacao;
use PHPUnit\Framework\TestCase;

class PHPTest extends TestCase 
{
    private $conn;

    public function setUp()
    {
        $this->conn = new Conn();
        $this->conn = $this->conn->retornaConexao();
    }

    public function testInsertAndRecoverFromDatabase()
    {      
        $stmt = $this->conn->prepare("INSERT INTO usuario values (?, ?)");

        $stmt->bindValue(1, 'teste', \PDO::PARAM_STR);
        $stmt->bindValue(2, '123456', \PDO::PARAM_STR);

        $result = $stmt->execute();
        $this->assertTrue($result);

        $selectResult = $this->conn->query("SELECT count(usuario.nome) as id 
                                    FROM usuario WHERE nome = 'teste' 
                                    AND senha = '123456'");

        $selectResult = $selectResult->fetch(\PDO::FETCH_ASSOC);

        $insertedId = (int) $resul['id'];

        $this->assertEquals(1, $insertedId , 'erro ao comparar insercao'); 
    }    

    public function tearDown()
    {           
        $this->conn->query("truncate table usuario");
    }    
}

Instead of setUp and tearDown , use setUpBeforeClass and tearDownAfterClass . These are two static methods that run only in the construction of the entire class of tests. Combined with @depends you can ensure both tests run.

use Application\Conn;
use Application\operacao;
use PHPUnit\Framework\TestCase;

class PHPTest extends TestCase 
{
    private static $conn;

    public static function setUpBeforeClass()
    {
        static::$conn = (new Conn())->retornaConexao();
    }

    public function testInsertIntoDatabase()
    {      
        $stmt = static::$conn->prepare("INSERT INTO usuario values (?, ?)");

        $stmt->bindValue(1, 'teste', \PDO::PARAM_STR);
        $stmt->bindValue(2, '123456', \PDO::PARAM_STR);

        $result = $stmt->execute();
        $this->assertTrue($result);

        $selectResult = static::$conn->query("SELECT count(usuario.nome) as id 
                                    FROM usuario WHERE nome = 'teste' 
                                    AND senha = '123456'");

        $selectResult = $selectResult->fetch(\PDO::FETCH_ASSOC);

        $insertedId = (int) $resul['id'];

        $this->assertEquals(1, $insertedId , 'erro ao comparar insercao'); 
    }    

    /** @depends testInsertIntoDatabase */
    public function testSelectPreviousInsertedRegister()
    {
        $resul = $this->conn->query("SELECT count(usuario.nome) as id 
                                    FROM usuario WHERE nome = 'teste' 
                                    AND senha = '123456'");

        $resul = $resul->fetch(\PDO::FETCH_ASSOC);

        $resul = (int) $resul['id'];

        $this->assertEquals(1, $resul, 'erro ao comparar insercao'); 
    }

    public static function tearDownAfterClass()
    {           
        static::$conn->query("truncate table usuario");
    }    
}
    
23.06.2017 / 01:53
1

The problem is in the tearDown method:

public function tearDown()
{           
    $this->conn->query("truncate table usuario");
}

This method always runs after each test, whether valid or failed. That is, when the testInsercaoDeDados test is executed, the information is written, but when the test is terminated, the tearDown method is executed by clearing the records. When the test testSelectDaInsercao is executed, there will be no records.

To work around this problem, you can do truncate of the table in the tearDownAfterClass method, because it will only run when ALL tests are run, thus ensuring that records are persisted while the tests are running.     

23.06.2017 / 01:42