Follow this post to easily version your FitNesse wiki acceptance tests (or any other tree of files).
The product manager and his crew will use the FitNesse wiki to author and maintain acceptance tests for the system. These tests are stored in files on the FitNesse server. This presents a unique problem of backing up and versioning the tests. The wiki itself supports 15 levels of modifications, but we use Subversion as the standard versioned backup at the company, so we’d like the acceptance tests to go there.
Here is how we solved this problem:
We created a new project in CruiseControl.Net to watch the wiki. Call it WikiWatcher. This project uses “filesystem” as it’s source control to watch. We point this at the FitNesse directory, and CC.Net will react when any of the files there change. CC.Net then kicks of a Nant script, and that gives us all the power we need. In Nant, we run two <exec/> task. The first adds any files not currently in SVN, and the second commits the files. NantContrib only provides update and checkout tasks for SVN, so we had to hit svn.exe directly with some command line arguments. This system works well, and within 60 seconds of a Wiki modification, the changes are versioned and backed up in SVN. (The CruiseControl.Net documentation can fill in any gaps you may have)
Here is the CC.Net config section that defines our project:
<!– this project watches the fitnesse wiki and backs things up in subversion –>
<project name=”WikiWatcher”>
<webURL>http://<serverName>/ccnet/Controller.aspx?_action_ViewProjectReport=true&server=aufile01&project=FitNesseWatcher</webURL>
<triggers>
<intervalTrigger seconds=”60″ />
</triggers>
<modificationDelaySeconds>15</modificationDelaySeconds>
<publishExceptions>false</publishExceptions>
<labeller type=”defaultlabeller”>
<incrementOnFailure>false</incrementOnFailure>
</labeller>
<sourcecontrol type=”filesystem”>
<repositoryRoot>C:\fitnesse</repositoryRoot>
<autoGetSource>false</autoGetSource>
<ignoreMissingRoot>false</ignoreMissingRoot>
</sourcecontrol>
<tasks>
<nant>
<executable>c:\<some path>\trunk\bin\nant\NAnt.exe</executable>
<baseDirectory>c:\<some path>\trunk</baseDirectory>
<buildFile>WikiWatcher.build</buildFile>
<targetList>
<target>commit</target>
</targetList>
<buildTimeoutSeconds>1500</buildTimeoutSeconds>
</nant>
</tasks>
<publishers>
<xmllogger />
</publishers>
</project>
This is pretty simple. Just add the above as a CC.Net project node, and you’re off to the races. The Nant script is even simpler.
Here’s the Nant script:
<?xml version=”1.0″ encoding=”utf-8″ ?>
<project name=”WikiWatcher” default=”commit” xmlns=”http://nant.sf.net/release/0.85-rc3/nant.xsd“>
<property name=”baseWikiDir” value=”C:\fitnesse”/>
<target name=”commit” description=”Commits entire wiki directory to source control”>
<fileset basedir=”${baseWikiDir}” id=”wikiFiles”>
<include name=”**”/>
</fileset>
<echo message=”My build ran”></echo>
<exec program=”c:\program files\subversion\bin\svn.exe”
commandline=”add –force *.*”
workingdir=”${baseWikiDir}” />
<exec program=”c:\program files\subversion\bin\svn.exe”
commandline=”ci -m"automatic checkin" –username <some user> –password <some password>”
workingdir=”${baseWikiDir}” />
</target>
</project>
This adds and commits all FitNesse files to SVN, and we’re done.
Have you found a solution for dealing with refactoring of Fitnesse pages (specifically, deletions?) Without a way to use svn delete, the commit will fail.
I am using a FitNesse plugin for eclipse which allows me to have FitNesse running within my eclipse shell. I have to start version control.. as of now I have not faced any problem but I have read at many places that if we version control FitNesse pages and use refactoring, it might break something in version control.. I am curious to know more on this topic.
This is definitely an ability which should be present in Fitnesse.
I’m looking at the Fitnesse source code to see whether I can “crowbar in” JavaSvn to do it a bit more natively than using the CC.NET method. It looks possible but not terribly elegant at the moment – for one thing, the code is hard-wired to use FileSystemBasedPage (IIRC) on startup. Have to do something about that to start with…
Jon