Running Python Unit Test in a VSTS/TFS build

Here’s a short explanation how to execute python unit tests during VSTS/TFS builds, without the need of plug-ins. The basic idea is to create a JUnit XML from your test results, and then have it published to the TFS build dashboard.

First, on the relevant build agent(s), install the pytest module. You can use the following command, or your favorite CM tool.

python -m pip install pytest

Next, edit your build definition in TFS, and add two build steps: one (Batch Script) for running py.test to generate a junit XML, and one (Publish Test Results) for publishing the xml to the test results page.
The full command line to run the tests is as follows (in this example, the unittest code is in

python -m py.test --junitxml test-results.xml

Here is a sample build definition which includes only those two steps:


Build Steps


Batch Script Settings


Finally, queue the build, and you will able to see the test results in the build page:





Python and Windows Symbolic Links

Python, like many other popular OSS (Git anyone?), does not support symbolic links on Windows platforms , although they have been around since Windows Vista. Note, I am referring to actual symbolic links, not NTFS directory junctions or shortcuts.

I’m not really sure why is that. Maybe because they do not distinguish between different Windows revisions?

My current approach is to use the OS commands to create/delete symlinks. It’s not very elegant but it works without compatibility issues, unlike other solutions (calling win32 api through DLLs, manipulating file attributes, and other stuff you find in StackOverflow or tech blogs)

For example, to create a symbolic link of directories, one can use:

 child = subprocess.Popen(['MKLINK', '/D', link, target], stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)
 streamdata = child.communicate()[0]

And check child.returncode for the result (and the output – stdout and stderr combined – available in the streamdata variable)

To remove a symbolic link to a directory, use the windows RMDIR command (os.rmdir or os.unlink won’t work)


Python in Visual Studio 2015

When I first heard that Visual Studio 2015 is going to support developing with Python, I wasn’t sure how to react. Microsoft? Python? it just doesn’t seem related. I was very skeptical about working in Python within Visual Studio.

Recently I started a new pet project in GitHub to play around with VS integration to GitHub. So I figured, let’s include some Python code just to see how it feels working with Python in VS.

And it feels great, actually! Visual Studio users would feel right at home with IntelliSense-like auto completion and tooltips, debugging capabilities, unit testing with Test Explorer, advanced searching and editing, and more. I would dare comparing it to some of the best Python IDEs out there like PyCharm. GitHub integration also work seamlessly.

This Python support (a.k.a Python Tools for Visual Studio) is included in the free Visual Studio 2015 Community edition, and even available as open source on GitHub.

Microsoft! on GitHub! Times are changing, indeed.

cmd /c doesn’t like quotes

I was quite baffled at first.

This works:

cmd /c "C:\Program Files\7-Zip\7z.exe" C:\Temp\MyFile.7z

But this fails:

cmd /c "C:\Program Files\7-Zip\7z.exe" "C:\Temp\My Other File.7z"
'C:\Program' is not recognized as an internal or external command, operable program or batch file.

Turns out it’s an issue as old as Windows 2000.

The solution is to add another pair of quotes around the entire command:

cmd /c ""C:\Program Files\7-Zip\7z.exe" "C:\Temp\My Other File.7z""

Thank you, Microsoft.

Getting a JIRA issue’s priority using Perl

JIRA::Client is a great and useful module. Too bad some of its usage is so cryptic!

For example – suppose you want to print an issue’s priority field. if you simply use $issue->{priority} you will get the priority id, not the display name which everyone is used too.
So, how to get the display name? documentation is very vague on this subject. Google doesn’t help much here.

After a lot of trial & error I figured out a way.

Continue reading