Earlier this month, we began looking at installing PHPUnit in Visual Studio Code with the ultimate goal of learning how to write unit tests for our WordPress-based projects.
To that end, this post assumes that you’ve read the following posts and it assumes that you’ve caught up with a handful of previous posts:
- A WordPress Development Environment (Using a Package Manager)
- An IDE for WordPress Development
- Working with User Settings in Visual Studio Code
And, of course, installing PHPUnit in Visual Studio Code as linked above. Once that’s done, we’ll be ready to proceed. But one thing to keep in mind is that this will night be a traditional or a comprehensive course in writing unit tests.
Instead, it’s all about writing unit tests for WordPress projects.
Unit Tests with PHPUnit, Part 1: The Set Up
Before getting too deep into this, I want to be clear that this isn’t so much a post in test-driven development but a post that lays the foundation for understanding writing unit tests. And then, ultimately, we’ll work towards writing unit tests for our code.
For those of you who have done any prior reading on unit testing then you know writing unit tests is a topic for which there is a lot of information and this post isn’t going to attempt to cover all of that. Instead, it’s going to take a more pragmatic approach to writing unit tests against WordPress-based plugins, web applications, and the like.
1. Writing Unit Tests
Whenever you first get into writing unit tests, you’re going to be presented with both the idea of the setUp and the tearDown methods. This is common in PHPUnit (as with other testing frameworks). There are a few things about these two particular methods that often cause problems.
In short, people treat the functions like this following:
- setUp is like the constructor where you instantiate your class and then you prepare everything you need for your test including the object to be tested, the data that’s needed, and so on.
- tearDown is the destructor where you reset everything and then dispose of your objects. This is usually more common in compiled languages but it’s not to be missed within PHPUnit either.
And although I can completely understand this, it’s not always the case. I’m speaking from experience here, too. Instead, this is from where the actual phrase unit testing comes. It’s all about testing units code code and doing so in a clean, concise manner.
So what are these methods for, anyway? This can be an especially difficult habit to break or even conceptual model to break when you’re first getting into the process. To that end, I want to examine the purpose of each method and then how to approach this when working with WordPress-based projects.
And, as usual, I’ll aim to keep this as simple and pragmatic as possible. I’m far less interested in the theory behind certain things than I am in how it can serve both my business and my projects well. (This isn’t to discount theory, of course, but there’s a time not a place for that and this blog is not it.)
2. The setUp Function
Even though I’m starting with a short discussion of the setUp method, it’s important to keep in mind that its sister-function (as some consider it) are not always needed.
For example, if you’re writing code where all you’re doing is instantiating an object or a set of objects, then the tearDown method may not be needed. I’ll get into more detail about this in the next section.
With that said, let’s say that you have a class that’s responsible for executing a bit of domain logic. Remember, for the purposes of this post, we are not concerned with code that will do things that WordPress does naturally and that already has its own set of tests.
By that, I mean we’re concerned with code that works specifically within a problem domain. For example, perhaps we’re concerned with writing a class that caches data to the database. One of the pieces of information that’s responsible for caching information is how long the data should be cache. Thus, a candidate for the unit test would making using that we’re able to set and change the amount of time, right?
Granted, perhaps this data is hard-coded but for the purposes of example, let’s assume otherwise. This implies the following:
- We have a class that serves as our cache,
- The class maintains of a piece of instance data for how long the cache should be set,
- The cache time can be set from third-party classes,
- The cache time can be read from third-party classes.
This means that a unit test would include:
- Setting up the class,
- Defining a value,
- Asserting that the value that was defined is as expected,,
- Changing the value,
- Asserting the value that was changed was updated.
So the basic class may look something like this (all documentation being left out of the class for the purposes of keeping the code as concise as possible):
Notice that, by default, we have the cache time set at 12 hours (in seconds). The class supports the ability to both change and read the duration, as well.
This means that we can write tests that test:
- if the initial value is what was expected,
- if the new value is what was expected (and that it overwrites the initial value)
One of the things I’d like to point out in the above code is that you may read that each test should have a single assertion whereas by testNewDuration clearly has two assertions.
I tend to take the idea of one assertion per test as a rule of thumb. For example, in this case, I want to assert that the initial value is overwritten or not stored anywhere and the new value is stored.
This may not always be the case though, so you may need to treat these types of situation with care.
As you can see, this has nothing to do with WordPress; however, it does have to do with testing logic related specifically to the domain at hand. Namely, the duration of the cache. And this is what the core of unit testing is all about: Testing the logical behavior of units of code to make sure that we have things working as expected.
And depending on when you write this code, you may have failing tests. This can ultimately help with class design, but that’s another topic and not one that’s part of this post.
Running The Tests
Once the tests are written, it’s important to be able to execute them to see if they pass, if they fail, what passes, and what doesn’t. But we’re not done yet. I want to provide a comprehensive look at unit testing in the context of WordPress and this comes at discussing what WordPress provides, what it doesn’t, some misconceptions, and how to run these tests in the terminal or within Visual Studio Code.
In the next post in this series, we’re going to look at the tearDown function and how (and when) to use it, when it’s needed, when it’s not, and then we’re going to look a little bit into around unit testing in WordPress in general.
Ultimately, we’re working towards getting a full picture of how to do this and how to do it right. But it’s important to lay the foundation for that and doing so over the span of a few posts is easier than in one monolithic post.
So examining tearDown(), it’s use, and how to execute tests from the command-line will be the topic of the next post in this series.