Fear and Loathing
Gonzo blogging from the Annie Leibovitz of the software development world.
-
What do you do to get motivated for the day?
I live about an hour south of Calgary in a town called High River. Each day I was driving into the downtown core and parking. It wasn't the expense that was the issue, but the fact I was on the road for about 2 hours a day, every day and my routine felt like I was driving from one place to the next (which I was). I felt unproductive and like I was switching context from one state to another with nothing in between.
Recently I decided that I would stop driving all the way into the downtown core and just drive to our community rail system at the south end of the city (about a 30 minute drive). There I would take the train into the core (about a 45 minute ride) and walk 2 or 3 blocks to the office. This would afford me the opportunity twice a day to wind down (or wind up as it were) as I got into the day. Everyone is always go, go, go these days but my attitude is to relax and enjoy the ride. This supported that.
With my spare time I either crack open a book (currently re-reading Jimmy Nilsson's Applying Domain-Driven Design and Patterns) or get 30 minutes or so on the laptop coding or something. And of course I plug in my iPod and whittle away the time with tunes. I think everyone needs a little downtime, not only between projects but between days. If you're constantly moving from bed -> work -> dinner -> bed, you'll burn out.
I'm not a music afficiando or anything (don't even have a geeked-out home theatre system) but I do enjoy music. My top 5 items on my iPod that I listen to each day is:
- Mike Oldfield. When it comes to music, I live, breathe, and eat Mike Oldfield. Most people have no clue who Mike is, but I'm sure you'll recognize it. It's the music played at the end of The Excorist (aka Tubular Bells). If you heard it, you would probably go "oh yeah". Mike is a musical genius in my books and anything he does is gold (especially when he pairs up with Maggie Reilly on vocals). Easy listening and relaxing.
- Bond. 4 drop dead gorgeous girls playing classical instruments to a boppy beat. What more can you say?
- Enya. The celtic sound does it for me, and her voice is soothing, especially at 6 AM on a crowded train.
- Sarah Brightman. Another muse that lets me ease into the day without frying my brain.
- Loreena McKennitt. More celtic goodness from someone with a heavenly voice and Canadian to boot!
Other stuff I'll listen to:
- Podcasts. It's always good to catch-up on the train with an episode of DNR or Hanselminutes. I never grow tired of listening to those guys.
- Peaches. A NSFW punk-girl band that kicks things up a notch. Another band like this is Evanescence. Good music with a little raunch and kick ass attitute. I'll throw Siouxsie and Banshees in here too.
- Classic rock. Yeah, I'm a 70s rock guy so you'll find things like Queen, Kiss, and Electric Light Orchestra happily playing alongside New Age goodness. This also includes ABBA that I'll admit I listen to. Who doesn't like these guys?
- Old TV themes. They're short and cute and take me back to my younger days and break up the emotional ride you might get from a deep instrumental piece. Fun and peppy.
- Movie soundtracks. Some music just works at any time of the day, like both volumes of Kill Bill. Awesome music and really gets the neurons firing early in the morning.
- Chemical Brothers, Moby and trance music. While I do like easing into the day sometimes it's good to mix in something spicy to kick it up a notch. These guys do it for me.
- Johnathan Coulton. Johnathan who? I only listen to one song from this guy, Code Monkey, as it bridges the music world and my geek life together in 3 minutes. Brilliant!
To kick off the morning I'll either down a coffee or two (or three or four...) but prefer a Red Bull or Rockstar (sugar free). Silly and probably damaging to some part of my internal organs (including losing about 10,000 brain cells each day), but it's that kickstart that I use to get going.
When I get to work I'm ready to face the day. I'll kick into work mode about halfway on my way there, thinking about the morning scrum, what I need to prepare for it, projects I'm working on, and accomplishments I intend to commit to for the team. This gets me into a mindset that lets me slip into business-mode rather than a quick shocking start like I used to have and I find it makes me more productive as a whole.
So what's on your iPod? How do you start your day (or finish it) so you're not burned out and ready to face any challenge you might have?
-
Breathing new life into Tree Surgeon
As I took over the maintenance of Tree Surgeon from Mike Roberts, there are millions (well dozens maybe) of ideas buzzing around in my head. We're tracking these ideas using the Issue Tracker on CodePlex. This will allow you to add new ideas as well as vote on existing ones. The strategy here (as is with all my CodePlex projects) is to have the team (which is building right now) focus the development on the most popular ones.
I've added a few of my own to start (VB.NET support, VS2005 support, ClickOnce) and others have jumped in too (CIFactory structure generation [great idea], and MbUnit support).
Please feel free to keep the discussions and ideas (via comments or work items) flowing as we evolve the Tree Surgeon tool to the next level.
Thanks!
-
Scrum Room = Fun Room!
I like to have fun at work. Whether it's just messing around (by changing developers desktops to pictures of the Simpsons) or just focusing on a task, I think software development should be a fun thing and thus, be conducted in a fun atmosphere. After all, if you're not having fun then what's the point?
A few months ago, we shifted things around and finally got a large enough room to setup our projects in what we call the Scrum Room (I like to call it the center of the universe, but that's a little egocentric as it doubles as my office). Unfortunately our environment isn't what I would prefer it to be (a large team room for all members to be co-located) but this isn't bad. A single "War Room" where we hold the daily scrums each morning for each project. I personally grind code, print out burndowns, and keep the ship steered in some direction (the direction changes all the time) here every day but besides holding daily scrums, the area is generally regarded as the "drop by and let's talk about [insert design pattern here]" room.
First off, we have the daily scrum rules posted on the wall for everyone to see and for us to refer to from time to time as people forget. As I mentioned last week, if anyone strays from the rules during the daily scrum, the Scrum Witch lets out a Wilhelm scream (and we don't want that to happen). This wall also holds the burn down charts (created from Team System) of each iteration. I forgot to snap a picture of the entire burndown wall but you can catch one of them here. I'll post later a more detailed breakdown of the burndowns from one project as we're in the 6th month and there's been a lot of great activity and challenges with that project.
Next is the start of daily scrum. This is a Japanese character a friend of mine got and I had to barter with to obtain (I traded a broken iMate Jas Jar for it). He's an alarm clock of sorts and when you press the button on his chest, music starts up and he tells you to wake up (in Japanese of course). Press the "snooze" button again and he tells you "thank you for waking up" (or something like that, my Japanese is non-existent) and the music stops. We would get into the habit of starting this guy up just to get everyone pumped for the day, although I haven't activated him for awhile now.
Now we come to "The Wall". This is a large (about 20ft wide) wall in my office that houses 3 projects and their tasks. Each project has a 8-10ft section of the wall and we print out the splash screen for each project to identify it (of course the splash screen is the first thing done for the project, screw the requirements, we need a cool logo!).
Under each project contains 3 sections with tasks. One for "Not Started", one for "In Progress", and one for "Done". The "In Progress" section is broken down with a small post-it showing 0% - 100% which is the completeness of the task. Under the "Not Started" section we break down tasks in an organized fashion so it's easier to find them when you're grabbing a task during your 5 minutes of fame at the morning scrum. Each team groups the tasks differently. One team has it defined by role (BA, QA, Dev, etc.), another has it defined by a feature, still another uses a line of business to collect tasks. Whatever works for each team is fine.
It's the usual routine for task boards (in our case the entire wall is the board). Tasks move from the "Not Started" area to 0% in the "In Progress" area. As team members work on tasks, they move across the wall to 100% then drop into the "Done" area. It really does give a quick overview of where things are at. It's the easiest way to describe and display progress and the entire state of the iteration for anyone looking at it. This is how much we have to do, this is how much we've done. Highly effective and easy to understand.
The banner at the top of the wall is labeled "The New Goodness" and was a phrase someone has mentioned awhile back (more than likely it was over a few shooters at the bar, but that's okay too). We liked it as it represented the new approach to software delivery (agile vs. waterfall) and seemed to reflect the atmosphere we wanted to take. Something new and something good. Sure the grammar is off but again, we're focused on fun here not English. The development manager also printed out a picture of a traditional rugby scrum so we felt it was appropriate for the wall (and some mornings it feels like this).
There's a section over my desk where we've got some fun and motivational type stuff. A printout of a cartoon that Hugh MacLeod created (I'm not cool enough like Scoble to have a hand signed lithograph) that is a bit of a motto when you're in my office. We have the Scrum cartoon about the chicken and pig wanting to open a restaurant, courtesy of Implementing Scrum. Finally, there's the fish. This will take a little explaining.
This fish is the award the team member gets for breaking the build. Originally we were thinking about bringing in a real (ala taxidermy) fish. The dev manager has 3 of these so we would pass out the fish and the team member who broke the build gets to display the fish on his desk all day. This wasn't quite practical (and we felt we would run out of fish and then what! Goats? Sheep? Cats?) so he hunted down a goofy picture of a kid holding a fish. If you break the build, he emails the fish to you and prints out a copy for you to pin up in your cube.
Today we discovered some people were actually collecting their fish so maybe we'll have a contest at the end of the project as to who gathered the most fish. The idea is to spice up your team with ideas and promote fun within the team even when they do something bad like breaking the build.
Well, that's the whirlwind tour of our Scrum Room. It doesn't have to be a stuffy board room or a boring task board, and if you're going to live in it every day (like I do) make it enjoyable!
The message here is to have fun with your projects. Don't get so stressed out. So what, you lost a resource or two. So what, the requirements changed a day before you were supposed to deliver that feature.
Breathe, relax, pick up, and carry on. It's just software.
-
Tree Surgeon has a new home... on CodePlex!
About a week or so ago Mike Roberts posted a note that he was no longer going to be working in the .NET world as the Java world was taking over at his company. Mike is the author of many blog posts on setting up a development tree in .NET and these blog posts spawned a tool called Tree Surgeon. As Mike was no longer going to be working in the .NET space, he threw out the gauntlet for someone to pickup the maintenance for the tool.
I picked it up as I think it's a great tool and can only improve with time. You can find the new home for Tree Surgeon here on CodePlex.
I've setup all the documentation the same as the original site along with putting out version 1.1.1 (the last release). You can grab it various flavours:
- TreeSurgeon-1.1.1-Setup.exe. Just click and install.
- TreeSurgeon-1.1.1.zip. Unzip and run.
- TreeSurgeon-1.1.1-Source.zip. Zip file of the source tree.
Source code is checked into CodePlex so you can grab the latest changesets from here.
There's plenty of ideas for Tree Surgeon in the coming year, so I encourage you to visit the Discussion Forums and talk about what you're interested in seeing and keeping track of (and voting on) new features and bugs via the Issue Tracker.
I've also changed the license for Tree Surgeon so it's now released under the Creative Commons Attribution-Share Alike 3.0 License (I'm not only a CodePlex junkie, I'm a CC one too).
-
Beware the Scrum Witch!
I'm always happy when I see the Internet spread goodness, or at least what I perceive to be goodness. Last week or so I talked about the Scrum Witch, a horrific little screamer that we introduced to our daily scrums as things were getting out of hand. If a team member strays from our standard routine, we unleash the Scrum Witch on them, screaming and howling for everyone in the office to hear.
The witch has been pretty successful as we're sticking closer to the routine and there's less gossip-talk during the scrum. Scrums end in under 10 minutes now (where they previously would linger for 15, 20 and even 30 minutes) and everyone is focused. I've only had to activate the Witch twice, and both times were with the same PM who charged off asking all kinds of questions (not even related to the current sprint!).
Mike Vizdos over at Implementing Scrum has a cartoon this week called Work Naked on dysfunctional things he sees at the daily scrum and yes, the Scrum Witch made an appearance (although it would have been awesome if she made it into the cartoon, ahh someday...)
The message here is simple. The daily scrum is your commitment to the team, not a report to the PM or Scrum Master on what you did. Be kind and respectful and the pain will last only a few minutes.
Watch later this week for more scrum fun as I have a few posts on the go right now.
-
Another year, another MVP renewal
I was a little nervous the last few days as everyone and his brother (Sahil, Frans, etc.) had all recieved their MVP renewal notices. I got mine this morning but apparently it was sent out yesterday, my pathetic mail client seems to have toasted it. Anyways, MOSS MVP for another year. This is my 4th year and so look for more SharePoint goodness the remainder of this year. Lots to come from this tired brain of mine. Congrats to all the new and renewing MVPs this round too. See you at the next summit!
-
Comparing expectations with Constraints using Rhino Mocks
I've been more work with Rhino lately (and really digging it) and wanted to pass on a tidbit that might be useful to some of you.
Here's the setup. You're implementing the MVP pattern and your view will contain a list of items (probably displayed in a grid, listbox, etc.). You start with a test where your presenter will initialize the view with a list of items from a backend system. You want your test to verify that the view gets updated (via the presenter) with the correct list.
Let's setup our test using mocks. We'll mock out the view since the implementation isn't important to us right now. We only want to ensure that when the presenter is initialized (via a called to OnViewReady) it will
- Call a backend system to get a list of items
- Set the view with those list of items
- We can ensure the view contains those items.
Here's the test for that with excessive comments so it should be self explanatory:
24 [Test]
25 public void OnViewReady_ViewShouldContainItemsFromRepository()
26 {
27 // Create the mock objects
28 MockRepository mocks = new MockRepository();
29 IProjectListView listView = mocks.CreateMock<IProjectListView>();
30
31 // Creat a real presenter and assign the mock view to it
32 ProjectListViewPresenter listViewPresenter = new ProjectListViewPresenter();
33 listViewPresenter.View = listView;
34
35 // Setup our expectations for the view by getting
36 // a list of projects from a repository (created via a factory)
37 RepositoryFactory factory = new RepositoryFactory();
38 ProjectRepository repository = (ProjectRepository)factory.GetRepository<Project>();
39 List<Project> fakeProjectList;
40 fakeProjectList = repository.GetAll();
41 listView.Projects = fakeProjectList;
42 LastCall.IgnoreArguments();
43 Expect.Call(listView.Projects).Return(fakeProjectList);
44
45 // Invoke the mock engine
46 mocks.ReplayAll();
47
48 // Call the real presenter that we want to test
49 // This will call the repository to retrieve a list of
50 // projects and update the view to include them
51 listViewPresenter.OnViewReady();
52
53 // Check the view to ensure it's been updated
54 // with the list of projects from the repository
55 Assert.AreEqual(3, listView.Projects.Count);
56
57 // Teardown the mocks
58 mocks.VerifyAll();
59 }
Other than the setup code (creating the mocks, presenter, etc.) which could all be done once in a Setup method there's a few problems with checking the list of projects from the view. While we did mock out the view, we're checking the count only. If we want to ensure that the list contains the projects we expect we might have to iterate through the list and compare the Project objects that are returned and that's a lot of work.
There's an easier way to check lists with Rhino which measures up to the same amount of code but is much more effective at testing the contents of the list. We can use constraints on the expected call. Constraints is a list of constraint objects attached to your mock that tell you there are expectations that should match up to the constraint you define.
Instead of assigning our fake project list to our view then setting the expectation via an Expect.Call method, we'll add a constraint to the mock. We don't need to assign the listView.Projects value so we can set it to null and the next line, LastCall.Constraints(...) will be our contraints we want to attach to that mock item:
30 listView.Projects = null;
31 LastCall.Constraints(new AbstractConstraint[] { List.Equal(fakeProjectList) });
We still have to create the expectation, but now we use List.Equal(...) and pass in the fakeProjectList. This means when the mock runs it will ensure that the listView.Projects property not only contains the same number of items (like our original test) but the list is actually of the same type and is the same list (I think Rhino internally uses the Equals method on each item to compare them). So now our test looks like this:
14 [Test]
15 public void OnViewReadyM_ViewShouldContainItemsFromRepository()
16 {
17 // Create the mock objects
18 MockRepository mocks = new MockRepository();
19 IProjectListView listView = mocks.CreateMock<IProjectListView>();
20
21 // Creat a real presenter and assign the mock view to it
22 ProjectListViewPresenter listViewPresenter = new ProjectListViewPresenter();
23 listViewPresenter.View = listView;
24
25 // Set the expectations of the mock via a constraint
26 RepositoryFactory factory = new RepositoryFactory();
27 ProjectRepository repository = (ProjectRepository)factory.GetRepository<Project>();
28 List<Project> fakeProjectList;
29 fakeProjectList = repository.GetAll();
30 listView.Projects = null;
31 LastCall.Constraints(new AbstractConstraint[] { List.Equal(fakeProjectList) });
32
33 // Invoke the mock engine
34 mocks.ReplayAll();
35
36 // Call the real presenter that we want to test
37 // This will call the repository to retrieve a list of
38 // projects and update the view to include them
39 listViewPresenter.OnViewReady();
40
41 // Teardown the mocks
42 mocks.VerifyAll();
43 }
Note that we also don't have to do the Assert.AreEqual check at the end. Our call to VerifyAll will handle that when the mock is torn down.
Like I said, the amount of code isn't that much different, you're just using a different call on setting up the mock. However you can add as many constraints as you like. For example you can ensure the list is of the right type, it contains that many items, and you can even tell it the first item has to have some pre-determined value. Constraints are stacked up and evaluated when you tear the mock down so make sure you put in the VerifyAll call.
This is just an example of changing the way you might check a list of items using constraints but you can use constraints for any type. For example if you had a single property on a mocked object you can add a constraint that it was greater than or equal to a certain value, or that it met a certain type if you were say testing a sub-class. Check out the "Is" class to do things like Is.GreaterThan, Is.LessThanOrEqual, Is.Type, etc.
Lots of possibilities here so dig in and play with constraints on your mocks. You might find something interesting and learn something new along the way!
-
Fool me once, fool me twice, April Fools Day has come and gone (again)
No, this blog is not being sued. As some observant readers figured out yesterday, the cease and decist letter to shutdown my blog was a hoax. Astute readers pointed out the Milton, Chadwick, and Waters was the law firm from the movie The Devils Advocate and that John Milton was the character played by Al Pacino. It was the first movie with lawyers that popped into my head and seemed appropriate, although the law firm from John Grisham's novel "The Firm" would have sufficed.
What most people didn't pick up on was that the hoax was actually setup by me. I was not the person on the recieving end of a prank as some people thought, you were. There was some news item on Saturday about someone having to change the name of their product and the idea for my blog popped into my head. I did a quick search to find an example letter and just filled in the blanks.
For those of you that are expecting the blog to shut down by April 15, sad to say I'm still here and will be for some time. For those that started the "Save the Bil" fund, I thank you but please send you money to people who club seals for a living or some other deserving group. I don't need it.
I don't know if I'm very, very, good at doing these April Fool blog posts or really, really, bad at them. Last years post of open sourcing Windows SharePoint Services got some people riled up (including unnamed sources deep inside the hallowed halls of Microsoft itself).
We'll have to hang around til next year to see what my augmented mind can dream up.
-
CSS Reference Chart for SharePoint 2007 - PDF Version
Heather Solomon, the MVP queen of SharePoint style, has put together a fabulous CSS reference for SharePoint 2007. This covers both Microsoft Office SharePoint Server (MOSS) and Windows SharePoint Services (WSS) and displays the name of the style along with an example and where the style is defined in what file. Brilliant.
I've put together a PDF version of the reference guide if you're into that. You can download the 12 page reference guide from here. Heather's original online version can be found here.
-
Cease and desist - Have to find a new name for my blog
It seems I am no longer able to keep this blog name. I received this email today:
From Milton, John S. Apr 1 08:29:30 2007
Subject: Cease and Desist Letter for your site "Fear and Loathing"
From: "Milton, John S." xxxxx@xxxxxxx.com
Dear Mr Simser:
I am the senior partner with the law firm of Milton, Chadwick, and Waters based out of New York City, NY and represent the estate of Hunter S. Thompson. It has come to my attention that you have made an unauthorized use of my clients copyrighted work entitled "Fear and Loathing" (the "Work") as the name for your website. The estate reserves all rights in the Work, first published in 1970. Your work entitled "Fear and Loathing" is essentially identical to the Work and clearly used the Work as its basis.
As you neither asked for nor received permission to use the Work as the basis for your website nor to make or distribute copies, including electronic copies, of same, I believe you have willfully infringed my rights under 17 U.S.C. Section 101 et seq. and could be liable for statutory damages as high as $150,000 as set forth in Section 504(c)(2) therein.
I demand that you immediately cease the use and distribution of all infringing works derived from the Work, and all copies, including electronic copies, of same, that you deliver to me, if applicable, all unused, undistributed copies of same, or destroy such copies immediately and that you desist from this or any other infringement of my rights in the future. If I have not received an affirmative response from you by April 15, 2007 indicating that you have fully complied with these requirements, I shall take further action against you.
Very truly yours,
Milton, Chadwick, and Waters
Attorneys at Law
While I don't consider myself an "A" class blogger, I guess too many people who were looking for content from the late Mr. Thompson keep arriving at my site and scratch their heads about this whole SharePoint thing.
So I need to find a new name for my blog. I turn to you, happy reader on this fine day for your help. What should I rename my blog to be? Looking for any suggestions here no matter how wild so feel free to leave them in the comments section below. If I don't come up with a good name by April 15th I'll shut this blog down.
Thanks.