20 \ December 2018 \ http://www.phparch.com
FEATURE
How to Learn PHP Unit Testing With Katas
David Hayes
All PHP code gets tested. Most of it is tested by the developer when they check to make
sure the webpage looks right in their browser; some when you run an API response tool, like
Postman. Some of it is tested when the same developer writes automated tests and runs them
against it—this is our focus. Sometimes code is first tested when the unfortunate client or user
feels like using the feature and tests the developer’s work. Hopefully, they’re not disappointed.
The most common and clear reason
to use automated testing is it helps us
verify our code works correctly without
having to walk through an elaborate
and complex set of “readying” actions
to get to the code we want to test right
n ow.
While I’m not certain, I suspect I’m
not the only developer in the world
who has ever spent hours bug-fixing
code at the end of complicated setup
procedure involving forms, file uploads,
and a whole lot of stuff I don’t enjoy fill-
ing with “dummy” data.
When I look back at those times,
about 20 percent of my time was spent
thinking about the code and solving the
concrete problems. The other 80% was
going through the five-step process of
selecting uploads, sending them, setting
the many values the form required, and
then (and only then) finding out if the
edits I’d made had fixed my problem
or if I’d made a new stupid error like a
missing semicolon.
That’s why you should be interested
in unit testing and Test-Driven Devel-
opment (TDD)—because it makes
your life as a programmer better. It
would have saved me hours of work
in situations like those outlined in the
last paragraph. TDD and automated
testing let us focus on what we’re there
for: solving complicated problems with
code and leaving the computers to do
more of the rest.
What is Unit Testing?
It’s useful before we get too deep into
this discussion to clearly define our
terms. Unit testing, automated testing,
and TDD are all related but distinct
things. They’re categories which contain
each other, i.e., “automated testing”
contains all “unit tests.” So “unit testing”
is generally considered to contain TDD,
though not quite as precisely.
We call something “automated test-
ing” if it is a test of a system which can
run without human intervention. That’s
the broadest level.
Within that, you’ll most often hear
people talk about unit tests—a contro-
versially used term. Some people insist
a unit under such a test must be a func-
tion or method one to 10 lines long.
Others insist even a whole system can
be tested as part of a unit.
We don’t need to adjudicate the whole
thing here. Suffice it to say a unit test
tests a software system without human
intervention.
What is Test-Driven
Development?
TDD is a subset of unit testing as
discussed above, but it’s also a little
different. TDD isn’t quite a type of unit
testing because it is actually a practice or
course of action the developer follows.
In short, it is the practice of letting your
(unit) tests drive your development.
In practice, then, TDD is often
spoken about as a Red, Green, Refac-
tor cycle. That means we first write the
test. This just-written test failing is what
people call a “red,” and lets us know the
test is indeed driving the process.
After they have seen the test fail, the
developer writes as little code as possi-
ble to make the test start to pass or turn
green. How strictly people hew to “as
little as possible” is another contour of
the debate where one could lose hours.
(To preview it: is return 2 a line of code
you should ever write when you’re
creating a calculator? Opinions differ.)
The final step of TDD, “refactoring”
means to change the internal design
of the system without changing its
external behavior. Martin Fowler, the
author of the seminal refactoring book,
argues that without automated testing
no changes to code can formally be
called refactorings. With tests, we rede-
sign the internals of our code when we
feel it’s necessary. Then we run the tests
without changing them to make sure
they’re all still passing. In this way, we
test-drive out the design of a software
system.
Why Do Unit Testing Or TDD?
Whether you’re doing unit testing or
TDD, some of the benefits are the same.
In either case, you can use the tests to
verify the code works as intended and
to prevent a breaking change from
hitting your code base. Running tests to
prevent “regressions”–code which used
to work, no longer working–is both
common and essential.
Some people insist regression test-
ing is explicitly not the point of TDD.
The point of TDD is there is a process
by which your code comes to exist
which produces better code than
simply having tests assures. Only a fool
wouldn’t rely on the tests they create in
the process of TDD for at least some
small amount of anti-regression benefit.
PHP Tools for TDD
You’ll need a few things to do
TDD — first, a text editor, which can
be as complex as Visual Studio Code,