PHPUnit offers a feature that lets you skip a test when certain requirements aren’t met. This can be done in two ways:
- You can manually check if the requirements are met, and then skip the test with
$this->markTestSkipped()
if they are not. - 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.