6

I have a build configuration in TFS 2013 that produces versioned build artifacts. This build uses the out of the box process template workflow. I want to destroy the build artifacts in the event that unit tests fail leaving only the log files. I have a Post-Test powershell script. How do I detect the test failure in this script?

Here is the relevant cleanup method in my post-test script:

function Clean-Files($dir){
    if (Test-Path -path $dir) { rmdir $dir\* -recurse -force -exclude logs,"$NewVersion" }
    if(0 -eq 1) { rmdir $dir\* -recurse -force -exclude logs }
}
Clean-Files "$Env:TF_BUILD_BINARIESDIRECTORY\"

How do I tests for test success in the function?

NotMyself
  • 29,209
  • 17
  • 56
  • 74
  • Failure being if some of the directories contents were not deleted and the directory is not truly empty? Or just error from the `remove-Item` cmdlet? – Matt Nov 07 '14 at 20:10
  • Failure being a unit test failed during the unit test run. – NotMyself Nov 07 '14 at 20:34

3 Answers3

3

(Updated based on more information)

The way to do this is to use environment variables and read them in your PowerShell script. Unfortunately the powershell scripts are run in a new process each time so you can't rely on the environment variables being populated.

That said, there is a workaround so you can still get those values. It involves calling a small utility at the start of your powershell script as described in this blog post: http://blogs.msmvps.com/vstsblog/2014/05/20/getting-the-compile-and-test-status-as-environment-variables-when-extending-tf-build-using-scripts/

Richard Banks
  • 12,456
  • 3
  • 46
  • 62
  • The test runs are a step of the Team Build template. The powershell script is called via the template as well after the test run completes. – NotMyself Nov 09 '14 at 19:57
  • This seems to do the trick. Seems like a huge miss by the TFS Team Build Team. If I am executing a script post test, it's only logical that I would want to access the test results in that script. Also, it a a bit sketchy to download a zip file form some random .net developers blog that is hosted on yet another random .net developers blog and expect anyone to use it. I poked around with dotpeek and it looks like the assembly has references to Telerik's Analytics system. There is no notification of that anywhere in the blog post or in the download. That does not really inspire confidence. – NotMyself Nov 10 '14 at 17:11
  • I think I will reply to the poster the suggestion that they opensource this tool set and make it available via nuget. – NotMyself Nov 10 '14 at 17:14
  • @NotMyself I totally agree this should be easier to do. Once I done this, at least I had to struggle to pass de enviroment variables from a bat to powershell. Luckly I found this other thread http://stackoverflow.com/questions/4384814/how-to-call-batch-script-from-powershell Hope I saves someone the two hours I spent on this – Christian Rodriguez Feb 04 '15 at 12:32
2

This isn't a direct answer, but... We just set the retention policy to only keep x number of builds. If tests fail, the artifacts aren't pushed out to the next step.

With our Jenkins setup, it wipes the artifacts every new build anyway, so that isn't a problem. Only the passing builds fire the step to push the artifacts to the Octopus NuGet server.

cloggins
  • 659
  • 3
  • 16
2

The simplest possible way (without customizing the build template, etc.) is do something like this in your post-test script:

$testRunSucceeded = (sqlcmd -S .\sqlexpress -U sqlloginname -P passw0rd -d Tfs_DefaultCollection -Q "select State from tbl_TestRun where BuildNumber='$Env:TF_BUILD_BUILDURI'" -h-1)[0].Trim() -eq "3"

Let's pull this apart:

  1. sqlcmd.exe is required; it's installed with SQL Server and is in the path by default. If you're doing builds on a machine without SQL Server, install the Command Line Utilities for SQL Server.
  2. -S parameter is server + instance name of your TFS server, e.g. "sqlexpress" instance on the local machine
  3. Either use a SQL login name/password combo like my example, or give the TFS build account an account on SQL Server (preferred). Grant the account read-only access to the TFS instance database.
  4. The TFS instance database is named something like "Tfs_DefaultCollection".
  5. The "-h-1" part at the end of the sqlcmd statement tells sqlcmd to output the results of the query without headers; the [0] selects the first result; Trim() is required to remove leading spaces; State of "3" indicates all tests passed.

Maybe someday Microsoft will publish a nice REST API that will offer access to test run/result info. Don't hold your breath though -- I've been waiting six years so far. In the meantime, hitting up the TFS DB directly is a safe and reliable way to do it.

Hope this is of some use.

Warren Rumak
  • 3,824
  • 22
  • 30