24 \ December 2018 \ http://www.phparch.com
How to Learn PHP Unit Testing With Katas
Finishing It Off: Testing the Edges
After we’ve gotten to point
supporting all the ASCII Roman
numbers (those which don’t
require a bar above the top of a
letter), we’ll have something like
the lookup table in Listing 5.
Now that we’ve filled out the
“happy path” through our code,
we can go ahead and move on to
edge cases. As I just mentioned,
the easy-to-write-as-a-string
Roman numbers end at 3999. So
even if I’m not fully test driving
it (my code already supports
it) I like to write a test to assert
that 3999 (my upper bound of
might-receive input) gives me
the right result:
function test3999() {
$this->assertEquals('MMMCMXCIX',
arabicToRoman( 3999 ));
}
Testing Zero
I also like to do the low end. For Roman numerals, that’s
generally regarded to be zero which is particularly interest-
ing. What should happen when we try to convert zero into
a Roman numeral? I think a reasonable answer is that we
should give back a string with no contents, ''. If we want that
result, like 3999, we won’t have to write new code.
There’s also a reasonable case to make that when we see
zero, or other out-of-bounds numbers, we should actually
throw an exception. After all, if you were trying to represent
zero in a string using Roman numerals, you might not find
the empty string very satisfying.
If we want to raise an exception, we’ll write the test like this:
function test0ThrowsAnException() {
$this->expectException(Exception::class);
arabicToRoman( 0 );
}
The customary way in PHPUnit to indicate you want an
exception is to say you expectException and then pass through
the exception you want. Then, (as you probably know) we’d
add to our production code a clause like:
if ($number < 1) {
throw new \Exception(
'Zero and negative numbers are not allowed'
);
}
At this point, I have pretty high confidence in our code. It
works for the numbers I think it reasonably can work for and
it breaks in a way I like in exceptional cases. Also, we’re just
approaching our time limit too.
Where to Find Other Code Katas
With the Roman numeral kata under your belt, you’ll
probably want to do some more. As I’ve said, there are tons
of sources. You can even find “legacy code katas” as well as
ones you write from scratch as we’ve done with the Roman
numerals. There are lots of sources for them online, but here’s
a list to get you started on sources to look for katas:
- Coding Dojo has a great Kata Catalog page:
http://codingdojo.org/kata/ - Dave Thomas (“The Pragmatic Programmer”) has a great
list on his site: http://codekata.pragprog.com/codekata/ - Kata-Log.Rocks (what a domain!) also has quite a
substantial list: http://kata-log.rocks/tdd - If you want a more thorough toolset for this, CodeW-
ars (owned by recruiting firm Qualified) is a great
complete software tool to challenge you with different
katas and make it easy for you to compare answers.
https://www.codewars.com
Why We Do Katas And What We Get from It
Hopefully, this preview of doing PHP unit testing and TDD
using katas has inspired you to try it out on your own. There
are many places to find katas, and also many setups you can
use. All of them should help you feel more comfortable with
your tools—your testing framework, text editor, command
line, etc.—and better at TDD.
PHPUnit is excellent for doing code katas because it’s the
most widely-used testing framework in PHP. Moreover, so
trying it here, and being comfortable writing and testing PHP
code on your machine with your favorite tools makes you
better at doing this for real, on code which matters to you or
your day job. I wish you great luck!
David is a developer from Fort Collins,
Colorado. He’s worked with PHP for over a
decade, and does a lot of intensive backend
work, a fair bit of JavaScript, and dabbles
with CSS. While big into WordPress—he
owns and runs the popular development
tutorial site WPShout—he has experience
with everything from old school PHP to the
latest and greatest of Symfony and Laravel.
@davidbhayes
Listing 5
- $arabicToRoman = [
- 1000 => 'M',
- 900 => 'CM',
- 500 => 'D',
- 400 => 'CD',
- 100 => 'C',
- 90 => 'XC',
- 50 => 'L',
- 40 => 'XL',
- 10 => 'X',
- 9 => 'IX',
- 5 => 'V',
- 4 => 'IV',
- 1 => 'I',
- ];
Related Reading
- PHPUnit Worst Practices
by Victor Bolshov. April 2018.
https://www.phparch.com/magazine/2018-2/april/ - Leveling Up: Ensuring Your Tests are Valuable
by David Stockton. March 2016.
https://www.phparch.com/magazine/2016-2/march/