DaedTech

Stories about Software

By

Chess TDD 16: Finishing Bishop Blocking

Once again I’m bringing you this code-cast from a Marriott, albeit a different one. In spite of a bizarre amount of noise over the course of the evening for a business hotel, I’ve managed to get at least passingly decent audio for this (and for some ongoing Pluralsight work as well). This is a pretty workmanlike episode where I dive into the refactoring I didn’t have time for last weekend and then use the resultant code to make my life easier as I finish the bishop implementation.

Also, as a quick aside, someone asked me a little while back for some advice about how I approach integration/system testing, and I was thinking I might just plow through this series to demonstrate where and how I’ll start bringing in broader tests. So, stay tuned for that, probably whenever the blocking implementation is finished.

Here’s what I accomplished in this clip:

  • Refactored a seriously bad piece of code for diagonal blocking.
  • Fleshed out the diagnoal blocking to handle all cases.
  • Satisfied myself that diagonal blocking is reasonably robust.

Here are lessons to take away:

  • If you’re not sure what to name a method that you’re pulling out, don’t interrupt your flow by obsessing over what to call it.  Naming is extremely important and you definitely want to come back to it, so just call it something like “Dunno()” and focus on the refactoring for the time being.  That silly, glaring name will prevent you from forgetting to come back and think through the name when you understand better what you want to do.
  • Oops.  Didn’t pay close enough attention to my little NCrunch notifier going red during a refactoring.  When that happens, don’t say, “uh oh” and go trying to fix the problem.  Start hitting undo until you’re green again.
  • Whenever something you want to do to the code strikes you, hurry over to Trello (or Excel or whatever) and add it.  TDD makes it easy to pick up where you left off, but you’ll often forget about stuff you want to do if you wait to note it.
  • If you’re not totally comfortable with your implementation, it’s perfectly fine to write a test that you expect (okay, maybe hope) will go green and then move on, more confident, when it does.  TDD discipline says that to change the behavior of production code you need a red test.  It doesn’t say that you always have to write tests expecting them to go red.  Anything that tells you more about the system or increases your confidence in it is a benefit.

By

Chess TDD 15

Prompted by comments from a few people, I’ve decided to see if I like using Trello for keeping track of the TODOs instead of Excel. Also, learning from past feedback, I’ve defaulted Trello to being really big when recording so everything is legible, and I copied everything over from Excel. Hopefully I like it as I go, but please let me know if it’s more pleasing to view as compared with the Excel spreadsheet, if it matters to you one way or the other.

Also, a meta-note. I apologize for the time between posts in the series and for the lack of posting in general, but I’ve been traveling nonstop and am pretty much living out of hotels, meaning my life is one of 3G-ish wifi and sub-optimal setups. Luckily, I’m driving everywhere and lugging my boom mic, desktop and monitors with me so I can still record in the hotel. 🙂

Here’s what I accomplish in this clip:

  • Make the “blocked” algorithm for horizontal/vertical less dumb.
  • Start the implementation for “blocked” diagonal.
  • Inadvertently create a potential solution for the problem of knight’s oddball movement.

Here are lessons to take away:

  • Even little things matter when it comes to readability.  For instance, at 0:40 I noticed that my test class name ended in should but the methods started with “returns.”  So, I took the time to fix this.  My advice is to get in the habit of avoiding sloppiness and inattention to detail at any level of code.
  • Bear in mind that changing prod code is fine while green in TDD, provided you’re not looking to introduce new behaviors.  It’s a refactoring if your goal is continue satisfying existing test cases in a different way.
  • A little before 10:00, I refactored a bit of a test while red for the sake of readability.  I shouldn’t have.  My bad.  Lesson is, no matter how much TDD you do, sometimes you flub it.
  • Sometimes a great way to get things passing when the implementation is getting hairy is to tease out a conditional that only applies to your new case and do something obtuse.  Use with discretion because it can lead you into blind alleys and cause problems, but there are times when getting to green can provide an aha! moment.
  • You’ll notice I refactored to a different method signature, changed some stuff around, and then refactored back.  This kind of waffling is fine.  With TDD, you’ll get used to fearlessly refactoring and slinging stuff around until you settle on something you like (or at least thing is the least bad, for now).
  • Get it working ugly now, make it pretty later.  It’s sometimes amazing how an algorithm will suddenly make itself obvious after a bit of brute forcing and futzing around.

By

Chess TDD 14: Figuring Out Blocking Pieces

In this installment, I’m looking to start defining the concept of “blocking” on a chess board. So far, I’ve been defining piece moves in a vacuum — put a rook down in (1, 1) and the rook can go anywhere in column 1 or row 1. But, what about when there’s a pawn at (1, 2)? That’s what’s on the docket in this episode.

Here’s what I accomplish in this clip:

  •  Started implementing the concept of pieces “blocking” one another.
  • Expanded the blocking logic to include horizontal and vertical blocking in both positive and negative directions.
  • Realized I’d been wrong about how Enumerable.Range() worked for a good long time because I had always used it for 0 indexed number generation, which masked my wrongness.

And here are some lessons to take away:

  • If you’re anything like me, sometimes you’ll thrash a bit between micro design decisions.  I introduced the concept of BoardCoordinate to avoid passing (int x, int y) to every method under the sun, but then I started to get annoyed by the ceremony of declaring new BoardCoordinate(x, y) everywhere.  Result was (for now) to implemented BoardCoordinate.For(x, y) which struck me as at least slightly more readable and elegant.  Point is, you probably won’t hit your most simple/elegant design on your first, second, or even third crack.  Keep at it, don’t be afraid to experiment, and solicit opinions and advice.  (Speaking of which, anyone with a good idea for this, please chime in!)
  • “Do the simplest thing you can to make the test pass” is not just a function of what you do in the production code but also of what test you’ve written.  In other words, make sure you don’t write an overly ambitious test like “test_that_all_end_user_requirements_are_satisfied” or the simplest thing you can do to make it pass will be really complicated.
  • TDD is the ultimate in “fail fast.”  I wasted about a minute of my time (twice) and a minute of yours (once) because I couldn’t figure out that I was calling Enumerable.Range(int, int) with the wrong second parameter.  But, seeing NCrunch’s dots turn red told me something was wrong very, very quickly while what I did was still fresh in my mind.  I didn’t know I was misremembering the method signature, but I did know that something about Enumerable.Range() in there was breaking things.  Without TDD, I’d have gone merrily on writing code for minutes or even hours until I fired up the whole application and wondered why the blocked rook could randomly move to one spot on the board in front of the opponent’s pawns or something.  I’d have wasted a lot more of both of our time trying to hunt down the problem then, when I had no clue which line of code was the offender.
  • There are times when the code smell of duplication or duplicate effort appears, but the solution isn’t immediately obvious (such as the case in this video where I was doing similar things for horizontal and vertical).  It’s my experience that you can find yourself in a blind alley when you try to abstract this to a common method where it becomes a snarl of conditionals or very dense, opaque mathematical logic.  Eliminating duplication is extremely important, but beware of times when you have “duplication elimination fools’ gold” and the gains in readability/maintainability actually go into the negative.  Be sure that your abstraction is actually making things simpler.
  • I didn’t like a number of things about this code when the clock started getting pas the 20 minutes mark and I felt the pressure not to make this a horribly long episode.  It might not be the same reason, but there are going to be times when you’re forced to get up and leave for the time being or for the day when you’re not thrilled with the code.  It’s okay — you’ll have another crack at it tomorrow with a fresh mind, and the TDD will help you pick right up where you left off.

By

Chess TDD 13: Moving On

In the last bunch of installments of this series, I’ve implemented methods for pieces to determine where they can move on a board and/or done some refactoring.  But I’ve ridden that train as far as I can, now having implemented all of the pieces, so it’s time to shake things up a bit.  Another thing that makes this post different is that I’m going to try a new way of structuring my test classes.

The other day, in response to a comment, I made a post about test initialize methods and Steve Smith commented and suggested an approach he described in detail in this post on his blog.  The gist of the idea is dispensing with the old stand by of having a test class for class Foo called FooTest and instead having the name of the test class describe the context of the test, BDD-style.  I found this idea immediately appealing and decided I’d try it out in “some project to be determined,” but what’s the fun in that?  Once an idea settles in my head, it’s hard for me to shake it, so instead of doing it later, I’ll do it here, now, publicly.  Apologies in advance (I’m typing this part before recording the coding) if it results in a bit more floundering, but I think it might be fun for us all to learn together.  If nothing else, you’ll get to see how easy or difficult it is to adapt to this convention.

Anyway, here is what I accomplished in this clip:

  • Got started on complete move calculation implementation.
  • Defined the setup of complete board for a lot of tests.
  • Established a new pattern for constructing tests.

And here are some lessons to take away.

  • When you are exposed to a new practice or way of doing things, there’s no time like the present.  While it may not always be practical to ram the new stuff into some time sensitive project, experiment and try it out to see how you like it.  Trying out different techniques keeps you sharp and helps you avoid falling into a rut.
  • When you haven’t looked at code in a long time, it’s easy to lose track of internal implementation of classes.  One of the real perks of TDD and having a test suite is that it’s easy to poke and experiment to see what’s going on without fear that you’re going to break something.
  • If kept concise and focused, a bit of yak-shaving in your implementations can be pretty productive.  Always be looking to improve on your code’s readability, elegance, and efficiency if you can.
  • It’s important to keep your test suite as communicative and descriptive as possible, and you should always be looking for ways to help you toward that end.

By

In Defense of Test Setup Methods

This post started out as a response to a comment on this post, but it started to get rather long for that venue, so I’m making it its own post. The comment concerns my habit of pulling instantiation logic for the class under test into a common setup method executed by the test runner prior to each test. Here are the main points that I’m writing this to address:

  • Why do I dislike code duplication in tests?
  • Extracting logic to a common setup method creates performance problems.
  • The indirection in pulling part of the setup out of a test method hurts readability.

Back Story and Explanations

I wrote this post a little under two years ago. It’s germane here because I explain in it my progression from not using the setup method to doing so. For those not explicitly familiar with the concept and perhaps following along with my Chess TDD series, what I’m referring to is a common pattern (or anti-pattern, I suppose, depending on your opinion) in unit testing across many languages and frameworks. Most test runners allow you to specify a unique method that will be called before each test is run and also after each test is run. In the case of my series, using C# and MSTest, the setup happens on a per class basis. Here’s some code to clarify. First, the class under test:

public class Gravity
{
    public decimal GetVelocityAfter(int seconds)
    {
        return 9.8M * seconds;
    }
}

And, now, the plain, “before,” test class:

[TestClass]
public class GravityTest
{
    [TestMethod]
    public void GetVelocityAfter_Returns_Zero_When_Passed_Zero()
    {
        var gravity = new Gravity();

        var velocityAfterZeroSeconds = gravity.GetVelocityAfter(0);

        Assert.AreEqual(0, velocityAfterZeroSeconds);
    }

    [TestMethod]
    public void GetVelocityAfter_Returns_Nine_Point_Eight_After_1_Second()
    {
        var gravity = new Gravity();

        var velocityAfterOneSecond = gravity.GetVelocityAfter(1);

        Assert.AreEqual(9.8M, velocityAfterOneSecond);
    }

    [TestMethod]
    public void GetVelocityAfter_Returns_NinetyEight_After_10_Seconds()
    {
        var gravity = new Gravity();

        var velocityAfterTenSeconds = gravity.GetVelocityAfter(10);

        Assert.AreEqual(98, velocityAfterTenSeconds);
    }       
}

And finally, what MS Test allows me to do:

[TestClass]
public class GravityTest
{
    private Gravity _gravity;

    [TestInitialize]
    public void BeforeEachTest()
    {
        _gravity = new Gravity();
    }

    [TestMethod]
    public void GetVelocityAfter_Returns_Zero_When_Passed_Zero()
    {
        var velocityAfterZeroSeconds = _gravity.GetVelocityAfter(0);

        Assert.AreEqual(0, velocityAfterZeroSeconds);
    }

    [TestMethod]
    public void GetVelocityAfter_Returns_Nine_Point_Eight_After_1_Second()
    {
        var velocityAfterOneSecond = _gravity.GetVelocityAfter(1);

        Assert.AreEqual(9.8M, velocityAfterOneSecond);
    }

    [TestMethod]
    public void GetVelocityAfter_Returns_NinetyEight_After_10_Seconds()
    {
        var velocityAfterTenSeconds = _gravity.GetVelocityAfter(10);

        Assert.AreEqual(98, velocityAfterTenSeconds);
    }       
}

Okay, so what’s going on here? Well, the way that MS Test works is that for each test method, it creates a new instance of the test class and executes the method. So, in the case of our original gravity test class, three instances are created. There is no instance state whatsoever, so this really doesn’t matter, but nonetheless, it’s what happens. In the second version, this actually does matter. Three instances get created, and for each of those instances, the _gravity instance is initialized. The “BeforeEachTest” method, by virtue of its “TestInitialize” attribute, is invoked prior to the test method that will be executed as part of that test.

Conceptually, both pieces of code have the same effect. Three instances are created, three Gravity are instantiated, three invocations of GetVelocityAfter occur, and three asserts are executed. The difference here is that there are three gravity variables of method level scope in the first case, and one instance variable of class scope in the second case.

Okay, so why do I choose the second over the first? Well, as I explained in my old post, I didn’t, initially. For a long, long time, I preferred the first option with no test setup, but I eventually came to prefer the second. I mention this strictly to say that I’ve seen merits of both approaches and that this is actually something to which I’ve given a lot of thought. It’s not to engage the subtle but infuriating logical fallacy in which an opponent in an argument says something like “I used to think like you, but I came to realize I was wrong,” thus in one fell swoop establishing himself as more of an authority and invalidating your position without ever making so much as a single cogent point. And, in the end, it’s really a matter of personal preference.

Why I Don’t Like Duplication

So, before I move on to a bit more rigor with an explanation of how I philosophically approach structuring my unit tests, let me address the first point from the comment about why I don’t like duplication. I think perhaps the most powerful thing I can do is provide an example using this code I already have here. And this example isn’t just a “here’s something annoying that could happen,” but rather the actual reason I eventually got away from the “complete setup and teardown in each test” approach. Let’s say that I like my Gravity class, but what I don’t like is the fact that I’ve hard-coded Earth’s gravity into the GetVelocityAfter method (and, for physics buffs out there, I realize that I should, technically, use the mass of the falling object, gravitational constant, and the distance from center of mass, but that’s the benefit of being a professional programmer and not a physicist — I can fudge it). So, let’s change it to this, instead:

public class Gravity
{
    private Planet _planet;

    public Gravity(Planet planet)
    {
        _planet = planet;
    }

    public decimal GetVelocityAfter(int seconds)
    {
        return _planet.GetGravitationalFactor() * seconds;
    }
}

Now, I have some test refactoring to do. With the first approach, I have six things to do. I have to declare a new Planet instance with Earth’s specifications, and then I have to pass that to the Gravity constructor. And then, I have to do that exact same thing twice more. With the second approach, I declare the new Planet instance and add it to the Gravity constructor once and I’m done. For three tests, no big deal. But how about thirty? Ugh.

I suppose you could do some find and replace magic to make it less of a chore, but that can get surprisingly onerous as well. After all, perhaps you’ve named the instance variable different things in different places. Perhaps you’ve placed the instantiation logic in a different order or interleaving in some of your tests. These things and more can happen, and you have have an error prone chore on your hands in your tests the same way that you do in production code when you have duplicate/copy-paste logic. And, I don’t think you’d find too many people that would stump for duplication in production code as a good thing. I guess by my way of thinking, test code shouldn’t be a second class citizen.

But, again, this is a matter of taste and preference. Here’s an interesting stack overflow question that addresses the tradeoff I’m discussing here. In the accepted answer, spiv says:

Duplicated code is a smell in unit test code just as much as in other code. If you have duplicated code in tests, it makes it harder to refactor the implementation code because you have a disproportionate number of tests to update. Tests should help you refactor with confidence, rather than be a large burden that impedes your work on the code being tested.

If the duplication is in fixture set up, consider making more use of the setUp method or providing more (or more flexible) Creation Methods.

He goes on to stress that readability is important, but he takes a stance more like mine, which is a hard-line one against duplication. The highest voted answer, however, says this:

Readability is more important for tests. If a test fails, you want the problem to be obvious. The developer shouldn’t have to wade through a lot of heavily factored test code to determine exactly what failed. You don’t want your test code to become so complex that you need to write unit-test-tests.

However, eliminating duplication is usually a good thing, as long as it doesn’t obscure anything. Just make sure you don’t go past the point of diminishing returns.

In reading this, it seems that the two answers agree on the idea that readability is important and duplication is sub-optimal, but where they differ is that one seems to lean toward, “avoiding duplication is most important even if readability must suffer” and the other leans toward, “readability is most important, so if the only way to get there is duplication, then so be it.” (I’m not trying to put words in either poster’s mouth — just offering my take on their attitudes)

But I think, “why choose?” I’m of the opinion that if redundancy is aiding in readability then some kind of local maximum has been hit and its time to revisit some broader assumptions or at least some conventions. I mean why would redundant information ever be clearer? At best, I think that redundancy is an instructional device used for emphasis. I mean, think of reading a pamphlet on driving safety. It probably tells you to wear your seatbelt 20 or 30 times. This is to beat you over the head with it — not make it a better read.

So, in the end, my approach is one designed to avoid duplication without sacrificing readability. But, of course, readability is somewhat subjective, so it’s really your decision whether or not I succeed as much as it is mine. But, here’s what I do.

My Test Structure

Let’s amend the Gravity class slightly to have it use an IPlanet interface instead of a Planet and also to barf if passed a null planet (more on that shortly):

public class Gravity
{
    private IPlanet _planet;

    public Gravity(IPlanet planet)
    {
        if(planet == null)
            throw new ArgumentException("planet");

        _planet = planet;
    }

    public decimal GetVelocityAfter(int seconds)
    {
        return _planet.GetGravitationalFactor() * seconds;
    }
}

Let’s then take a look at how I would structure my test class:

[TestClass]
public class GravityTest
{
    private const decimal EarthFactor = 9.8M;
    private IPlanet Planet { get; set; }
    private Gravity Target { get; set; }

    [TestInitialize]
    public void BeforeEachTest()
    {
        Planet = Mock.Create();
        Target = new Gravity(Planet);
    }

    [TestClass]
    public class GetVelocityAfter : GravityTest
    {
        [TestMethod]
        public void Returns_Zero_When_Passed_Zero()
        {
            var velocityAfterZeroSeconds = Target.GetVelocityAfter(0);

            Assert.AreEqual(0, velocityAfterZeroSeconds);
        }

        [TestMethod]
        public void Returns_Nine_Point_Eight_After_1_Second_On_Earth()
        {
            Planet.Arrange(p => p.GetGravitationalFactor()).Returns(EarthFactor);

            var velocityAfterOneSecond = Target.GetVelocityAfter(1);

            Assert.AreEqual(9.8M, velocityAfterOneSecond);
        }

        [TestMethod]
        public void Returns_NinetyEight_After_10_Seconds_On_Earth()
        {
            Planet.Arrange(p => p.GetGravitationalFactor()).Returns(EarthFactor);

            var velocityAfterTenSeconds = Target.GetVelocityAfter(10);

            Assert.AreEqual(98, velocityAfterTenSeconds);
        }
    }
}

Alright, there’s a lot for me to comment on here, so I’ll highlight some things to pay attention to:

  • Instance of class under test is named “Target” to be clear what is being tested at all times.
  • Planet instance is just named “Planet” (rather than “MockPlanet”) because this seems to read better to me.
  • Nested class has name of method being tested (eliminates duplication and brings focus only to what it does).
  • Test initialize method does only the minimum required to create an instance that meets instance preconditions.
  • There’s not much going on in the setup method — just instantiating the class fields that any method can modify.
  • The second two test methods still have some duplication (duplicate setup).

Now that you’ve processed these, let me extrapolate a bit to my general approach to test readability:

  • The class nesting convention helps me keep test names as short as possible while retaining descriptiveness.
  • Only precondition-satisfying logic goes in the initialize method (e.g. instantiating the class under test (CUT) and passing a constructor parameter that won’t crash it)
  • Setting up state in the class under test and arranging the mock objects is left to the test methods in the context of “Given” for those asserts (e.g. in the second test method, the “Given” is “On_Earth” so it’s up to that test method to arrange the mock planet to behave like Earth).
  • I use dependency injection extensively and avoid global state like the plague, so class under test and its depdenencies are all you’ll need and all you’ll see.
  • Once you’re used to the Target/Mocks convention, it’s (in my opinion) as readable, if not more so, than a method variable. As a plus, you can always identify the CUT at a glance in my test code. To a lesser degree, this is true of mocks and constants (in C#, these have Pascal Casing)
  • I suppose (with a sigh) that I’m not quite 100% on the maturity model of eliminating duplication since I don’t currently see a duplication-eliminating alternative to setting up Earth Gravity in two of the test methods. I think it’s not appropriate to pull that into the test initialize since it isn’t universal and adding a method call would just make the duplication more terse and add needless indirection. To be clear, I think I’m failing rather than my methodology is failing — there’s probably a good approach that I simply have not yet figured out. Another important point here is that sometimes the duplication smell is less about how you structure your tests and more about which tests you write. What I mean is… is that “Returns_NineyEight_After_10_Seconds_On_Earth” test even necessary? The duplicate setup and similar outcome is, perhaps, telling me that it’s not… But, I digress.

Addressing the Original Concerns

So, after a meandering tour through my approach to unit testing, I’ll address the second and third original points, having already addressed the question of why I don’t like duplication. Regarding performance, the additional lines of code that are executed with my approach are generally quite minimal and sometimes none (such as a case where there are no constructor-injected dependencies or when every unit test needs a mock). I suspect that if you examined code bases in which I’ve written extensive tests and did a time trial of the test suite my way versus with the instantiation logic inlined into each test, the difference would not be significant. Anecdotally, I have not worked in a code base in a long, long time where test suite execution time was a problem and, even thinking back to code bases where test suite performance was a problem, this was caused by other people writing sketchy unit tests involving file I/O, web service calls, and other no-nos. It’s not to say that you couldn’t shave some time off, but I think the pickings would be pretty lean, at least with my approach of minimal setup overhead.

Regarding readability, as I’ve outlined above, I certainly take steps to address readability. Quite frankly, readability is probably the thing most frequently on my mind when I’m programming. When it comes to test readability, there’s going to be inevitable disagreement according to personal tastes. Is my “Target” and initialization convention more readable than an inline method variable also with the convention of being named “Target”? Wow — eye of the beholder. I think so because I think of the instantiation line as distracting noise. You may not, valuing the clarity of seeing the instantiation right there in the method. Truth is with something like that, what’s readable to you is probably mainly a question of what you’re used to.

But one thing that I think quite strongly about test readability is that it is most heavily tied in with compactness of the test methods. When I pick up a book about TDD or see some kind of “how to” instructional about unit tests, the tests always seem to be about three lines long or so. Arrange, act, assert. Setup, poke, verify (as I said in that old post of mine). Whatever — point is, the pattern is clear. Establish a precondition, run an experiment, measure the outcome. As the setup grows, the test’s readability diminishes very quickly. I try to create designs that are minimal, decoupled, compatible with the Single Responsibility Principle, and intuitive. When I do this, test methods tend to remain compact. Eliminating the instantiation line from every test method, to me, is another way of ruthlessly throttling the non-essential logic inside those test methods, so that what’s actually being tested holds center stage.

So, in the end, I don’t know that I’ve made a persuasive case — that’s also “eye of the beholder.” But I do feel as though I’ve done a relatively thorough job of explaining my rationale. And, my mind is always open to being changed. There was a time when I had no test setup method at all, so it’s not like it would be unfamiliar ground to return there.

By the way, if you liked this post and you're new here, check out this page as a good place to start for more content that you might enjoy.