Archive for the 'Best Practices' Category
links for 2008-04-22
Subversion Best Practices

Here’s a list of practices that we use over at ImageTrend that have proven very helpful over the last year. We made the switch to Subversion in Fall of ‘06 from Visual Source Safe. I wrote this about a year ago, and all of the points are still very valid today.

  • With every commit, give a very descriptive and helpful commit message. Say what the commit changes, any additional features added, specific bugs fixed, etc. If you need a reminder of what you’re committing, take a few minutes to compare your workspace files that you are committing to their head revisions in the repository (it will show you line-by-line what changed). When committing the message, ask yourself, ‘Would this make sense to the guy next to me if he read it?’. If there was a help desk/track record or a SQL Script file associated with the commit, make a note of it! If the commit is a file you missed with another commit, use the same commit message as the initial commit. (Both Eclipse and Tortoise have a feature to auto-load recent messages for this reason) Remember, you can always go back and edit your commit message if you forget something (and if you realize you forgot something, absolutely go back and make a note of it!).

Here are some examples of messages that need work:

    • “(No Commit Message)” – There are lots of these around. Anything is better than nothing.
    • “CFC changes needed for Payables updates.” – What was the change? Did you add a method that others can use? This type of message doesn’t tell anyone much.
    • “updated logic for task counts next to folders”
    • “added logic for renewal” – How was the logic changed? If I included this message in the release notes which are sent to the client, would they understand it?

And examples of good messages…

    • “Changes to Payables Queue: Added Transaction Type and Check Number columns. Changed Year filter to a Date Range filter. Status filter now in sequential order. User can now only update the status of Payables with a status of Pending. No sql scripts required.”
    • “Added ‘Date FROI was received date’ to accident overview”
    • “Added permissions around the update tools on the browse payables object. When deploying this change, be sure to setup the security in resource management.”

A few extra minutes of adding a descriptive and helpful message can prevent problems from happening on deployment and will ultimately keep our customer happy.

  • Don’t commit changes to the trunk that will cause someone else’s code to break. If you are committing to the trunk repository, pretend that it is going to go up to production in 5 minutes. If it’s going to cause something to break, don’t commit it to the trunk! If you want to commit it so someone else can take a look at what you’re doing, or you can work on it remotely, create a branch and switch your working copy to that branch. When you’re finished with your changes, merge them with the trunk. For more information on branches and merging, see this link to the free o’rilley book on SVN. [Editor's Note: We practice Branch for Feature (Scenario 4). This may differ depending on your own branching strategy]
  • If your commit message requires a DB Change, Include a SQL script in the commit. Also, make a note of the script in your SVN Commit message so it can be run when your revision is deployed up to different environments. Make sure you notify the DBA’s of your change. [Editor's Note: or better yet, come up with your own way of Database Versioning]
  • Commit Often. It is preferable to have many smaller commits (2-5 files) rather than one large commit (10+ files). A general rule of thumb is 1 commit per feature change or 1 commit per bug-fix. This rule doesn’t necessarily apply in the early stages of development when massive amounts of code are generated (adding a completely new feature that might include 15 pages of code), or bringing down an entire branch into the trunk. The reason for this is that it’s easier to log and revert an entire revision than it is to log and revert select files in one or more particular revisions.
  • Check out a permanent copy of the Trunk. Because we have recently been utilizing branches, there will be times when you will be asked to re-prioritize and perform a bug-fix on the trunk while you’re currently working off of another branch. Rather than switching out your working copy from a branch to the trunk (which could take upwards of 30 minutes) you can perform the bug-fix on your permanent-copy of the trunk and commit directly from there. [Editor's Note: Again, if your branching strategy differs from Branch for Feature, you might do this differently.]
  • Update your workspace often!!! The great part about SVN is that you don’t need to download entire files each time a file is changed. By updating often and testing on your local instance, you will be able to be certain that the changes you make work with the current revisions of the system, and be confident that your commits will not cause any unwanted secondary effects.
  • Review your changes before you commit! Blindly committing your code without even a quick review of the “diff” (the changes you’re adding to the repository) can cause many headaches later on to try and re-implement code that may have accidentally been overwritten. You can quickly view the diff in tortoise by double clicking the files that are being committed in the commit dialog. The changes will always be highlighted, and If you need to you can right click the lines and revert, or just go back and fix the changes yourself.

I’d love to hear any other best practices you guys use out there, post away in the comments below.

Running Functional Web Application Tests with Selenium

One of the best things any developer can do is to automate regular tasks as much as possible. On the quality control side, this includes running regular functional tests to check to make sure that everything still works exactly as it’s supposed to. Selenium is a project which lets developers write tests for browsers to “drive themselves”. This basically means you develop a script which selenium can then read and interpret into mouse clicks. Scripts can be written by hand, but it is usually easiest to start by having the Selenium IDE watch you click around and then use the script it generates as a starting point. The best part about this project is Seleneium-RC which lets you take the scripts and run them directly from .NET, Java, Ruby, PHP, and others. Having this capability also lets us integrate these scripts into unit testing, which we can run regularly with tools like CruiseControl.

For example, if I launch Firefox, and open up the Selenium IDE, and then open google and search for “Billy Bob Thorton”, then click pages 2,3,4, Next, and Back, Selenium IDE will look like this:

ss-1

We can then export this script to code. C#, for Example:

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using Selenium;namespace SeleniumTests
{
    [TestFixture]
    public class google
    {
        private ISelenium selenium;
        private StringBuilder verificationErrors;

        [SetUp]
        public void SetupTest()
        {
            selenium = new DefaultSelenium(“localhost”, 4444, “*firefox”, “http://localhost:4444″);
            selenium.Start();
            verificationErrors = new StringBuilder();
        }

        [TearDown]
        public void TeardownTest()
        {
            try
            {
                selenium.Stop();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual(“”, verificationErrors.ToString());
        }

        [Test]
        public void TheGoogleTest()
        {
            selenium.Open(“/”);
            selenium.Type(“q”, “billy bob thorton”);
            selenium.Click(“btnG”);
            selenium.WaitForPageToLoad(“30000″);
            selenium.Click(“link=2″);
            selenium.WaitForPageToLoad(“30000″);
            selenium.Click(“link=3″);
            selenium.Click(“link=4″);
            selenium.WaitForPageToLoad(“30000″);
            selenium.Click(“link=Next”);
            selenium.WaitForPageToLoad(“30000″);
            selenium.Click(“link=Previous”);
            selenium.WaitForPageToLoad(“30000″);
        }
    }
}

This code should be compiled to a Windows Library type, and run within an NUnit Test runner. There’s a few things you need to consider before straight up running this code:

  • Ensure that your selenium server is running on your localhost, or change the selenium constructor line to point to the correct network path.
  • Include the NUnit.Framework and NUnit.Core dll’s in your resource directory, and make sure they get copied to the output directory.

For the NUnit test runner, I would reccommend downloading testdriven.net- it allows you to easily right click within the method and then run the tests without having to worry about compiling, launching the NUnit test runner, and then opening up the DLL. The end result of this is a firefox browser is opened, and Selenium reproduces exactly what you did when you were controlling firefox.

More on integrating this test with CruiseControl soon…

Setting Up CruiseControl

Today I delved into the world of automation, in an attempt to try and refine and automate some of the process that happens around here. I have known about the existance of CruiseControl for well over a year now, but I haven’t had (or necessarily needed) the chance to use it. With the size of my development group growing larger on quite a regular basis, tools like this are going to become increasingly necessary.

What is Cruise Control?

Taken straight from their home page..

CruiseControl is a framework for a continuous build process. It includes, but is not limited to, plugins for email notification, Ant, and various source control tools. A web interface is provided to view the details of the current and previous builds.

This means we’ll be able to focus on bigger and better things, such as writing unit tests to improve the quality control of our code, automating deployments when it is time for our releases. (including database scripts that need to run, as well as the code)

Goals for this side project of mine include:

  • Improving the way we version our database changes
  • Bringing in regular use of unit testing into my group
  • Bringing in regular use of functional and performance testing

From what I understand, CruiseControl, along with other tools such as ANT and Selenium will allow us to achieve these objectives. What will be interesting is that I haven’t read anywhere on achievements with this specific to ColdFusion.

Automation with CruiseControl and ColdFusion

Today I delved into the world of automation, in an attempt to try and refine and automate some of the process that happens around here. I have known about the existance of CruiseControl for well over a year now, but I haven’t had (or necessarily needed) the chance to use it. With the size of my development group growing larger on quite a regular basis, tools like this are going to become increasingly necessary.

What is Cruise Control?

Taken straight from their home page..

CruiseControl is a framework for a continuous build process. It includes, but is not limited to, plugins for email notification, Ant, and various source control tools. A web interface is provided to view the details of the current and previous builds.

This means we’ll be able to focus on bigger and better things, such as writing unit tests to improve the quality control of our code, automating deployments when it is time for our releases. (including database scripts that need to run, as well as the code)

Goals for this side project of mine include:

  • Improving the way we version our database changes
  • Bringing in regular use of unit testing into my group
  • Bringing in regular use of functional and performance testing

From what I understand, CruiseControl, along with other tools such as ANT and Selenium will allow us to achieve these objectives. What will be interesting is that I haven’t read anywhere on achievements with this specific to ColdFusion.

This will be the first post in a series of many on this topic.