Thursday 7 May 2015

PeanutButter TempDb gets LocalDb support

PeanutButter.TestUtils.Generic contains a lot of stuff, including TempDb<>, a generic abstract class which can be used to create temporary database instances and two derivatives, TempDbSqlite and TempDbSqlCe which, as the names might suggest, provide temporary databases of the Sqlite and SqlCe flavours.

Tonight, I added TempDbLocalDb which uses SQL Server's LocalDB mode (as is the default mechanism for MVC web applications. Whilst this does seem to take a little longer to spin up, it means that your tests can now have full SQLServer support with a temporary database which is automatically cleaned up as your tests end.

TempDb<> implements IDisposable, so the natural flow would be something like:

using (var db = new TempDbLocalDb())
{
    var connection = db.CreateConnection();
    connection.Open(); // if you need it open first
    // do stuff with the connection
    // for example, create an Entity context using the DbConnection
}
 
Thanks to Andrew Russell for the idea and pointing me at some resources (http://blog.developers.ba/localdb-for-database-integration-testing-in-asp-net-5-project-and-xunit-net/) which got me going.

You can install via nuget with:

install-package peanutbutter.testutils.generic

Hope this is of use to someone. Whilst it's true that providing a repository layer, for example, and mocking out data get/set operations is a lot faster (and probably better design), there are times when you just have to test against a database engine (for example, when testing that your database migrations work and that your entity models align with your migrated database structures... you are testing that, aren't you?)

Update (2015/06/03):  the TempDb packages have (finally) been split out and swept up so you don't have to install all of the providers you're not using. Check out the post here: http://davydm.blogspot.com/2015/06/a-little-peanutbutter-housekeeping.html

Monday 4 May 2015

Kata - Part 2: In which speed becomes the primary focus

Pursuant to part 1, this is the story of how the speed-run kind of got out of hand.

So I was chasing this time: 12:44. It was faster than I'd ever been, and... there was that damn smiley-face mocking me.

I sat down and thought about it for a while. The first step of optimising for speed is simply this:

Do less.

So I did -- using the tooling at my fingertips, learning more about what I could get it to do, trusting in the R# completion a bit more (which I used to trust only when I couldn't be bothered to type something out in full or when I wanted to take advantage of the automatic library inclusions) and figuring out how I could write my code with the least keystrokes -- with the proviso that the code still had to be something I liked. That means no single-character variable names or stupid test names. My tests must still describe what they do -- they still have to follow the template

{MethodName}_Given{Input}_Should{ReturnSomething or HaveSomeEffect}

My implementation should still be pleasurable to read. I'm an advocate of the idea that good code doesn't need comments because it already reads like a story, conveying the author's intents to the reader whilst simultaneously allowing the compiler to convey the author's intents to the host machine.

I also still had to follow TDD: write a test, test must fail for the correct reasons, write simplest implementation, test should pass, optionally refactor if I can think of a better way to write it. It's important to note the "optionally" part of this last step: when optimising for speed, I don't want to compromise code quality, so I try to write the "best" code first. I do think that I can write prettier code (and I have, for the same kata), but I have allowed simpler code where that would shave seconds off of the final time.

Of course, the next place you get to after "do less" is quite simply "get faster". Whilst engaging in that cycle though, being aware of ways you could "do less" whilst still maintaining the parameters of the assignment becomes vital: sometimes getting faster at a particular unit of work uncovers how you could do less there (or elsewhere). It's quite a lot like optimising code for execution times.

My speed-run implementations centered around an extension-method approach, which I think provides a level of readability to the final result. Extension methods are, IMO, one of the best features of .NET and I use them in production to make code read better -- code which reads better is easier to maintain and has less ramp-up time for the new developer who invariably is saddled with the troubles of coders past.

I slowly whittled away at my 13:48:
10:42...
09:16...
08:48...
and, this morning:
07:35.

Now bear in mind that Katarai does give me a little time boost here: the system bootstraps a solution with a shell test fixture and a shell implementation which has the Add method throwing NotImplementedException. So if I were to do this bare-bones, I'd expect probably another 30 seconds for creation of those files. In other words, I'd like to recognise that this isn't the time required to write every character of code in the outcome. On the other hand, I also make mistakes in this run, so I could theoretically go faster -- though I'm not sure if there's any point in trying to do so (and I also said that when I did 10:42, so... yeah...).

You can view the kata here: StringKata 2015-05-04, completed in 07:35 if you'd like.

I had to tweak my whole way of doing things to get down to this time, including
  • moving my taskbar to the right so that Katarai wouldn't overlay the area I was working on
  • learning to trust in R#'s code completion more
  • using R#'s CamelCase feature
  • learning the requirements for the kata so intrinsically that, in this particular run, I actually "forgot" where I was in the whole process, but somehow continued to write the next correct test. Weird.
The question, of course, is what the value is of completing a kata in this kind of time. I'd argue that a lot of the value of the kata is lost once you've got to the point of knowing the steps and your counter-argument implementation iterations so well. I'm not thinking about a new way to complete the problem. I'm not critically analysing my thought processes around the problem or TDD. I'm blindly banging it out... Write test!... Run all!... Write code!... Run all!... Write test!... Run all!... Write code...! Lather! Rinse! Repeat!.

I had actually argued that I thought I wasn't gaining anything once I got past around 12 minutes, until a conversation with Chris Ainslie this morning. He raised the same question: "Once you're going that fast, is there anything to gain from the kata?". In talking it out though, I can attest that there is something to gain in a pure speed-run, much like there might be something to gain through placing another arbitrary constraint on the problem, a practice which is sometimes used to stretch the kata or make the process a little more mindful. Constraints that I have tried for a kata include:

  • No mouse (this will get you familiar with your keyboard shortcuts, for sure)
  • Implementation has no variables or state or loops. LINQ is allowed. Logic is allowed, through the terniary operator only. All member methods start with the return keyword (I find the result from this constraint set particularly pleasing and it's the basis for my speed-run result, though being pure on this does take a little longer).
  • Implementation makes use of no LINQ or inbuilt string functions (yes, write your own Split! Just like grandpa used to! *ahem* I mean, just I like I used to, back in the days of C)
By making the constraint the rather open-ended "shortest time possible", I have gleaned the following:
  • Learned more about my tooling (I've mentioned R# and code completion, for example)
  • Practice typing for speed and practice reducing typos when typing at speed!
  • Learn to evaluate a prior test as a possible candidate for a shell for a new test which can be modified and used in a shorter time than writing the test from scratch
  • Enforcing a strict adherence to readable code, even when time is tight
  • Enforcing a strict adherence to TDD, even when time is tight
  • You can always get a little better; always go a little faster. Translated to production code, this makes me more critical of the code that I am writing -- could I have done it more succinctly (but still make it read like a story)? Have I done the smallest thing possible or am I gold-plating? Am I implementing features which aren't (at least not yet) actually required? This last one trips us all up: we all too easily get into a mindset of trying to produce perfect code instead of great code which can be extended on requirement.
At the very least, this video should suppress the argument that I have heard that doing a String Kata in 20 minutes is a ridiculous requirement. If I can do it in 07:35, so can you -- indeed, I bet this is still far from the floor of times that are possible for this kata.

Kata - Part 1: The gauntlet is thrown.

Kata are, according to Wikipedia, foundry of all knowledge (and often of factually correct knowledge) "the detailed choreographed patterns of movements practised either solo or in pairs".

In software circles, there's a similar concept, embodied by the practice of test-driven code exercises, often with the premise of a rather synthetic problem which the user (or pair) is left to solve in the strictest sense of TDD that she/he/they can muster. The point is to provide a problem which isn't necessarily new or tricky, leaving the body of the exercise to the players to practice their TDD cadence:
  • Red: write one test and one test only, which tests a very specific requirement of the specification. Running all tests should give one "Red" result (one test fails, on purpose, for the intended reason).
  • Green: implement the bare minimum code to get the last test to pass. Running all tests should give all "Green" results (all tests pass).
  • Refactor: step in which the practitioner evaluates the code which was implemented to make the test pass and optionally renames, refactors or tidies up. If the code is deemed to be in a good state, the process is repeated.
Performing code katas provides the practitioner the opportunity to practice the strictest sense of TDD as well as examine programming, testing and style habits. The main idea is that the perfection which is sought during the kata will seep into production code. Some supplementary goals are to strengthen the practitioner's familiarity with her tools, hone her skills and encourage thought of alternative paths to the solution which still adhere to the TDD cadence. In addition, a kata can be used as a "jump-start" for the code "juices" as it were: an exercise where the output will be discarded (and hence isn't completely material), but where the practitioner's thought patterns can be aligned with the environment of programming towards a goal in preparation for production work.

At least, I've found it can be a good way to get the coding started.

I work at Chillisoft where one of the products in development at the moment is a kata assistant: Katarai. (Full disclosure: much of the gruesome innards of Katarai are the result of a fevered few tinkering sessions with a colleague, Mark Whitfield, so I kind of have a dog in this race, though I'm not part of the active development team for it).

Katarai aims to address a few issues with the code kata concept:
  • Seasoned developers often can't wrap their heads around the concept of writing code you know you're about to throw away, or the concept of practicing TDD cadence simply for the practice. Katarai provides feedback of your progress through a kata as well as providing (in the future), feedback about your improvements / changes over time (and potentially a competitive flavour in that you could compare times or other metrics you derive from katas with those of your friends).
  • Juniors may find it difficult to get into katas -- the code requirements can be a little esoteric and the TDD cadence hasn't taken hold yet.
  • Code katas aren't necessarily fun by nature -- Katarai tries to change this perception a little.
  • Katarai also times your attempts -- which leads us to where we are with this article. More on that later. 
(and probably others).

I gladly postulate the code katas are beneficial for programmers of any level. You could use them to familiarise yourself with a new language, you can use them just as part of the rhythm of your coding day, you can use them to keep your keyboard and tooling skills tip-top... Basically, you can use them for the same reasons martial artists do:  

"The basic goal of kata is to preserve and transmit proven techniques and to practice self-defence. By practicing in a repetitive manner the learner develops the ability to execute those techniques and movements in a natural, reflex-like manner."

Replace "self-defence" with "the skill you aim to master" and you can see how the concept applies to code (:

Recently, there was a challenge at work to complete the String Kata (yes, I really did just push you off to Google there -- there are too many great links to follow!) in under 17 minutes. The challenge isn't all that foreign to us: a few months back, a requirement was put forth that all developers should be able to complete the String Kata in 20 minutes or less to demonstrate proficiency in their programming environment. The original "20 minutes" requirement could be met in any language and environment of choice. The 17-minute challenge was done as part of internal testing for Katarai, so had to be in C#, using Visual Studio, though addons and extensions which facilitate production are also allowed.

I had already been testing out Katarai (that whole "dog in the race" thing), so I ran a quickie and submitted my time for the competition: 13:48. I thought that was a reasonable time; it was certainly well under the required 17 minutes and one of the fastest times I had recorded. I was quite pleased with myself.

It wasn't long until Peter Wiles replied to the mail thread to the effect that he had completed in 12:44.

The time was a challenge. The little smiley-face at the end of the email was just plain infuriating.

Read more in part 2

What's new in PeanutButter?

Retrieving the post... Please hold. If the post doesn't load properly, you can check it out here: https://github.com/fluffynuts/blog/...