DevOps Zone is brought to you in partnership with:

Gil Zilberfeld has been in software since childhood, writing BASIC programs on his trusty Sinclair ZX81. With more than twenty years of developing commercial software, he has vast experience in software methodology and practices. Gil is an agile consultant, applying agile principles over the last decade. From automated testing to exploratory testing, design practices to team collaboration, scrum to kanban, and lean startup methods – he’s done it all. He is still learning from his successes and failures. Gil speaks frequently in international conferences about unit testing, TDD, agile practices and communication. He is the author of "Everyday Unit Testing", blogs at http://www.gilzilberfeld.com and in his spare time he shoots zombies, for fun. Gil is a DZone MVB and is not an employee of DZone and has posted 76 posts at DZone. You can read more from them at their website. View Full User Profile

What Is A Unit Test?

05.09.2014
| 4800 views |
  • submit to reddit

What make unit tests different than other tests? They are full of FAIL.

Going to the Wikipedia  definition, you’ll get a vague and unhelpful description, and to summarize: It tests a small piece of code.

In  what language? What is small? And why does that matter?

I feel that many times in software, we’d rather concentrate on the mechanics, rather than on the goal. For example, we talk about mocking (how we do it) while we actually want isolation (which is what we need for our tested code).

First, let’s take a look at our goals for a good unit test:

  1. Tell you quickly when there’s a real problem
  2. Get you as quickly as possible from “Found a problem” to “Fixed a problem”

Let’s take a closer look, using FAIL.

Functionality: A unit test is a sensor, telling us if a former working functionality no longer works. While feedback is the requirement from every kind of test, the key thing is functionality, and in code terms - logic: if-thens, try-catches and workflows inside the code.

Accuracy: A unit test should fail for only two reasons: We broke something and should fix the code (A bug), or we broke something and should fix the test (A changed requirement). In both cases, we’re going to do valuable work. When is it not valuable? Example: If the test checked internal implementation, and we changed the implementation but not the functionality, this does not count as a real problem. The code still does what it was meant to, functionality didn’t change. But now we need to fix the test, which is waste. We don’t like waste.

Instant: A unit test runs quickly. A suite of hundreds and thousands unit tests runs in a few seconds or minutes. The success of applying a fine-grain sensor array relies on quickness in scale. This usually translates in the tested code to be short and isolated.

Locator: When there’s a problem, we need to fix it quickly. Part of it is testing a small amount of code. Then, there’s more we can do in the test to help us solve the problem. Yet, we need to think outside the context of writing the test, though. Someone else may break it, in a year or more, after we’ve moved companies twice. In other words, we’re leaving a paper trail to locate the specific problem for someone else. To do that we use accurate naming, readable test code, testing small portion of the code in a specific scenario, isolation from any undetermined or non-specific dependency, and lots of other tricks that will help our unfortunate developer achieve a quick fix.

Notice that none of these attributes are about the experience of writing a test. It’s about getting the most value out of it after it’s there.

The only value you get while writing a test, is when the code is not there yet. That’s right, in TDD. In that case, you get all of the above, plus insight about the design and safe incremental progress.

All other kinds of tests, which are also valuable, don’t have all these traits: Integration tests don’t locate the problematic code. UI tests are brittle. Full system tests are slow. Non-functional tests just give you feedback, and exploratory testing is not about functional correctness, but rather on business value (at least should be).

If your test passes the FAIL test, then it is a unit test.

Published at DZone with permission of Gil Zilberfeld, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)