In this, hopefully briefer, article I want to talk a little about testing approaches. Testing can fall anywhere on a continuum between writing all the code and then testing afterwards to writing the test first and then writing and rewriting code to pass the test.
I don’t want to get too hung up on various development methodologies and paradigms, those are beyond the scope of what I’m trying to accomplish here. The big question though, is when to test in relation to coding.
As the name indicates we are testing units (functions or classes) in isolation of other code. So, our focus is on a unit of code. Testing can occur after a unit is coded, or even before with test-first approaches.
So, starting at the test-first end of things (popular in Test Driven Development (TDD) and Behavior Driven Development (BDD)) we first conceive of something we want a unit of code to do, its requirements. It is useful to ask what arguments, or input, the code will need, and what its output, return values and side effects, will be. Then we write the test that will test that thing. The test will fail the first time, because we do not have the actual code written. So we write the bare minimum code that will make the test pass. Then we refactor the code as necessary. When that chunk is done we move on to the next. Here is tutorial on TDD if you are interested in pursuing it further: https://www.sitepoint.com/re-introducing-phpunit-getting-started-tdd-php/.
The upside of this first approach is that you always have tests in place for all of your code, the downside is that it can be a slower way to develop.
The next level on the continuum would be to write a function or class method and then test it, refactoring and fixing it before moving on to the next. The advantage of this method is that you are writing the test and testing your chunk of code right after writing it while it is still fresh in your mind.
Finally, you can write all your code and then write all your tests. The downside of this is that you are probably getting pulled by your next project and if things seem to work it’s tempting to skip the tests. Also, you may not recall the specifics or any misgivings you had about the code. There are very few in the way of advantages, I suppose that being in the test-writing mindset might be one of them.
I have to confess that this was how I approached the TruUcde plugin, not intentionally though. It only occurred to me to pursue unit testing on it after I had written the code. Now that I have a bit more of a handle on testing I’m likely to pursue one of the test-first approaches.
The key concept of integration testing is context. We are testing our code in the context and environment of the other code that it will interact with and depend on. So in our case, we are writing a WordPress plugin so we should test in the context of WordPress building addition context nuances as we go.
We want to test different things that we test in unit testing. In unit testing we are focussed on the business logic of what we have coded. In integration testing we are concerned with how well our code interfaces.
For example, with our plugin we will mock out several WordPress functions in unit tests. In integration testing we will want to test if our code works when this information is supplied via WordPress, and the various results that could be supplied.
At the end of the day, the aim of our plugin with be for users with certain permissions on subsites to be able to add users outside of white/black lists constraints. We will want to have elements of our integration testing that makes sure this happens.
Enduring Test Bank
One of the huge advantages of building out tests is having them available for future testing following code changes or environmental updates. For instance, with each new release of WordPress we can run our tests and make sure everything still tests out okay. If we decide to add a feature or make changes to our code, our existing tests are useful for what is called regression testing. Regression testing helps ensure that code changes don’t break something else accidentally.
Okay, that’s enough of a prelude, let’s move to the next article and get on with our unit tests.