Creating Your Own PHPUnit @requires Annotations

PHPUnit offers a feature that lets you skip a test when certain requirements aren’t met. This can be done in two ways:

  1. You can manually check if the requirements are met, and then skip the test with $this->markTestSkipped() if they are not.
  2. In some cases, you can use the @requires annotation, and the test will be skipped automatically when the requirements aren’t met.

Using the @requires annotation is nicer, but PHPUnit only has so many options built in. Sometimes you have custom requirements that can’t really be checked reliably with any of the built-in options. An example is when you need some tests you’ve written for a WordPress plugin to run only when WordPress’s multisite feature is enabled on the test site. In my tests, I find myself needing this a lot. So I’ve been writing this over and over:

if ( ! is_multisite() ) {
     $this->markTestSkipped( 'Multisite must be enabled.' );
}

But just yesterday I realized that this was silly, and that I could easily add my own custom @requires annotation. So I did. Here is the code:

	protected function checkRequirements() {

		parent::checkRequirements();

		$annotations = $this->getAnnotations();

		foreach ( array( 'class', 'method' ) as $depth ) {

			if ( empty( $annotations[ $depth ]['requires'] ) ) {
				continue;
			}

			$requires = array_flip( $annotations[ $depth ]['requires'] );

			if ( isset( $requires['WordPress multisite'] ) && ! is_multisite() ) {
				$this->markTestSkipped( 'Multisite must be enabled.' );
			} elseif ( isset( $requires['WordPress !multisite'] ) && is_multisite() ) {
				$this->markTestSkipped( 'Multisite must not be enabled.' );
			}
		}
	}

You just need to add that method to your base test case class, and you will then be able to use @requires WordPress multisite instead of messing with markTestSkipped() all the time. For tests that should only run when multisite isn’t enabled, you can use @requires WordPress !multisite.

You could easily add more options for any other requirements your tests commonly have.

Leave a Reply

Your email address will not be published. Required fields are marked *