Thursday, October 12, 2006

The myth of the "perfect past project"

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_myth_of_the_perfect_past_project.htm]

In today's world, developers switch projects a lot. Whether it's a consultant at the same company who keeps jumping between 3 month projects, or a developer who switches jobs every two years, most people can refer to some "previous" job. I notice an interesting trend, that some people insist that they've had that perfect project in the past - the one (unlike their current job) where everything was done properly. It almost comes across as their development life was great before (i.e. their last job did it "right"), but their current employer is a bozo. Many people can refer to a good previous project because some other star (not them) made it good. For example, a past project may have had awesome process or tools - but someone else set it up. It seems like a bluff (or the grass is always greener on the other side thinking), but because you don't know about their previous project, and have to just take their word for it. But, you can always ask what they did to make that last project so great, and what they can do on the current team (besides just reminiscing about the "Good old days") to make the current project better.

Friday, September 15, 2006

How to make maintenance easier

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/how_to_make_maintenance_easier.htm]

Almost everyone would rather create something new than fix something broken (especially someone else's broken code). However, it's inevitable that some maintenance will always be required. Here are some ideas to make maintenance easier:

  • Reduce the amount of work that must be maintained by refactoring your code.
  • Add Unit Tests for easier regression testing, and to make sure that your maintenance doesn't break something else.
  • Document your work so that it's easier to understand, perhaps with inline comments (maybe using NDoc), wikis, or more traditional word documents for feature designs.
  • Design you code to be maintainable - perhaps use simpler algorithms (if all else is equal), loosely couple components so that it's easier to understand, make flexible code, etc...

Sunday, September 3, 2006

Creating Database Unit Tests - new install UI

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/creating_database_unit_tests__new_install_ui.htm]

The MassDataHandler is a framework to assist with Database Unit Testing. The framework makes it very easy to insert test data into a database, which in turn makes it very easy to write database unit tests. The user merely needs to specify their relevant data in a simple XML fragment, and then the framework uses knowledge of the database schema to do all the grunt work and convert that XML data into SQL, from which it populates the database.

It is an open-source .Net app available here.

We recently improved the install process for the app by having a GUI form collect environmental info for SQL 2005, MSTest, and MSBuild. The install script uses the concept of Having an MSBuild script collect userinput.

If you're looking to test your data layer, check out this free tool. It's now easier to install.

Saturday, August 26, 2006

Have MSBuild script collect userinput

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/have_msbuild_script_collect_userinput.htm]

MSBuild is great for automated batch processes. It's easy to set properties in the script itself using the . However, MSBuild is powerful enough that you can also collect user input with a WinForm.

Why would you do this, given that the whole point of a build process is to be automated? ... Because MSBuild is an automation language, it can be used not just for builds but to
ultimately automate any task. For some tasks that you kick off manually (like installations, deployments, instrumentation, etc...) you may want to collect the user input up front.

Doing this requires three steps.

  1. Use MSBuild's exec task to call a WinForm exe (that you create with a Windows Form project). Note that you may want to compile the windows project first, and then call the newly created exe.
  2. Have the WinForm app close, returning an error
  3. Back in the MSBuild script, collect this error information and handle it how you want.

The first step is easy, lets look at the second one. There are several different ways we can return error information from a WinForm.

  1. We could throw an exception, but that just pops up a messy JIT window, tells the user that the app failed, and doesn't return an error to the build process.
  2. We could have the WinForm write out to a log file, and then have the MSBuild script fail if that file exists - but that requires extra files and is messy.
  3. We could modify the return code of program.cs (just like you can modify a console app's return code) to return an integer, and that set that int with a static variable. This is our best option of the three - no external files, and the error is handled gracefully.

With this technique, everything becomes easy: Our MSBuild script can be simple:

  "EndPoint">
   
    "WindowsApplication1\WindowsApplication1.csproj"
        Targets="Build"
        Properties="Configuration=Debug" />
   
    "Start UI" />
    "WindowsApplication1\bin\Debug" Command="WindowsApplication1.exe" />

    "Done, do other stuff now..." />
 

The WinForm is easy:

  static class Program  {    ///     /// The main entry point for the application.    ///     [STAThread]    static int Main()    {      Application.EnableVisualStyles();      Application.SetCompatibleTextRenderingDefault(false);      Application.Run(new Form1());      return _intReturnCode;    }    private static int _intReturnCode = 0;    public static int ReturnCode    {      get { return _intReturnCode; }      set { _intReturnCode = value; }    }      }

 

We can then set the static variable "ReturnCode" anywhere in the WinForm by setting Program.ReturnCode.

(Note that we can also have the WinForm use Console.Writeline(), which will be logged in the MSBuild script).

Having the MSBuild script take user input is an easy trick to perform, and may be helpful for certain tasks.

Friday, August 25, 2006

Things that fundamentally improve how you program, Part II

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/things_that_fundamentally_improve_how_you_program_part_ii.htm]

About a year ago, I posted on Things that fundamentally change how you program, listing several things:

  • Object Oriented Code
  • Unit Tests
  • Regex Expressions
  • Xml
  • Code Generation
  • Consciously seeking Tools

A year later, there are new things I would add to this list:

  • Continuous Integration - Besides just checking in your code to a general repository, there's a huge benefit to have the repository's source code continually tested with a regular build. A simple build may just compile and run unit tests. However, by doing this whenever someone checks in new code, you can catch many errors because they propagate and do real damage. A popular (and free) Continuous Integration framework is CruiseControl.
  • Automation, especially of processes (such as with MSBuild). The point is that complicated processes are two tedious to repeatedly do manually. For example, a build process may take 30 minutes, and with Continuous Integration you may do this 20 times a day. There's simply no way to manage it without automation.
  • CallBacks and Ajax/Atlas related technologies. This changes how websites operate, from the postback model that sends the entire page back and forth, to a asynchronous request that sends just a small packet of data, which enables you to make a rich-UI.
  • Virtual Machines (such as VMWare) - I'm exploring this more, but essentially Virtual Machines let you make a "guest" image of a machine that runs in isolation on a host. This can be great for expanding your build process, testing in different environments, and studying applications with a ton of configuration to them (without messing up the main host machine).
  • Blog Aggregators - In our industry, learning is critical. If you stop learning, not only does the job become dull, you risk losing your job. Blogs are a great way to learn new quick and practical ideas from veterans in the trenches. A blog can publish info much faster than a book. Reading blogs is a great way to inject a bunch of new ideas into your head. The problem is that no one wants to manually check 20 different web pages, so you'll want a way to aggregate all the new blog posts into an easy-to-read inbox (as if they were email). Two free blog aggregators are RssBandit and SharpReader.
  • Visiting Tradeshows or users groups. Anytime you get out of your cubicle, and meet other experts face-to-face in the field, it will make you more confident. User groups are usually free, let you bump shoulders with other real people, and keep you in the loop about new technologies and trends. Along with reading high-profile bloggers, this helps you never to get "surprised" by some sudden technical development that changes how your app functions. It also gives you assurance in knowing how other people implement things.

All of these things are easy to get started, but they will fundamentally improve how you program. If you want to be a better developer, you'll get a high return from investing in these things.

Monday, August 21, 2006

Creating Database Unit Tests in 10 minutes.

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/creating_database_unit_tests_in_10_minutes.htm]

Unit testing the database is hard - and there are mixed reactions to it. My take is that there could be legitimate logic in the database (transactions, SQL aggregations, reusable functions, complex SP like paging, etc...). The problem with unit-testing the database is creating a test database and filling it with data. At Paylocity, we created a tool called the MassDataHandler to help us unit-test our data layer. We recently open-sourced this tool, and you can download the beta here.

The MassDataHandler is a framework to assist with Database Unit Testing. The framework makes it very easy to insert test data into a database, which in turn makes it very easy to write database unit tests. The user merely needs to specify their relevant data in a simple XML fragment, and then the framework uses knowledge of the database schema to do all the grunt work and convert that XML data into SQL, from which it populates the database.

The XML fragments that contain the test data are robust and refactorable. You can include expressions like variables substitution and identity lookup, default row templates, and include statements to import sub-templates. Because the framework already knows the database schema, you only need to specify the relevant data, and the framework can auto-populate the rest of the row’s required columns with dummy data.

For example, the following Xml script would insert data into three tables - providing you variables, default row templates, and automatically handling the identity lookups and non-null fields:

  <Root>

    <Variables>
      <Variable name="lastName" value="Simpson" />
    Variables>

    <Table name="Customer">
      <Row CustomerName="Homer $(lastName)" />
      <Row CustomerName="Marge $(lastName)" />
    Table>

    <Table name="Product">
      <Row ProductName="KrustBurger" Description="best burger ever" />
    Table>

    <Table name="Order">
      <Default LastUpdate="12/23/1997" />
      <Row CustomerId="Customer.@1" ProductId="Product.@1" />
      <Row CustomerId="Customer.@2" ProductId="Product.@1" />
    Table>
   
  Root
>

Download the MDH Framework Beta here.

By making it so easy to insert and maintain test data, the MDH framework helps you write database unit tests.

Sunday, August 20, 2006

How to program what you enjoy

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/how_to_program_what_you_enjoy.htm]

We all want to program what we enjoy - else our job gets boring. Loving your job also builds Technical Confidence. Some people just wait, hoping that the perfect project will fall in their lap, but there are things you can do to help your cause:

  1. Make a list for yourself of what you want to program. If you don't know what you want, no one else will know for you.
  2. Work little bits of these things into daily features. Perhaps you can demo a new coding technique, framework call, or trick.
  3. Make an objective business case for it so that it's not "Bob wants to play around with new tech X (wouldn't we all)", but rather "Bob can add value to the team using new Tech X".
  4. Tell your manager so that they can look out for you. If your manager knows that you're interested in "X", then they can at least try to send that kind of work your way.
  5. When you get the opportunity to do part of the new tech on something small, nail it.
  6. Invest your own time (off the clock) to build a prototype of something. You can then show this to management (you're not just some dreamer wasting their time, but a solid contributor with a tangible prototype). It also helps you Continually learning better coding methods, and demonstrates your commitment to management ("Bob did this on his own time, imagine what he could do if we let him do it full time").