08 March 2017
Lately I've been going through Cracking the Coding Interview and practicing generative testing approaches to some of the problems. This will hopefully be the first in a number of posts about the problems found in that book. I won't be posting solutions to the actual problems, but these posts will provide code and strategies for testing solutions that readers come up with.
The problem in the book states: Implement an algorithm to determine if a string has all unique characters. Presumably this algorithm returns true
if the string has all unique characters and false
otherwise. For example, strings like 'abc' would return true
and aba
would return false
.
02 April 2015
In the last post I discussed generating structured random inputs using RandomStringBuilder. This is all well and good for tests that we expect to pass, but what about negatively testing inputs? That is, testing inputs that should fail. For sufficiently complex regular expressions, it's quite easy to introduce an unwanted quantifier or pattern. To revisit the Canadian postal code regular expression from prior posts, it's a subtle mistake to inadvertently change
/(?i)^([A-Z][0-9][A-Z])(?:[ -]?([0-9][A-Z][0-9]))?$/
to include the 1-or-more + quantifier:
/(?i)^([A-Z]+[0-9][A-Z])(?:[ -]?([0-9][A-Z][0-9]))?$/
27 March 2015
After spending some time working with generating random strings for testing regular expressions, I decided to write a utility to make things easier to read and reduce the amount of code in my tests. The library is here: https://github.com/stephenkhess/RandomStringBuilder
15 August 2014
It's been quite awhile since I last posted but my wife and I had a kid in November and, despite my very vocal protestations, diapers trump TDD. Today's article is a short one, but I've found it useful ever since switching away from servlet definitions in web.xml to inline @WebServlet annotations. It's applicable to any type of annotations, I suppose, but for me the @WebServlet annotation comes up quite a bit in my day-to-day development.
First, here's our servlet class definition:
@WebServlet(
name="Pleb Control",
description="This servlet is for keeping the plebs in check",
loadOnStartup=1,
asyncSupported=true,
urlPatterns={
"/stupidplebs/subjugateBrutually",
"/stupidplebs/governFairly"
},
initParams = {
@WebInitParam(name="enforcementMethod1", value="the stink eye"),
@WebInitParam(name="enforcementMethod2", value="propaganda")
}
)
public class StupidPlebServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
// do some stuff
}
}
27 August 2013
I attended a presentation by Stu Halloway on generative testing in Clojure at Uberconf 2013 in Denver a few weeks ago and it piqued my interest. Now I may be completely off on this (hell, I thought my coworker Sanjay stole the Lindbergh baby) but generative testing is for auto-generating tons of tests where the unit of code under test has a combinatorically prohibitive input space. Stu gave the example of a game that tests for colored pegs in a correctly ordered sequence. While revisiting some functionality recently that formats a string to Canadian postal code format if it matches a regular expression that allows for case-insensitivity and an optional space or hyphen delimiter, I realized that generative testing is a great technique for this functionality.
27 January 2013
I've been looking for a good reason to use parameterized tests for awhile now and I finally discovered a great one: testing regular expressions. This is especially useful for case-insensitive regexes with lots of OR (|) conditions.
19 February 2012
(It's been awhile since I've last posted but I agonize over wording so it takes a few hours from start to finish to write these articles)
So you've diligently written some thorough tests but our benevolent lord and savior, Cobertura, that wants only good things for us informs you that those pesky conditionally-executed logging statements are uncovered. Or maybe you just want to verify that your logging statements are being output. If either of these statements apply to your situation, then this article is for you.
Before I get started, and I cannot stress this enough, excessive testing of log4j statements (especially DEBUG) will cause your tests to become extremely brittle! Your coworkers will become very annoyed with you if the debugging statements they're adding to diagnose a logic problem are causing tests to fail. I'll address how to get around this later on in the section entitled "How to Avoid Being Beaten to Death".
09 December 2011
In this post, I'll cover negative testing, which is to make sure we know what error conditions can occur and how to make sure our code can handle them appropriately. Let's say that I want to track our plebs in a registry as just a list of Plebeian
POJOs consisting of just a first and last name. I can load my registry from an InputStream
of newline-delimited String objects, each of which is itself a comma-delimited last and first names. Constructing the registry should throw either an exception if something went wrong or complete and able to return an unmodifiable list of Plebeian
objects.
09 December 2011
Private constructors in your factories messing up your coverage graphs? I'm a bit OCD about my unit testing and like to get all my cobertura graphs to 100% but the problem is I sometimes have classes or factories that contain only statics and the default empty private constructor. Sure I could declare my default empty constructor public, but I'm also a bit adamant that if my code does something, it had better have a purpose and if I'm willing to just have public constructors when there's no reason for it, well then society may just as well be on the cusp of anarchy. I digress. My statics are well-tested, but cobertura complains that the private constructor that doesn't actually do anything is untested code.
07 December 2011
Lots of classes and applications I've written at some point output information to System.out
and System.err
. Sometimes it's quick-and-dirty debugging but if the output is meaningful, testing what's written to either is a pretty simple thing to do.
For this post, I've created a helper class with two static methods that write to System.out
and System.err
:
class SystemOutAndSystemErrHelper {
public static void writeToSystemOut(String text) {
System.out.println("writing '" + text + "' to stdout");
}
public static void writeToSystemErr(String text) {
System.err.println("writing '" + text + "' to stderr");
}
}
03 December 2011
Some time ago, JUnit added assertThat
as a replacement to assertEquals
, assertTrue
, assertNull
, etc. Originally, assertions were written as
assertEquals("stupidplebs.com", site.getMostAwesome());
assertTrue(site.isMostAwesomeSite("stupidplebs.com"));
assertNulhl(site.getAwesomerSiteThanStupidPlebs());
This always struck me as a little odd because, especially true for assertEquals
, the order actual and expected parameters order didn't matter which made reading the purpose of the test a little hard to read. That is,
assertEquals("stupidplebs.com", site.getMostAwesome());
is the equivalent to
assertEquals(site.getMostAwesome(), "stupidplebs.com");