Skip to content

Reliable API for freeing resources used by the test #4796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
morozov opened this issue Oct 13, 2021 · 1 comment
Closed

Reliable API for freeing resources used by the test #4796

morozov opened this issue Oct 13, 2021 · 1 comment
Labels
type/enhancement A new idea that should be implemented

Comments

@morozov
Copy link
Contributor

morozov commented Oct 13, 2021

Take this test for example:

<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Tests;

use Exception;
use PHPUnit\Framework\TestCase;

abstract class IntegrationTest extends TestCase
{
    protected $connection;

    /**
     * @before
     */
    protected function connect(): void
    {
        // connect to the database
        $this->connection = ...;
    }

    /**
     * @after
     */
    protected function disconnect(): void
    {
        // disconnect from the database
        $this->connection = null;
    }
}

class TearDownFailureTest extends IntegrationTest
{
    protected function tearDown(): void
    {
        throw new Exception();
    }

    public function testSkipped(): void
    {
        self::markTestSkipped();
    }
}

The code above does the following:

  1. The base class defines the @before and @after methods that will prepare and clean up the test database and the connection.
  2. The specific test cases may define their own setup and teardown procedures.

There is a problem in the TearDownFailureTest that it may get skipped but it doesn't check (and probably can't) if it was skipped, it attempts to perform the teardown logic and throws the exception that gets suppressed by the test runner. Because of that, the disconnect() method in the parent class doesn't get called and the test instance remains connected to the database leaking resources.

It wouldn't be a problem if the test object got destroyed after the run but it doesn't (there are a few reported issues about that, e.g. #3039).

If the teardown methods are meant for the cleanup, should they be called independently on the results of each other? Currently, an exception stops the chain:

foreach ($hookMethods['after'] as $method) {
if ($this->methodDoesNotExistOrIsDeclaredInTestCase($method)) {
continue;
}
$this->{$method}();

Currently, the desired logic could be implemented in a TestListener class which has access to the Test object but it's deprecated:

public function endTest(Test $test, float $time): void;

Neither the deprecated TestHook API, nor the event-based API seem to provide access to the Test instance for reliable cleanup.

@morozov morozov added the type/enhancement A new idea that should be implemented label Oct 13, 2021
@mvorisek
Copy link
Contributor

duplicate of #4705

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement A new idea that should be implemented
Projects
None yet
Development

No branches or pull requests

3 participants