Skip to content

Contract Checks - Once and Only Once for Unit Testing (Part III)

← Back to blog | ADMIN | 09-02-2011

I discussed the advantages of incorporating contract checks into one’s unit testing methodology. I thought it would be useful to include an example.

Hexagon pattern 1

In Part I and Part II of this thread, I discussed the advantages of incorporating contract checks into one’s unit testing methodology. I thought it would be useful to include an example, so here it is . . .

To decide on the example, I first thought of the contract check I wanted to write – to check that a sorted list is actually sorted – and then worked my way backwards to figure out the routine that I wanted to write. Sorting routines are already available (qsort, anyone?), so it seemed a little silly to write one of those. Instead, I postulated someone writing a routine that would calculate the permutation needed to sort an array.

Since TDD is all the rage, here’s the test (I’m using C#):

johncode1

Note the validation conditions after the routine has been called: that the permuted values actually are sorted (#2), and that the purported permutation array actually is a permutation (#1, #3, and #4 ). Each of these conditions is suitable as a contract check, since they must always be true, independent of data inputs.

The test-code design complexity issue that I’ve been talking about would come in if we wanted to write a second test, perhaps using a different data-set. In that case, we would either need to write a "design-and-validate" routine that performed phases 2 and 3 together (which is actually almost identical to introducing contract checks), or we would need to pull phase 3 out into another routine, then call it at the end of each test, or exercise some similar architectural cleverness in the test class(es).

In contrast, if we turn the validation conditions into contract checks (by moving them into contract blocks in the routine), then the test now looks like this:

johncode2

 

A lot simpler, eh? The significance is that we just removed a responsibility from the test code – the test code now is only responsible for driving an execution path within the routine; it no longer has responsibility for validating the results. Let me emphasize what I just said, because I didn’t realize it or its significance before I typed it up for this post. In order to solve a once-and-only-once problem, we just removed a responsibility from the test. This would indicate that the true root cause of the complexity is a violation of the Single Responsibility Principle (SRP) by the xUnit test classes – they’re responsible for setup, running, validating and tear-down. Each of the four phases is an independent axis of change; SRP says there should be only one (or was that the Highlander?) :)

Ok, now it’s time for a question: How many of you noticed the bug in my contract check? As a hint, imagine what would happen if the routine were called with this input data instead:

johncode3

 

This is the reason that I wanted to use something related to sorting in my example; it’s very easy to forget the possibility of two identical elements in the list that you’re sorting. (The bug, of course, is that validation 2 should have used "<=", rather than "<".) This is also the heart of why Test2 is a better way of doing things than Test1 – the contract checks in Test2 have a chance of picking up the oversight as a side-effect in another test.  And if the oversight is detected, it is immediately localized to the permutation routine.

This is what I meant in my previous post about "Configuration Coverage" and "(No Need) for Cleverness" – including the validation code in the method gives us a much better chance (than external validation) of picking up and localizing the fact that we missed a subtlety.

Note that such a bug in the contract is important even if the routine works correctly; the fact that the contract is wrong means that the developer didn’t understand everything about the possible input configurations. There are several possible ways the routine could manage duplicate entries; the point is that the choice of behavior should be a conscious decision. Understanding these choices can lead to completely different choices of algorithm and (more importantly) client code behavior and assumptions.

Finding contract bugs is also important in a software-as-an-ecosystem analysis. Recall that the vast majority of defects in a major application like ACIS are not due to "happy path" failures of methods. Instead they come from low probability, hard-to-think-of data configurations (such as repeated list elements in the permutation example) generated in the environment of the application being run millions of times. One way to counteract this environmental dependency and increase robustness is to use provably correct algorithms. The problem is that these proofs rely on correctly understanding exactly those corner-cases which are so hard to think of; missing a case means that the correctness proof could be wrong and the algorithms susceptible to environmental changes.

You might also like...

5 Min read
3D Modeling
What is digital manufacturing? Here’s a simple digital manufacturing definition: the process of using computer systems...
5 Min read
3D Modeling
Software components are like the stage crew at a big concert performance: the audience doesn’t see them, but their...
Application Lifecycle Management Flow
4 Min read
3D Modeling
When you hear the term, Application Lifecycle Management (ALM), you likely think about the process that a software...
8 Min read
3D Modeling
What is Computer Aided Manufacturing The CAM Market Who Uses CAM Software? Trends in CAM What do CAM Software...
9 Min read
3D Modeling
SLS in Additive Manufacturing is used to convert 3D CAD designs into physical parts, in a matter of hours.
8 Min read
3D Modeling
There’s a lot of confusion around what the terms additive manufacturing and 3D printing mean.
4 Min read
3D Modeling
Additive manufacturing, often referred to as 3D printing, is a computer-controlled process for creating 3D objects.
5 Min read
3D Modeling
Take a fresh, new sheet of paper, and fold it in half, like you’re making a paper airplane. Place the folded paper on...
6 Min read
3D Modeling
Table of Contents Simulation in CAD Who Uses Simulation Modeling? Key Benefits of Simulation Modeling Challenges in...
8 Min read
3D Modeling
What do you do? What Exactly is FEM? What You Need to Know About Choosing a FEM Modeler FEM and Partial Differential...
5 Min read
3D Modeling
Computational Fluid Dynamics (CFD) is a type of analysis that provides insight into solving complex problems, and...
2 Min read
3D Modeling
WRL files are an extension of the Virtual Reality Modeling Language (VRML) format . VRML file types enable browser...
Voxel model example
3 Min read
3D Modeling
Voxels are to 3D what pixels are to 2D. Firstly -- let’s examine what pixels actually are. Everything you see on your...
Point_cloud_torus
2 Min read
3D Modeling
Point-cloud modeling is typically used in the process of 3D scanning objects. Rather than defining surfaces through...
Polygonal Modeling
2 Min read
3D Modeling
Polygonal (or polyhedral) modeling is the most common type of modeling for video games and animation studios. This type...
aerodynamics-CFD
9 Min read
3D Modeling
Computational fluid dynamics (CFD) is a science that uses data structures to solve issues of fluid flow -- like...
BREP Model example
2 Min read
3D Modeling
BRep modeling, or Boundary Representation modeling, is, in CAD applications, the most common type of modeling. BRep is...
Feature Recognition Zoomed
5 Min read
3D Modeling
IN THIS ARTICLE: What is FEA (Finite Element Analysis) Principles of Finite Element Analysis and Simulation Software A...