Friday, August 6, 2010

Running Fitnesse with PowerShell - RESTful Tests

Previously I noted how I had written my original tests with Fitnesse to use the TestRunner and access Fitnesse in a way that worked, but as I recently discovered is no longer supported. Oh well, so I update my tests. Which was necessary anyway, since on the Build Machines where these tests would be run Fitnesse is not going to be running, and if it was I shouldn't need to usurp it for my tests. So I moved over to using the RESTful method, which I had a hard time with earlier, but now is so insanely simple I wonder why I had a hard time with it before.

Without futher ado, here is the RESTful method to run Fitnesse tests.

First I set up my variables, I've also added in an archive file now, so I can keep track of my results, the RESTful results are nice so I actually output each test into its own results file, and I make an aggregate to be an archive. Eventually I will get rid of the individual results and keep the archive around - this also let's me go onto any machine that ran a test and see how things have been going. The Arrays I have are suites that I set up in Fitnesse to contain my tests, I have one for QA that I would run, and a Smoke suite that is a selected set to verify the build worked.

# Get the current directory Push-Location .
# Variables for the script
# This location should not change, since its the standard checkout location
[string]$fitnesseLocale = "C:\MAIN\trunk\AutomatedTests\Fitnesse\Fitnesse"
[string]$fitnesseJar = "fitnesse.jar"
# Need to get the local machine here, it will be how Fitnesse runs [string]$serverName = $env:COMPUTERNAME
[string]$portName = "8080"
# These are needed for the CheckFitnessProcess function,
# placing them here
$fitRunning = $false
# Set Java executable to use within PowerShell $Java = "java.exe"
# Archive file $archiveFile = "fitnesseArchive.txt"
# Use a Test Array to be able to bundle all the tests
# Tests that are commented out are having issues being run
# Smoke Testing is Development Based
# although its now geared towards checking Login
$smokeArray = ( "SpringsLoginLiteTests" )
# Tests for the QA environment
# although its now geared towards checking page links
$qaArray = ( "SpringsLinkChecks" )
# Tests to check how this script runs, this is a hidden command
# This just validates the Registration Verify Fields
$checkArray = ( "SpringsTest.UserLoginFfTests" )
# Location of the Test Results, this is hardcoded within the SVN structure
# so it should always be available, I am sure there are better ways of doing this
$testResultsDir = "C:\IHI_MAIN\trunk\AutomatedTests\Fitnesse\Fitnesse\testResults"
if (!(Test-Path -path $testResultsDir))
{
New-Item $testResultsDir -type directory > $null
}
Then I still run my check on whether Fitnesse is running, it doesn't really need to be running anyway; so I decided that since REST only runs as needed then I was going to shut down Fitnesse if it was going.

# CheckFitnesseProcess determines if Fitnesse is running, if Fitnesse is not running
# then the script continues. The current test configuration does not require Fitnesse
# to run and does a better job when it's not.
# Adapted from: http://odetocode.com/Blogs/scott/archive/2006/07/17/5330.aspx
function CheckFitnesseProcess {
param ([string]$AppPoolName="")
$ProcessId = $null
if ($AppPoolName.ToUpper() -ne $NOT_PASSED) {
[string]$filter = $null
if ((Get-Process java -ErrorAction SilentlyContinue) -ne $null) {
Get-Process java | ForEach {
# use WMI API to get process details
$filter = "Handle='" + $_.Id + "'"
$wmip = Get-WmiObject Win32_Process -filter $filter
# CommandLine property has AppPool name; grab name using contains
if($wmip.CommandLine.contains("fitnesse")) {
# Uncomment the next line for debugging
# Write-Host "Found this java process: $wmip.CommandLine `n"
$fitRunning = $true
# Saving the Process ID to stop the process later,
# using a Global as I could not get this work if I declared
# the variable at the beginning.
$Global:fitProcess = $_.Id
}
}
}
if ($fitRunning -eq $false) {
# All is good
}
if ($fitRunning -eq $true) {
Write-Host "Fitnesse is running, it's best if its not - shutting it down...`n" -ForegroundColor Red
# Stop the Fitnesse process
Stop-Process -Id $fitProcess
}
}
}
I'm going to skip the Help function, if you need that it should be in my previous post, the important one is the Main function.


function main()
{
# Need to be in the Fitnesse directory to access TestRunner, and
# the Fitnesse batch file in case Fitnesse needs to be started
cd $fitnesseLocale
#Check and see if Fitnesse is running
CheckFitnesseProcess
foreach ($test in $testArray)
{
# Start the test
$myDate = Get-Date
Write-Host "`nRunning $test`n"
# Build RESTful URL
$testLink = $test +"?" + $testType +"&format=text"
# Get the output from TestRunner so we can scrape it for test passes and fails
$testResults = & $Java "-jar" "$fitnesseJar" "-c" "$testLink"
Write-Host "Completed $test`n"
# Write-Host "Test Results..."
# Scan through the output, then display the results
# Dump $testResults out to a File
$testFile = $test + $myDate.Day + $myDate.Month + $myDate.Year + $myDate.Hour + $myDate.Minute + ".txt"
$testResults | Out-File "$testResultsDir\$testFile"
# Print out date to an archive file
$testDate = "Last run time: " + $myDate.Day + "/" + $myDate.Month + "/" + $myDate.Year + " at " + $myDate.Hour + ":" + $myDate.Minute
$testDate >> "$testResultsDir\$archiveFile"
foreach ($line in $testResults)
{
if ($line -match "\A\.\s"){
# This is a Pass
Write-Host $line -ForegroundColor Green
# Output to archive file
$line >> "$testResultsDir\$archiveFile"
}
if ($line -match "\AX\s") {
# This is an Exception, a warning but not a Failure
Write-Host $line -ForegroundColor Yellow
# Output to archive file
$line >>