PHPUnit筛选不适用于setUpBeforeClass()和tearDownAfterClass()


PHPUnit filtering not working with setUpBeforeClass() and tearDownAfterClass()

我们非常广泛地使用PHPUnit过滤,它似乎不会阻止我们在与过滤结果不匹配的测试类中执行setUpBeforeClass()和tearDownAfterClass()。

对于那些不知道的人,您可以使用--filter选项来过滤您的PHPUnit测试。

像mocha这样的其他测试框架不会执行fixture,除非它们与过滤器匹配。

我想首先说,我非常尊重所有phpunit贡献者。

我们的解决方法是开发一个新的基类,它提供了一组新的构造,可以用来代替setUpBeforeClass()和tearDownAfterClass()。

class Test extends PHPUnit_Framework_TestCase {
  /**
   * PHPUnit has a serious design flaw where setUpBeforeClass() and tearDownAfterClass() are still
   * executed for all test classes even if they don't match the filter. This appears to be due to
   * PHPUnit applying the filter after these fixtures. Fortunately, with a little magic, we can
   * define constructs for before() and after() that achieve our desired behavior. Some may say that
   * this is not a PHPUnit bug, but other testing frameworks like mocha don't execute any of the
   * fixtures unless the filters match.
   */
  /**
   * @var boolean True if we are executing this test
   */
  protected static $executing = false;
  /**
   * Use instead of setUpBeforeClass() to create a fixture that is called once per test class and
   * not called unless it is in the filter results.
   */
  public static function before() {}
  /**
   * Use instead of tearDownAfterClass() to create a fixture that is called once per test class and
   * not called unless it is in the filter results.
   */
  public static function after() {}
  /**
   * A base method for setUp() that uses the $executing flag to determine whether or not to run
   * before(). We cannot use setUpBeforeClass() here as setUpBeforeClass() will run before any
   * filters are applied.
   */
  protected function setUp() {
    if (!self::$executing) {
      static::$executing = true;
      static::before();
    }
  }
  /**
   * A base method for tearDownAfterClass() that uses the $executing flag to determine whether or
   * not to run after()
   */
  public static function tearDownAfterClass() {
    if (static::$executing) {
      // Set to false so that this doesn't trigger execution of another classes fixtures as $executing
      // is a static member
      static::$executing = false;
      static::after();
    }
  }
}

然后,您可以像这样使用新的before()和after()构造,如果测试不是过滤结果的一部分,它们将不会被执行:

class MyTest extends Test {
  public static function before() {
    // Code done once before all tests
  }
  public function testFoo() {
    // Test something
  }
  public static function after() {
    // Code done once after all tests
  }
}
相关文章:
  • 没有找到相关文章