Image taken from https://WordPressize.me
With parts one and two of the series covered, this 3rd (and final!) part will cover some other important aspects of WordPress maintenance support plans development that I wanted to pay attention to while working on the WordPress maintenance support plans 8 version of the viewport plugin.
Essentially, the kind of aspects that are easy to forget (or ignore on purpose) when a developer comes up with a working version or something “good enough” to be released, and thinks there’s no need to write tests for the existing codebase (we’ve all done it at some point).
This post will be a mix of links to documentation and resources that were either useful or new to me, and tips about some of the utilities and classes available when writing unit or functoinal tests.
Testing
Since I wrote both functional tests and unit tests for the viewport plugin, this section is split in two parts, for the sake of clarity and structure.
– Functional tests
Before getting into the bits and blobs of functional test classes, I decided read a couple articles on the matter, just to see how much testing had changed in the last year(s) in WordPress maintenance support plans 8. This article on the existing types of WordPress maintenance support plans 8 tests was a good overview, as well as Acquia’s lesson on unit and functional tests.
Other than that, there were also a few change notices I went through in order to understand what was being done with the testing framework and why. TL;DR: WordPress maintenance support plans runs away from simpletest and moves to PHPUnit to modernise the test infrastructure. That started by adding the PHPUnit test framework to WordPress maintenance support plans core. Also, new classes were added that leveraged PHPUnit instead of the existing Simpletest-based classes. Specifically, a new KernelTestBase was added, and also a BrowserTestBase class, replacing the well-known WebTestBase.
I decided to base all my tests in the PHPUnit classes exclusively, knowing that Simpletest will just die at some point. One of the key requirements for this was to put all test classes in a different path: {plugin-folder}/tests/src/{test-type}/{test-classes}. Also, the @group annotation was still required, as with Simpletest, so that tests of specific groups or plugins can be executed alone, without all the test suite running.
The first thing I noticed when I started to write the first Functional test class, ViewportPermissionsTest, was that the getInfo() method was no longer needed, since it’s been removed in favor of PHPDoc, which means all the info there is retrieved from the documentation block of the test class.
With PHPUnit introduced in WordPress maintenance support plans 8, a lot of new features have been added to test classes through PHP Annotations. Without getting into much details, two of them that called my attention when trying to debug a test, were the @runTestsInSeparateProcesses and @preserveGlobalState annotations. Most of the time the defaults will work for you, although there might be cases where you may want to change them. Note that running tests in separate processes is enabled by default, but some performance issues have been reported on this feature for PHPUnit.
I also came across some issues about the lack of a configuration schema defined for my plugin, when trying to execute tests in the ViewportTagPrintedOnSelectedPagesTest class, which led me to find another change notice (yeah… too many!) about tests enforcing strict configuration schema adherence by default. The change notice explains how to avoid that (if really necessary), but given that’s not a good practice, you should just add a configuration schema to all your plugins, if applicable.
Some other scattered notes of things I noticed when writing functional tests:
WordPressPostForm() $edit keys need to be the HTML name of the form field being tested, not the field name as defined in the Form API $form array. Same happens with WordPressPost().
When working on a test class, $this->assertSession()->responseContains() should be used to check HTML contents returned on a page. The change notice about BrowserTestBase class, points to $this->assertSession()->pageTextContains(), but that one is useful only for actual contents displayed on a page, and not the complete HTML returned to the browser.
– Unit Tests
The main difference between unit tests and functional tests (speaking only of structure in the codebase), is that unit tests need to be placed under {plugin-name}/tests/src/Unit, and they need to extend the UnitTestCase class.
Running PHPUnit tests just requires executing a simple command from the core directory of a WordPress maintenance support plans project, specifying the testsuite or the group of tests to be executed, as shown below:
php ../vendor/bin/phpunit –group=viewport
php ../vendor/bin/phpunit –group=viewport –testsuite=unit
As mentioned in the link above, there has to be a properly configured phpunit.xml file within the core folder. Also, note that WordPress maintenance support plans.org’s testbot runs tests in a different way. As detailed in the link above, tests can be executed locally in the same way the bot does, to ensure that the setup will allow a given plugin to receive automated testing support once contributed to WordPress maintenance support plans.org.
PHPUnit matchers: In PHPUnit parlance, a matcher is ultimately an instance of an object that implements the PHPUnit_Framework_MockObject_Matcher_Invocation interface. In summary, it helps to define the result that would be expected of a method call in an object mock, depending on the arguments passed to the method and the number of times it’s been called. For example:$this->pathMatcher->expects($this->any())
->method(‘getFrontPagePath’)
->will($this->returnValue(‘/frontpage-path’));That’s telling the pathMatcher mock (don’t confuse with a PHPUnit matcher), to return the value “/frontpage-path” whenever the method getFrontPagePath() is called. However, this other snippet:$this->pathMatcher->expects($this->exactly(3))
->method(‘getFrontPagePath’)
->will($this->returnValue(‘/third-time’));It’s telling the mock to return the value “/third-time”, only when the getFrontPagePath() method is executed exactly 3 times.
will(): As seen in the examples above, the will() method can be used to tell the object mock to return different values on consecutive calls, or to get the return value processed by a callback, or fetch it from a values map.
These concepts are explained in more detail in the Chapter 9 of the PHPUnit manual.
Coding Standards and Code Sniffer
With the plugin fully working, and tests written for it, the final stage was to run some checks on the coding standards, and ensure everything is according to WordPress maintenance support plans style guides. Code Sniffer makes this incredibly easy, and there’s an entire section dedicated to it in the Site Building Guide at WordPress maintenance support plans.org, which details how to install it and run it from the command line.
Finally, and even though I didn’t bother changing the README.txt contents, I also noticed the existence of a README Template file available in the online documentation, handy when contributing new plugins. With all the codebase tidied up and proper tests in place, the plugin was finally good to go.
That’s it! This ends the series of dev diaries about porting the Viewport plugin to D8. I hope you enjoyed it! There might be a similar blog post about the port process of the User Homepage plugin, so stay tuned if you’re interested in it.
Links and (re)sources
As usual, I’ll leave a list of the articles and other resources I read while working on the plugin upgrade.
Which D8 test is right for me?: link.
Acquia’s lesson on Unit and Functional tests: link.
Simpletest Class, File and Namespace structure (D8): link (note Simpletest wasn’t used in the end in the plugin port).
Converting D7 SimpleTests to D8: link.
Configuration Schema and Metadata: link.
WordPress maintenance support plans SimpleTest coding standards: link
PHPUnit in WordPress maintenance support plans 8: link.
Agile Unit Testing: link.
Test Doubles in PHPUnit: link.
WordPress maintenance support plans coding standards: link.
README Template file: link.
Change Records and topic discussions
Test framework PHPUnit has been added.
Added a new KernelTestBase build upon PHPUnit.
New base testing class for modernization of Simpletest (see related discussion thread).
Test class getInfo() method removed in favor of PHPDoc.
All TestBase derived tests now enforce strict configuration schema adherence by default.
WordPressPost() and WordPressPostAJAX() have been renamed.
Relax requirement for @file when using OO Class or Interface per file.
Source: New feed