DaedTech

Stories about Software

By

ChessTDD 36: Acceptance Tests for Queen Movement

This episode went smoothly until I discovered a bug.  Philosophically, I suppose this is the natural state of software development.  For my purposes here, though, hunting down the bug caused the episode to balloon to 26 minutes, so I’m going to try a new thing so as to keep the videos a reasonable length of time.  I’m splitting it into 2 videos: parts A and B.  Please let me know if this approach is preferable to sometimes having long videos or not; if you leave feedback, I’ll more likely do it the way you prefer, since I’m just trying to go with what people like.

What I accomplish in these clips:

  • Created a couple of code snippets in CodeRush to get rid of the hand typing in the specflow scenarios.
  • Wrote acceptance tests for the queen’s movement.
  • Squashed a subtle bug (or at least half of one).

Here are some lessons to take away:

  • Projects go better when there are more eyeballs on them.  Run things you’re doing by other people and see if they have suggestions that might help.  They may think of things that never would have occurred to you and might later seem obvious.
  • Whenever you make mistakes copying and pasting, it’s a crapshoot whether fixing them takes more time than you would have spent hand-typing or not.  In my experience, most of the time you don’t come out on the winning end, and wholesale copy-paste obscures your understanding.  This is why I try to avoid the practice.
  • What I find is that unit tests should be very directed and specific about system behaviors.  But acceptance tests let you put on your exploratory testing hat, dreaming up scenarios in which users might use this thing that could potentially break it.  For you unit testing newbies, fight the urge to write unit tests with lots of assertions that cover a lot of ground.  You can express that in your acceptance tests.
  • Once again, don’t do low-hanging fruit refactorings (e.g. deleting dead code) when you have red tests.  It might seem like it’s not a problem, but it will come back to haunt you at some point.
  • Another example in this episode of finding a bug with a failing acceptance test, and drilling in to get closer by writing failing unit tests.  This is an excellent and helpful practice.
  • TDD facilitates Eureka moments where you try something you think might work and you see all of your tests go green.  However, just like trying something in your code and seeing the application magically behave correctly next time you run it, it’s important to cement your understanding of why it worked.  Don’t program by coincidence, even if you have a green test suite backing you.  Keep writing tests and/or reasoning about the code until you’re sure you understand what’s happening.  (Writing tests provides an excellent way to prove your understanding to yourself).

  • Oded Coster

    Just realized that your full board has the black king and queen in the wrong positions (queens and kings for both colors start on the same column, also stated as white queen starts on a white square and black queen starts on a black square).

    • Good catch. I’ll fix that in the next episode. Been a while since I’ve played, and the color heuristic you mention is how I setup pieces (find the middle square of my color, put the queen there), so not having a board with actual colors on it kind of messes with me.

  • Having a two-part video was an improvement. It gives people the option to watch the second one later. My issue (i.e., not something I expect you to address) is that if I know all the content is available, I’m compelled to watch both in one sitting just so I can check it off my list.

    • Glad to hear it was better. I’m still striving for shorter episodes on the whole, but I’m realizing that’s not always possible. Basically, if I get 10 minutes in and start down a rabbit hole, my choices are this or backing out my changes and doing a more practiced run at it (which goes against my promise of un-edited development).

      By the way, I totally know what you mean about checking things off of your list 🙂

  • Guy Boicey

    I don’t mind the two videos, but I’m also capable of making a mental note as to the time I stopped a video to watch later. In case I have to take a break, to do, squirrel.

    • I’m going to do my best to make it not necessary by attempting to avoid flubbing my way into quagmires 🙂

  • Guy Boicey

    readability and the use of var.

    My understanding is that var is best used when the type can be inferred from the line of code. But when in those cases where you can’t infer the type then included type. With the exception if the line to too long then use var. This is like i before e except after c and then for all these other rules. I know I’m going to ask this questions. But, I figure the answer based on the videos so far, that you favor var regardless. I get the brevity of code, but for the sake of readability? I have seen this as a theme throughout the videos. Actually, I see the type then the use of CodeRush to turn into var. I guess this is more of an opinion than a question.

    In this line:

    var checker = new PathMaker(origin, destination);

    I can infer that checker is of type PathMaker, but in this line:

    var spacesAlongPath = check.GetPathToDestination();
    var lastSpace = spacesAlongPath.LastOrDefault();

    I don’t know the type of spacesAlongPath nor the type lastSpace.

    In contrast there is the example below, which uses var because the line with the type is too long. I was going to use a the spacesAlongPath as the example, but because I can’t infer nor do I know the type GetPathToDestination returns (case in point) I had to use another example. Another opinion/question, is using var lazy coding? This is in line to the philosophy of not copying and pasting (which I love). Again this might be along the same philosophy of making videos shorter, blog post shorter, tweets shorter, FaceBook post shorter, I better wrap this up because if I continue no one will read this.

    ObservableCollection orders = cust.Orders;
    var orders = cust.Orders;

    • I’ve written about this some. In this post: http://www.daedtech.com/a-rider-to-the-law-of-demeter I refer to an older post where I address this topic in the comments too. TL;DR is that the reason I favor var everywhere revolves around comparable ease of refactoring as well as gentle pressure to write better names. I also have a broader philosophy where I don’t much sweat coding standards and am not terribly interested in stylistic debates. What I mean is, if we cover the code well with tests and factor it decently, then if you prefer reading it with explicit typing in some cases, by all means, change it as suits you (I do the same with other people’s explicitly typed code).

      I actually once worked in a group that wanted explicitly typed variables everywhere, and I automated a shortcut that would convert every declaration in the file to explicit and back so that I could check it out, read it the way I liked, then put it back the way others liked.

      • Guy Boicey

        Nothing in theory is TL;DR unless we are lazy. If that was the case half you blog post would not be read. If not for readability but for brevity. Why then do I see code with class names a mile long.

        Another question/opinion how does var impact type safety? I read the article and the comments about compiling. In the example, as a consumer/client of the library I would always assume it to be int. I can perform int specific logic and assign the results to int. If the producer changed to long that would be a breaking change. As the library developer I’m making a grave assumption that consumers of my library are using var. Regardless of var usage I would still need to recompile, but without having to change code.

        Can you expand on how refactoring is easier with var vs. type? Or expand on how refactoring differs with var vs. type? If I was the consumer of my own library and used int. When changing to long, the refactoring not only takes care of the return type but also the place where the method was used. I understand if I used var then I would only need to change the methods signature, but again how does type safety factor in.

        Without a type I have to assume that GetFoos() returns a bunch of Foos as ICollection, IEnumerable, List, or IList. These different types act differently? Therefore making it a challenge to determine the usage of the object if var is used instead of a type.

        Reminds me of when in episode 33 (5:00 – 7:30) you where trying to figure out the CollectionAssert. I was unable to figure things out as I was watching because the object storing the values from board.GetMovesFrom was not typed. I know it was a collection, but did not know if it was IEnumrable, IList, List, ICollection or something else. I had to pause as you hovered over it to get the type (5:09). I wonder, did you hover over it to get the type? Would you have had to do that if the type was used instead of var?

        I don’t know, either way is okay, this is just one of those slippery slopes. I can only image those meetings, should it be done or not. They must have been very interesting.

        • Just to clarify something up front (not wanting to assume anything about what you do or don’t know), using implicit typing has no actual impact on the compiled IL. So, if I write var x = GetFoo() and GetFoo() returns ICollection, x is an ICollection. Compiled, it’d be identical to me having ICollection x = GetFoo(); (Apologies if you’re already aware of that — just want to be clear)

          So, regarding type safety, “var” thus has no impact. If I’m consuming a library with an interfaced method that returns int, and they introduce a breaking change to have it return long, sure, that’s a bummer and it’s annoying for me, but I don’t control it. In the case of var, I recompile and life is fine. In the case of int x = whatever, I have to go in, modify my code and recompile.

          About refactoring, it’s easier for me because I cover code with tests and then do a lot of method extraction, method inlining, and general churn of implementations within classes. If I leave everything as var, it’s easier for me to change return types that are applicable only within the class as private methods and it does come up that I want to do this. Off the top, maybe it’s something like var x = someLocal.GetWhatever() and I want extract someLocal.GetWhatever() into a private method and tweak the return type somehow. Explicitly typed, that’s going to mean two steps, implicitly typed, it means one.

          It’s really just a personal preference that I’ve developed from having spent a good bit of time writing code in both styles. I don’t know that I’d try to persuade anyone to do it my way, really. All I can do is explain how I’ve come to where I am (and say that it’s subject to change, because I often try new things and wind up liking them)

          • Guy Boicey

            Being clear is good. After 20 years I still try as hard as possible to be humble, convincing myself that I don’t know anything and I don’t. My point was more of var x = GetFoo() I don’t know if it is ICollection or List, or …. without IntelliSense or some other way to determine it. One type acts different than another. I also gather that maybe like me your team of people is small, so small it is person not people. I think what we can agree on is this is more of a personal preference. I’m sure in the meetings the powers at be had foreseen conversations late at night by programmers discussing the philosophy of var. No different than the discussion of strings being null vs empty. I just like to get different opinions on the pragmatic parts of programming. thanks for taking the time and sharing you bring up some good points.