Home

Archived Posts from “Mgmt”

Upgrading Microsoft Certifications

11

August

I am a Microsoft Certified Solution Developer (MCSD.) Seeing as some of the folks at work are looking to get their certifications, I spent some time today reviewing possible tracks to upgrade my credential to Microsoft Certified Technology Specialist (MCTS) or Microsoft Certified Professional Developer (MCPD.)  I was happy to discover that I am eligible to upgrade my MCSD credential with the option of one or two exams.

If you (like me) are an MCSD, you can earn certifications in MCTS: .NET Framework 2.0 Web Applications, MCTS: .NET Framework 2.0 Windows Applications, MCTS: .NET Framework 2.0 Distributed Applications, and MCPD: Enterprise Applications Developer on Visual Studio 2005 by passing Exam 70–554 and Exam 70–553

Alternatively, you can receive your MCPD: Enterprise Applications Developer by passing a single exam, Exam 70–554, but you will need to earn your MCPD: Web Developer and MCPD: Windows Developer certifications first. This option is certainly the faster track if you have already satisfied the two prerequisite certifications (which I have not.) 

MCPD: Database Administrator

You will note the exams called out above are geared around Visual Studio 2005 and the .NET Framework 2.0.  There are also equivalent MCTS and MCPD certifications for Visual Studio 2008 and the .NET Framework 3.5.  I’ve been inside of VS 2008 and .NET Framework 3.5 for some time now so I may just test my skills against the latest and greatest.  It seemed to make sense but you never know.

It’s been over 4 years since I last tested.  If anyone has advice or feedback, I would love to hear it — even if it’s merely "good luck."  


VS2008 Test Project Tips

04

August

As I mentioned last week, I am new to TDD.  For better or worse, all of my tests (and spikes) have been generated via Visual Studio Test Projects.  Working with VS Test Projects hasn’t been all that bad although I noticed a couple of annoyances right away. 

Is anyone else bothered by the fact that, by default, an unlimited number of test results and binaries are "deployed?"  If you are testing first, this arguably makes for a lot of useless activity and waste disk space.  Since the default TestResults folder location is set to be side-by-side with your solution files, the extra folders, trx files and binaries can also really interfere with your otherwise easy source control check-ins. 

Fortunately, there are ways to work around the excessive TestResults problem if you are running VS2008.  Some options are available through the IDE and other require an update to the .testrunconfig file directly:

Limit the number of deployed tests:

Tools > Options > Test Tools > Test Execution > Test Results Management > Limit number of old Test Results to the value of your choosing. 

The screen shot below sets the number of tests to one.  Therefore all previous tests are purged and only the latest test is maintained.

image

Disable Test Result deployment:

If you wish to disable the Test Result generation completely, double-click on your solution’s .testrunconfig file and uncheck the "Enable deployment" option.  No results will be generated thereafter.

image 

Change the Test Result folder location:

This option is hidden.  I don’t believe it is exposed in any of the VS 2008 dialogues and you have to edit the .testrunconfig file directly. 

Right-click on the .testrunconfig file > Open With… > XML Editor > Include the following within the TestRunConfiguration node:

<Deployment useDefaultDeploymentRoot="false" userDeploymentRoot="C:\TestResults" />

I hope it helps.

kick it on DotNetKicks.com

References:


Learning Test Driven Development

01

August

I am relatively new to the Test Driven Development (TDD) scene.  Though I have read up on the subject (specifically Test Driven: TDD and Acceptance TDD for Java Developers by Lasse Koskela), my only hands-on experience is limited to a single, 3-month project where I was the lone developer.  All other information gathered on the subject has been through blog entries, podcasts, ramblings and the occasional deCover Imagemo in the office.  Though I believe I have a good understanding of TDD methodologies, I am far from putting this, dare I say, knowledge to practice.  Good practice, that is…

A spike is a term associated with TDD.  A spike is nothing more than quick coding exercise which validates or invalidates an assumption.  Lasse Koskela says it more eloquently:

A spike is a short experiment with the purpose of familiarizing ourselves with the technology, tools, algorithms, and so forth, that we need for solving the problem at hand.  A spike is  a way to make an unknown known — at least to a point where we know whether it’s worth continuing to dig that way or whether we should start looking for another way.

If you are familiar with TDD concepts, you know that spikes offer no value with it comes to testability, maintainability, etc.  They are merely quick prototypes which I find immensely helpful but should not be considered the focal point of TDD.  Well, my first crack at TDD resulted in roughly 70% spikes and 30% actual tests.  Not too good.

There is no doubt in my mind that I always had the best intension to test-code-refactor, but I wasn’t yet familiar enough with TDD to know I was way off course. There was also no one around to put me on the right track (or keep me honest.) Putting my ego aside, I know I could have used some hand-holding when I was starting off with TDD.

Test Driven Development is a discipline.  Like many other disciplines, TDD requires a teacher, student and practice.  The teacher offers instruction and ensures the discipline is practiced correctly.  The good student gathers knowledge and implements under watchful guidance.  In my opinion, TDD is therefore a seemingly good fit for a team which embraces an Agile approach, collaboration, rapid development and testability.   I’m not saying the lone developer with no prior experience with TDD is not capable of learning TDD on their own. I know some are.  I know guys who have done it.  Simply, I am stating that TDD seems most accessible to the mentored developer working with team members who previously adopted the methodology.  To put it another way, I bet Test Driven Development concepts are best learned through practical, hands-on example.

I haven’t given up on TDD yet.  Who wants to hold my hand?

kick it on DotNetKicks.com


Introducing Lightning Talks

29

July

The folks I work with are wicked smart.  Go back and read that first sentence again.  This time read it like you are Ben Affleck in Good Will Hunting or one of the guys I used to play summer ball with outside of Boston. Fun right?  Anyway, the point is I work with really smart people and I like to push random characters voices into the heads of my readers. 

Tip Number 1: If you have the means, I suggest you plant yourself in a similar environment.  There’s nothing you can do to better for your career than surround yourself with talented, smart people who are passionate about their work.  It doesn’t matter if you are a junior coder, manager-type or CTO.  It’s just good sense.

The problem with my current environment is we are scattered amongst many projects, across many clients and the opportunity to collaborate doesn’t knock very often. We do have a weekly team meeting, but it generally focuses on business/management stuff.  I do find that software development talk often surfaces at lunch but arousing conversation around grass fed vs grain fed cattle is equally as likely.  There really was no venue to really talk shop and harness the collective software development knowledge of my coworkers. 

So, I suggested we start hosting Lightning Talks… The immediate response was very favorable (everybody likes to hear themselves talk, right?) and this week we held a very quick business/management team meeting and then the development staff started our first round of *modified* Lightning Talks.  I emphasis the word "modified" because we broke a rules.  Read on.  We kept things very informal and, in the spirit of lightning talks, intended to host a number of very quick quick 3-10 minute presentations.  Unfortunately, we kind of blew it with the time allotment as my two talks, one on AnkhSVN and the other on Inno Setup, took 5 minutes and then 45 minutes respectively.  All the same, everyone seemed genuinely interested in presentations and the pseudo-lightning talk concept (although you never know because I work not only with really smart people they are also very kind.)  Perhaps the best evidence of the Lightning Talk success was at least one coworker volunteered to do a presentation next week and our internal Wiki already has a section dedicated to presentation notes. 

Tip Number 2: Introduce a similar practice to your workplace.  No matter what you call the meeting, getting coworkers talking about technology is one of the best ways to get introduced to new ideas and sharpen your existing skills. 

Wish us luck on future talks.  Let’s hope my brain doesn’t get too big.

kick it on DotNetKicks.com


Good Estimates Despite Bad Process

13

February

Are you involved in your company’s project estimation process? If so, let’s pretend. Let’s pretend that your company has internal constraints which makes estimating rather difficult. For example, let’s say you were required to completed all of your 2008 estimates towards the end of 2007 despite the fact that very few requirements were known. Don’t get me wrong. There were a few requirements but they were very high-level or what I would equate to a vision document or merely a great idea someone thought up while taking their morning shower. Of course, no one should expect these estimates to be all that accurate, but just for fun, let’s pretend that some felt they would be good enough to use as a basis to determine the entire budget for 2008. Kind of scary, eh? Well, I’m familiar with such a process and it is really scary and frustrating and, in my opinion, a tough way to end and start a year. You do learn to deal and make the best of it though.

It goes without saying but estimation is an art. It is hard enough if you have all relevant information at your fingertips. The thing is we rarely do have everything we need. Now, I recognize the provide example is a little to the extreme, but it happens. Believe me, it happens. Again, you do learn to deal and make the best of it though. But what if one wanted to improve on the process summarized above? What could be done?

I think the first step is determine the key factors in providing a good estimate which I believe included the following:

  • You Need Good Requirements: Good requirements have the greatest impact on an estimate. As requirements become more complete and detailed, estimates become more accurate and our confidence increases. Period.
  • You Need An Appropriate Estimator: Estimators should be chosen based on their understanding of the requirements, their knowledge of technology and possible solutions and their past estimating experience. The decision of whom should estimate one’s projects should not be taken lightly.
  • You Need To Know The Implementer: To provide a good estimate, it isn’t really necessary to know who will be performing the work, but since no two developers have the same skill set or experience, knowledge of the implementer can help firm up an estimate considerably. If nothing else, you need to know the candidate’s assumed skill set and domain knowledge.

It should be noted that we often think that timeline and/or budget have an affect on our estimates. This is only true because these factors affect scope, which in turn affect requirements, which are ultimately reflected in the estimate.

Once the key factors are identified (maybe there’s more than listed above), a better process needs to be defined. Assuming the company absolutely has to continue estimating and budgeting for the upcoming year prior to having solid requirements, I would suggest breaking the estimation process into three stages in order to continually firm up one’s numbers as additional information is provided:

  • SWAG: This high-level estimate is based on the limited requirements offered in the project request. Since this estimate is typically provided by management, and is based on few requirements, it should come along with a fairly low confidence level. Unfortunately, the allocated budget is tied to these estimates. Since none of individual estimates will be accurate, the best case scenario is to end up with estimates balancing themselves out. In other words, for every over-estimated effort there will an under-estimated effort. If the majority of efforts are under-estimate, you are screwed. If the majority are over-estimated, you are bound to have some awesome launch parties.
  • Detailed Estimate: This estimate can be produced once detailed requirements are offered. This requirements would come in the form of a BRD or FSD. Who produces this estimate? People with knowledge of the product and the technologies who will hopefully be involved with the project until it is released. This estimate becomes the foundation of the project plan and is the basis of all staffing requests.
  • Developer Validation: Once development assignments are distributed, each developer will validate the provided estimate against his/her associated tasks. Adjustments to the project plan and staff plan will be made if necessary.

In theory, one should expect estimates to change as scope or staff fluctuates — if we follow the steps above.

In no way is this high-level plan a silver bullet. It isn’t necessarily realistic for all shops as I, for one, can’t remember the last time I was asked to estimate a project AFTER I received firmed up requirements and I can’t think of a single case where scope didn’t change between a project’s inception and its end. I guess that’s why estimation is an art. You must leverage whatever process you currently have in place, search hard for few facts and then provide your best guestimate all the while knowing that things may very well change tomorrow. I do believe if one respects the key factors and overall process above, there’s a better chance of success than if these core ideas are disregarded.

Best of luck with your next estimate. By the way, what did I miss?


Getting Started with CruiseControl.NET

29

January

I consider myself a neophyte when it comes to continuous integration (CI), but having read up on the topic, “played around” a bit, reviewed a couple of products, and having now incorporated it into our standard development practices, I am starting to hold my own.  If nothing else, the benefits of continuous integration are now obvious and, well, I can’t imagine ever turning back. 

For me, the power of continuous integration extends far beyond build validation.  CI it has become a welcome management tool which allows me to keep my finger on the pulse of numerous developed products as well as individual developer contributions.  Though I am very interested in the overall success/fail state of the current build, equally valuable is the the notifications which email specified team members the code change log which accompanies each build. (i.e. A list modified files and associated comments since the last automated build.)  If you are responsible for overall project success (which typically includes management of deliverable, code quality, task distribution, etc) then continuous integration is for you.

As I mentioned earlier, I reviewed a few products.  Last year, I reviewed FinalBuilder which provided me a nice and easy introduction into this space.  Based almost completely on its popularly and price tag (free), I have since turned to CruiseControl.NET.  I will not claim that was able to quickly get up and running with CruiseControl.NET.  At times, I was down-right questioning if I was smart enough to figure out the product and its configuration.  But, alas, it is now running on a dedicated build machine and my team and I are all the better for it. 

Please let it be known that I am not a wizard when it comes to CruiseControl.NET.  I am, however, good at is documentation of repeatable actions and I tried to capture the steps on getting started with CruiseControl.NET below.  As always, any feedback is greatly appreciated.

By the way, if you are looking for general information on continuous integration or CruiseControl.NET, you are not going to find here.  For more information, you may wish to consult the following:  What is Continuous Integration and What is CruiseControl.NET.

That’s basically it.  Best of luck!

 

1. Find a Build Machine

Though CruiseControl.NET could be installed on a development machine, I recommended that it be installed on a dedicated build server. Your build server should have access your source control repository and an optimal STMP server.  The server should have IIS and the NET Framework installed as well.  More information on the build server to follow…

 

2. Install CruiseControl.NET

Download CruiseControl.NET Server and Dashboard and install using provided default selections. 

http://downloads.sourceforge.net/ccnet/CruiseControl.NET-1.3-setup.exe?modtime=1182463056&big_mirror=0

 

3. Install MSBuild

If you are working with .NET 2.0+ applications, you can build using MSBuild. Otherwise, you may need to learn a bit about NANT.  All of the provided sample configurations below assume you will be using MSBuild. 

The MSBuild DLL is not included in initial CCNET Server installation, but it can be downloaded from the ThoughtWorks site: http://ccnetlive.thoughtworks.com/MSBuildXmlLogger%2DBuilds/. To install, simply copy the ThoughtWorks.CruiseControl.MSBuild.dll into C:\Program Files\CruiseControl.NET\server\ location.

 

4. Install Source Control Client

You will potentially need to install your source control client on the build machine. For the samples provides, we are using Borland StarTeam 2005.  CruiseControl.NET integrates with just about every source control system I could think of, so if you are using something other than StarTeam, you will want to consult the Source Control Block documentation.

 

5. CruiseControl.NET Server Configuration

CruiseControl.NET Server is driven by CCNET configuration file settings. After the fresh install, the configuration is essentially empty and requires manual updates to the ccnet.config file itself. As far as my knowledge, there is no associated configuration editor.  First things first, crack open “C:\Program Files\CruiseControl.NET\server\ccnet.config” in Visual Studios or your favorite XML editor. (There is shortcut under All Programs > CruiseControl.NET > CruiseControl.NET Config.)

If you have a pre-configured ccnet.config file available, simply overwrite the file content. If you are starting from scratch, you may wish reference the online CruiseControl.NET configuration overview and review samples: http://confluence.public.thoughtworks.org/display/CCNET/Configuring+the+Server.  Additional example configuration files were installed on your build box as well: C:\Program Files\CruiseControl.NET\Examples.  They are worth a look.

The bad news: Though you will find examples sprinkled throughout the ThoughtWorks site and the locations noted above, you will most likely need to muck around with your own config file for a while until you get it right.  Additional samples are provide below, but just as I wasn’t able to find the magic configuration combination to get my server running right off the bat, I bet you won’t either. 

The good news: Getting the right configuration was trail-and-error process for me.  I kept the configuration very simple at first and then built upon it.  Hopefully the next steps can help you with your troubleshooting.

 

6. Start CruiseControl.NET Server

The CCNET Server is not started at the time of installation. Thus, you will need to start the service manually: Administrative Tools > Services > CruiseControl.NET Server > Select > Start the service.

If the service fails at startup, it will immediately stop and present the following generic dialogue:

The CruiseControl.NET Server service on Local Computer started and then stopped. Some services stop automatically if they have no work to do, for example, the Performance Logs and Alert service.

If you encounter this error your first stop is to consult the logs: C:\Program Files\CruiseControl.NET\server\ccnet.log. By default, the file contains verbose logging which is helpful (although somewhat difficult to navigate.)  Believe me, the logs are your fried.

Based on the log file feedback, I suggest tweaking the ccnet.config file and then restarting the service – repeating until the service is fully configured.  And, if it is easier for you, you may run the CCNET Server via the command window: CD C:\Program Files\CruiseControl.NET\server > ccnet.exe.  This approach will render errors in the cmd window rather than having to monitor the ccnet.log file.  It was a time saver for me at least.

Once the project is successfully setup, you will see something similar to the following listed in the logs:

· [CCNet Server:DEBUG] The trace level is currently set to debug. This will cause CCNet to log at the most verbose level, which is useful for setting up or debugging the server. Once your server is running smoothly, we recommend changing this setting in C:\Program Files\CruiseControl.NET\server\ccnet.exe.config to a lower level.

· [CCNet Server:INFO] Reading configuration file “C:\Program Files\CruiseControl.NET\server\ccnet.config”

· [CCNet Server:INFO] Registered channel: tcp

· [CCNet Server:INFO] CruiseManager: Listening on url:tcp://localhost:21234/CruiseManager.rem

· [CCNet Server:INFO] Starting CruiseControl.NET Server

· [PROJECTNAME:INFO] Starting integrator for project: PROJECTNAME

At this point, the Server is waiting to initiate the next build. Based on the config file <triggers> setting it could take a while to get the checkout and build to fire. Adjust the following setting to around 10 seconds while still in the testing phase:

<triggers>
  <intervalTrigger name=continuous seconds=10                   buildCondition=IfModificationExists/>
</triggers>

On a similar note, the Server restarts itself automatically each time the ccnet.config file is modified.

 

7. Potential Gotchas

I ran into a couple specific cases while debugging which I suspect could be common issues. 

1. Ensure the MSBuild timeout value allows enough time to the build to complete. This will otherwise return in a failure which wasn’t easy to troubleshoot.

<msbuild>
  <timeout>600</timeout>
</msbuild>

2. For web solutions, update the TargetPath for the Debug and/or Release build of the application to be outside of the source application directory. Otherwise, you will receive the following error:

ASPNETCOMPILER : error ASPRUNTIME: The precompilation target directory cannot be in the same tree as the source application directory.

This can be done by modifying the following in the solution file:

Debug.AspNetCompiler.TargetPath = “c:\ccnet\PrecompiledWeb\SampleWeb\”
Release.AspNetCompiler.TargetPath = “c:\ccnet\PrecompiledWeb\SampleWeb\”

Alternative, one may update the Output location found in the application MSBuild properties.

You may be wondering why an updated solution won’t be updated with the next scheduled build.  As it works out (and makes sense) only changes which are applied to source control are pulled onto the build box. 

 

8. Automating Your Builds

Once the build process is running successfully, modify the <intervalTrigger> setting to a reasonable value and then update the “CruiseControl.NET Server” Service Startup Type to Automatic and then Start the service.  I might suggest also crossing your fingers for the next day or so.

 

9. Monitoring Your Builds

The CCNet Web Dashboard Application is used for reporting a wide range of information. At one end of the scale it reports summary details of all projects being managed by CruiseControl.NET and at the other it can give specific metric output for any specific build.  The Dashboard is setup with your initial installation.  You may access the Dashboard application by navigating a location similar to the following: http://buildbox.com/ccnet/ViewFarmReport.aspx.  For more information on the Web Dashboard: http://confluence.public.thoughtworks.org/display/CCNET/Web+Dashboard

The CCTray an optional utility for use with the CruiseControl.NET Continuous Integration server. It provides feedback upon build progress, and allows control over some of the server’s operations.  As “optional utility” implies, the CCTray isn’t included with the base installation.  You may download the Windows Tray Application from the following location and install using provided default selection: http://downloads.sourceforge.net/ccnet/CruiseControl.NET-CCTray-1.3-Setup.exe?modtime=1182463076&big_mirror=0. There isn’t much to using the CCTray but I do consider it a handy add-on.  Basically, you will find a shortcut to the CCTray on your desktop. Launch the application to begin monitoring the automated build(s) status and schedule.  The information provides via the CCTray is very similar to that which is provided in the Dashboard application.  For more information on CCTray: http://confluence.public.thoughtworks.org/display/CCNET/CCTray.

 

Sample Configuration Files

If you have made it this far, I really, really hope your required configuration is similar to mine.  If so, this is your golden ticket.  I have provided two flavors of configuration files below. You will undoubted need to tweak the files a bit (replace the project locations and names along with credentials will obviously be required), but hopefully these will help get you started.  By the way, the formatting of the XML leaves something to be desires as I have formatted to fit within the given real estate.

 

Windows Service, StarTeam, MSBuild, Emailing and Unit Tests

<cruisecontrol>
  <project name=SampleService queue=Q1 queuePriority=0>
    <workingDirectory>c:\Projects\Services\SampleService
      </workingDirectory>
    <artifactDirectory>c:\ccnet\artifacts\Services\SampleService
      </artifactDirectory>
    <category>Continuous Builds</category>
    <webURL>http://buildbox.com/ccnet/server/local/project/
      SampleService/ViewProjectReport.aspx</webURL>
    <triggers>
      <intervalTrigger name=continuous seconds=600
                       buildCondition=IfModificationExists/>
    </triggers>
    <state type=state directory=c:\ccnet\state/>
    <labeller type=defaultlabeller>
      <prefix>Build-1.0.</prefix>
      <incrementOnFailure>false</incrementOnFailure>
    </labeller>
    <sourcecontrol type=starteam>
      <executable>c:\Program Files\Borland\StarTeam 2005\
        stcmd.exe</executable>
      <project>Project</project>
      <username>user</username>
      <password>password</password>
      <host>10.1.10.100</host>
      <port>11111</port>
      <path>Projects/Services/SampleService</path>
      <autoGetSource>true</autoGetSource>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe
        </executable>
        <workingDirectory>C:\Projects\Services\SampleService
          </workingDirectory>
        <projectFile>SampleService.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:m
          </buildArgs>
        <targets>Clean;Build</targets>
        <timeout>600</timeout>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XMLLogger,
          C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\Projects\Services\SampleService
          </workingDirectory>
        <projectFile>UnitTestBuild.proj</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag
          </buildArgs>
        <targets>Tests</targets>
        <timeout>1500</timeout>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XMLLogger,
          C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
    </tasks>
    <publishers>
      <merge>
        <files>
          <file>c:\ccnet\artifacts\Services\SampleService\
            mbUnit-testResults.xml</file>
          <file>c:\ccnet\artifacts\Services\SampleService\
            msbuild-results.xml</file>
        </files>
      </merge>
      <xmllogger/>
      <email from=no-reply@buildbox.com
              mailhost=localhost includeDetails=TRUE>
        <users>
          <user name=User 1 group=BuildMaster
                  address=user.one@buildbox.com/>
          <user name=user 2 group=TechLead
                  address=user.two@buildbox.com/>
        </users>
        <groups>
          <group name=BuildMaster notification=always/>
          <group name=TechLead notification=change/>
        </groups>
      </email>
    </publishers>
  </project>
</cruisecontrol>

Web Application, StarTeam, MSBuild, Emailing, and Build Dependencies

<cruisecontrol>
  <project name=SampleWeb queue=Q2
           queuePriority=1>
    <workingDirectory>c:\Projects\Web\SampleWeb
      </workingDirectory>
    <artifactDirectory>c:\ccnet\artifacts\Web\SampleWeb
      </artifactDirectory>
    <category>Continuous Builds</category>
    <webURL>http://buildbox.com/ccnet/server/local/project/
      SampleWeb/ViewProjectReport.aspx</webURL>
    <modificationDelaySeconds>15</modificationDelaySeconds>
    <triggers>
      <intervalTrigger name=continuous seconds=3600
                       buildCondition=IfModificationExists/>
      <projectTrigger project=SampleData>
        <!– Force build when data component is successfully built. –>
        <triggerStatus>Success</triggerStatus>
        <innerTrigger type=intervalTrigger seconds=30
                      buildCondition=ForceBuild/>
      </projectTrigger>
    </triggers>
    <state type=state directory=c:\ccnet\state />
    <labeller type=defaultlabeller>
      <prefix>SampleWeb-Build-</prefix>
      <incrementOnFailure>true</incrementOnFailure>
    </labeller>
    <sourcecontrol type=starteam>
      <executable>C:\Program Files\Borland\
        StarTeam Cross-Platform Client 2006 R2\stcmd.exe</executable>
      <project>Project</project>
      <username>user</username>
      <password>password</password>
      <host>10.1.10.100</host>
      <port>11111</port>
      <path>Projects/Web/SampleWeb</path>
      <autoGetSource>true</autoGetSource>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\Projects\Web\SampleWeb
          </workingDirectory>
        <projectFile>SampleWeb.sln</projectFile>
        <timeout>900</timeout>
        <buildArgs>/clp:PerformanceSummary /verbosity:d
          </buildArgs>
        <logger>C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
    </tasks>
    <publishers>
      <xmllogger />
      <buildpublisher>
        <publishDir>c:\ccnet\artifacts\Web\SampleWeb</publishDir>
        <useLabelSubDirectory>true</useLabelSubDirectory>
      </buildpublisher>
      <email from=no.reply@buildbox.com
              mailhost=localhost includeDetails=TRUE>
        <users>
          <user name=User 1 group=BuildMaster
                  address=user.one@buildbox.com/>
          <user name=user 2 group=TechLead
                address=user.two@buildbox.com/>
        </users>
        <groups>
          <group name=BuildMaster notification=always/>
          <group name=TechLead notification=change/>
        </groups>
      </email>
    </publishers>
    <externalLinks>
      <externalLink name=Sample Web
             url=http://buildbox.com/SampleWeb/default.aspx />
    </externalLinks>
  </project>
</cruisecontrol>


Recognizing Programmer Breeds

29

January

Last week’s post about The Anti-team by Jemery Miller reminded me of a book I picked up a while back: Herding Cats: A Primer for Programmers Who Lead Programmers by J. Hank Rainwater.  In his book, Rainwater offers tips and management techniques on everything from code reviews to managing a distributed workforce.  With good humor, he discusses dozens to topics which relate to a software manager’s every day. 

Per Amazon’s Editorial Review:

While many titles on software engineering and management lean toward the theoretical, this book’s candid and practical focus help distinguish it from the crowd. It also helps that the author is a good writer and mixes quotes from a variety of sources (including Jack Welch and Andy Grove). This is one of the few titles to concentrate on the all-too-common problem of good programmers promoted to project leads, where management and people skills, rather than raw programming chops, will often determine success.

I recommend this book to software development leaders with a request that special attention is given to the section entitled “Recognizing Programmer Breeds.”  Here, Rainwater “stereotypes” developers for the purpose of understanding and identifying ways to work with them.  He groups the breeds into three categories: major, minor and mongrel.  Majors refers to the most common types you’ll find in the workforce.  The minor breed are sometimes seen, but not as frequently as the major ones.  Mongrels, are not very desirable, but the do exist in the workplace, and as a result you need to recognize them.  Mongrels can work out fine, as long as you help them build up their skills to overcome the weaknesses they inherently bring to the coding process. 

As Rainwater notes,

Any individual can be an amalgam of the characteristics identified with a breed — this makes working with that person a challenge but well worth the effort.  Programmers are a wonderfully complex people.  Relish the differences and unique styles of each breed.  You’ll probably recognize many of these traits the next time you look in the mirror.

Here are the developer personality types which Rainwater dissects in his book:

The Major Breeds
The Architecture
The Constructionist
The Artist
The Engineer
The Scientist
The Speed Demon

The Minor Breeds
The Magician
The Minimalist
The Analogist
The Toy Maker

The Mongrels
The Slob
The Intimidated
The Amateur
The Ignoramus
The Salad Chef

You may recognize a few (without having to pick up a copy of his book.)

Update: You’re in luck.  As Jon Rowett points out, Recognizing Programmer Breeds may be found at Apress.com for free.


The Cube Question

29

January

If I had to guess, I would say I conducted at least 100 phone or in-person interviews last year and all of the onsite interviews followed the same standard format:

1. Three or four lead developers, the interviewee and I sit in a large conference room.
2. Per our request, the candidate spends 3-5 minutes telling us about themselves. 
3. The leads and I then take turns asking the candidate both technical and team-oriented questions. 
4. When I get the sense that the team has had adequate time to make a hire/no hire decision, I ask the “cube question.” 
5. Finally, we give the candidate some time to ask us questions. 

So what is the cube question?  It’s something I was asked in an interview years and years ago and I’ve never forgotten it.  “How many sides does a cube have?”  That’s it.  Simple, yet surprisingly 40% of our candidates answer incorrectly. Honest. My guess is that most interviewees figure it must be a trick question and they over-think the answer.  Others are probably so focused on answering the technical and team-oriented questions that they aren’t able to get their brain to chew on anything else.  A small portion probably just have no idea what it is I’m asking.

When it comes down to it, the question, well, more importantly, the answer means nothing to me.  Whether the candidate answers right or wrong, it is a nice way to wrap up our Q & A session and let the candidate ask us some questions.  Not surprisingly, the bulk of the time, the candidate’s first question is “Did I answer the cube question correctly?” 

When the candidate does give us the wrong answer, we sometimes ask for an explanation.  We’ve gotten reasonable explanations why one would answer 8 or 12, but one candidate answered 35.  When we questioned him, he said, “In his world, a cube has 35 sides.”  We hired the guy and he ended up being one the most fun, crazy and talented coders around and we still laugh about it today.

[ I’ve had this post in my queue for a while now.  I had to get it out there today after reading Jim Martin’s post, You Don’t Bury Survivors.  Read it. It’s fantastic. ]


Will Work For … Nothing?

24

November

I don’t remember the exact quote.  Actually, I don’t know if she actually said it aloud, or I could just read it in her eyes, but my wife recently let me know (in her own special way) that I spend a heck of a lot of time on my computer with very little to show for it.  I’m sure I’m completely over-simplifying it, but I think it boils down to this:

I’m doing something software related roughly 100% of the time I’m on the computer.  Since software development is my livelihood, one could reasonably deduce my time spent on the computer is time spent working.  Since most people get paid for their work, it isn’t such a stretch to think I should be compensated for my time on the computer.

I’m sure that some of you are ready to get into a shouting match with my wife.  Now, let’s not judge her quite yet.  She does understand that a good number of coders (including her husband) have a love affair with their work.  Software development may pay our bills, but we also eat, sleep and breathe code and my wife knows it.  She also knows that we need to spend some of our spare time keeping up the Joneses –  learning, experimenting, creating, reading, playing outside of office hours.  She totally gets it.  She really does.  All the same, I do tend to spend an exorbitant amount of time “online” and my wife does have good reason to give me the stink-eye more often than I wish to admit.  

[ Off on a tangent, I have another blog entry in the works.  It’s about the importance of choosing an appropriate development estimator.  In the process of writing the article, I considered how estimation plays into our daily lives. For example, when my wife asks “What time are you coming home from the office today, Honey?” I tend to be overly optimistic.  When I arrive home a few hours later than expected, the stink-eye comes out.  Perhaps you have seen it as well? ]

Most recently, my wife asked why a coder would contribute to an open source project.  I fell back on the the obvious answers:  learning and enjoyment.  I knew what she was thinking, ”Well, that’s fine, but what you are really doing is coding and giving the product away for free.”  She was blunt, but she was right.  It is a little different than just goofing around on the computer “learning” and “having fun” on my spare time.  This was contributing to a legitimate development effort … for nothing.  I did mention that it was also good for networking (meeting other developers, finding future work) but I don’t think I appropriately made my point and the conversation died a quick, yet terrible, death.

Since our talk,  I have been thinking about all the other times I’ve done work for nothing. 

As I mentioned, there’s open source project contributions which, I admit, I haven’t been very involved with in the past.  There’s the dozen or so websites I’ve put together for friends and family over the years.  There’s the handful of sites for the good cause and non-profit organizations.  In some of these cases, I didn’t only do the coding, I also purchased the domain and the hosting.  There were also a couple of savvy business people who promised to make us gazillions of dollars in exchange for a beta version of the software to show the venture capitalists they have lined up.  Finally, I suppose JohnnyCoder.com could be added to to the list of “work I do for nothing” as well. 

Well, there’s a lot of debate on whether or not you can measure software development productivity.  If productivity is a measure of what you get for what you give, I guess, on a personal note, I haven’t always been productive over the years.  Now, I’m not saying it is good or bad, but I would like some additional justification for going about my “business” the way I do. 

Any thoughts? 


Don’t Lose Sight Of The Problem

10

November

You may remember singing There’s a Hole in Bucket when you were younger.  This is the song where boys sing the part of Henry, the poor guy who desperately needs to fix his bucket, and girls sing the part of Liza, his wife, who dreams up the fix. 

There’s a hole in the bucket, dear Liza, dear Liza,
There’s a hole in the bucket, dear Liza, a hole.

So fix it dear Henry, dear Henry, dear Henry,
So fix it dear Henry, dear Henry, fix it.

With what should I fix it, dear Liza, dear Liza,
With what should I fix it, dear Liza, with what?

 

The song begins with a simple problem. Unfortunately, in the process of patching the hole, Henry encounters issue after issue and, in the end, the hole is virtually impossible to fix.  Of course, we see the err of Henry’s ways.  He lost sight of the problem  because he was sidetracked by other problems which he introduced.  We may laugh at Henry, but we fall victim to this same mistake in software development all the time. 

A few years back, I spent a lot of time trying to speed up a query which was hitting a single table over a linked server connection.  I called in a number of people for help and, though we all learned a lot about SQL optimization in the process, we were working on the wrong problem.  I needed to pull data from a table. That’s it! The fact that my query was performing slowly was a completely different problem and a big distraction. I didn’t realize this, however, until someone was smart enough to step back and ask “What is the problem we are trying to solve again?”  Once our focus was back on the problem, we reassessed the solution and 30 minutes later we were hitting the table directly and the expected results were coming back quickly. 

Of course, we don’t only get off track when coding.  The same thing happens in meetings.  Though we may start off with the intension of addressing concerns that a primary server is running dangerously low on disk space, the conversation may take any number of twists and turns.  In this case, maybe focus shifts to how to get approval to work through a different hardware vendor, how can we speed up the company’s reimbursement program, or what can we do to make sure that the group responsible for maintaining the servers actually maintains the servers.  Whatever the case, let’s hope there is somebody in the room willing to ask “What is the problem we are trying to solve again?”  If you are lucky, you may actually walk out of the meeting with a fix to the disk space issue.

If you do find yourself down the wrong path, put your focus back on the problem and ask yourself Henry’s question (”With what should I fix it?”) again.  A better solution is more likely to come to you without the unnecessary distraction of other problems. 

I bet this advice would have helped out that poor old woman who swallowed a fly…


Rethink Job Postings

20

October

Before you submit your next job posting, keep the end result in mind. If you are in the market for talented, interesting people who are accountable for producing quality work, you may wish to give your job listing a second look.

Haacked.com discussed the Art of the Job Post today. The article shares where the great majority of job posters miss the boat and offers tips to get back on track.

The author suggests that one should avoid the standard, monotonous outline of the potential employee’s role and responsibilities. One should not focus solely on what a candidate must provide your company, but, to the contrary, the emphasis should be on what the company has to offer.

A good job ad should not explain what hoops the candidate must jump through to join your company, it should explain why the candidate should even want to jump through those hoops in the first place.

For example, you should not be afraid to cough up information about your company’s personality and culture. After all, a good candidate is going to ask about this anyway.

Sure, many corporations seem like soulless cubicle farms in which workers are seen as mindless drones. But surely not your company, right? So why does your job posting have a tombstone all over it?

You should also “appeal to the vanity” of those seeking employment. Challenge the candidate to show how great they are. As the article states, asking the individual if they are a good problem solver conjures up the desire to prove it.

Again, your job posting should be a request for interesting, talented people — not just those who have methodically pack their resumes with the alphabet soup they think will help them land the offered position. Find these people and it is a win-win for everyone.

In my experience Haacked.com’s comments are accurate. Most job postings are bland and focus only on experience, skills and responsibilities. Heck, I’ve been involved in the hiring process for a few years now and I’m guilty of using the same cookiecutter job description template as everyone else. Shame on me, right? Well, I will give myself some credit. I do request team players with strong verbal and written communication skills and a willingness to learn. But these are only secondary criterion. First and foremost, I evaluate a candidate’s experience and it is their technical know-how which lands them a phone screening. In the end, however, it’s the “soft skills” which get the individual hired.

There’s a lot to be said about the hiring process. It can be extremely frustrating, but also unbelievably satisfying. As one can imagine, it’s crucial to get off on the right foot so mind the “Art of the Job Post.”

I’m sure there’s more to come on the topic in the future…


Email Etiquette 101

20

September

Unquestionably, effective communication is a key ingredient to delivering a successful project. I could rant on and on about avoidable day-to-day issues which exist only because of miscommunication, under-communication or (gasp!) over-communication, but I will save this for another day. Instead, today’s lesson hones in on the primary vehicle for poor communication — email. I am not an expert on the subject, but I do send and receive my fair share of email. I would like to think if everyone adhered to the following guidelines, projects could be delivered with less “drama.”

Do Spell and Grammar Check

This may be my # 1 pet peeve because it is so easily remedied. Nearly all programs provide a spell/grammar checking option so simply enable it. You wouldn’t do a crossword puzzle in pen, would you? We all make mistakes so make sure that proper spelling, grammar and punctuation is used before sending your next message.

Do Read Your Message Before Sending

Spell and grammar checker will bail you out the majority of the time, but it’s still a good idea to proof read a message before it is sent out. It is amazing how easily the context of an email can change due to simple mistakes. (Have you ever accidentally written don’t instead of do? I haven’t. Oops. I mean, I have.) Apart from this, reading your email through the eyes of the recipient will help you send a more effective message and avoid misunderstandings and inappropriate comments. And don’t be afraid to have someone review your message before sending — especially if you are upset with the intended recipient. It’s okay to let an email “sit” for a while until you count to ten.

Do Not Use Abbreviations and Emoticons

In business emails, try not to use abbreviations such as BTW (by the way) and LOL (laugh out loud). This is generally not appropriate. The same goes for emoticons, such as the smiley : ). If you are not sure whether your recipient knows what it means, it is better not to use it.

Do Not Leave Out the Message Thread

There is nothing more frustrating then receiving an email to which you can’t immediately determine the context and you are forced to dig through your inbox (or archives) to get up to speed. This is another “mistake” which is easily corrected. When you reply to an email, always include the complete thread.

Do Not Send Confidential Information

If you aren’t comfortable having an email forwarded to your entire company, don’t send it. Emails have a funny way of landing into the most unlikely person’s inbox at the most inopportune time. A word to the wise: be particularly careful with discriminating comments and jokes. It could cost you your job.

Do Not Attach Unnecessary Files

Compress attachments and only send attachments when they are productive. There’s nothing more infuriating than receiving a message from the System Administrator stating “Your mailbox is over its size limit” just because you’ve been forwarded dozens of 6MB FSDs which could have been replaced with the link to their location in source control.

Do Not Overuse the High Priority Option

If you overuse the high priority option, it will lose its function when you really need it. Moreover, even if a mail has high priority, your message will come across as slightly aggressive if you flag it as ‘high priority’. And we all know the story of the boy who cried wolf…

Do Not Overuse Reply to All

Only use Reply to All if you really need your message to be seen by each person who received the original message. Odds are you will never need to use this option again.

Do Not Request Delivery and Read Receipts

This will almost always annoy your recipient before he or she has even read your message. In fact, it probably annoys them enough that when prompted to send the receipt they will simply cancel the function! If you want to know whether an email was received it is better to politely follow up with the recipient. (Will an article on follow up etiquette be coming soon?)

Do Not Recall a Message

Assume that your message has already been delivered and read. In that case, a recall request would look very silly, wouldn’t it? It is better just to send an email to say that you have made a mistake. This will look much more honest (and call less attention) than trying to recall a message.