Pester Testing And PowerShell Development Workflow

In this post I’m going to have a look at Pester testing and PowerShell development workflow. I’ll be using Visual Studio and Team Foundation Server/Visual Studio Team Services to keep it simple. What I’m going to show won’t be news for developers but this can help to put testing in perspective for non developers.

Developer WorkFlow
Firstly lets have a look at the typical points during development when you want to run your tests and then we will dive into the details of getting it to work.

  • Running tests locally while developing.
    This depends on the development methodology you follow.

    • If you practice TDD you will be writing unit tests as you develop, a few lines at a time.
    • Depending on the size of the script most other developers will be writing a function and then a unit test for it or the whole script and then multiple unit tests. Remember it is better to write the tests while the code is still fresh in your mind.These scenarios work seamlessly if you use Visual Studio with PowerShell tools, Visual Studio will discover your Pester tests and show them in the test explorer.

Side Note: You can also use the tests to make development easier by mocking out infrastructure that is tricky to test like deleting user accounts in AD or deleting VMs.

  • Running tests with a gated checkin. In this case you want VSTS/TFS to run the build and test suite before the code is committed to the main code repository. VSTS/TFS  supports check in policies and one of them requires the build to pass before it is committed.
  • Running the tests after checkin as part of the build process. This is how most developers will run it and although VSTS/TFS doesn’t have native support for Pester tests you can run the tests using a Powershell script. Usually the whole test suite is executed at this point and can include integration tests.

For the last two scenarios to work you have to be able to install the Pester and PSCodeAnalyzer modules as well as any other modules required for your script on the build server. If you are using VSTS hosted build agents this is a bit of a problem since you need administrator access to install modules in the default locations for PowerShell. You can however manually import a module from a local folder during the build process. You can include the modules in you project or store them in a central location or repo and share them between your scripts. Some modules can even be installed from the Marketplace as a build step. If you are hosting your own Visual Studio Agents or using TFS this is not  a problem, you can install them as part of your build server or on demand.

Running A Pester Test
To execute Pester tests you have run a PowerShell script that will call Invoke-Pester. By default Pester will look for all scripts called *.Test.ps1 recursively but you can specify the script to test and even the specific functions in a script. Read the full documentation here.

Retrieving Test Results
Pester can output the test results in NUnit XML consult the documentation for the syntax and output options. VSTS/TFS can display this format on the test results tab. It doesn’t seem to do the same for the CodeCoverage results but you can still attach the output of the code coverage to your build artifacts by using VSTS/TFS commands.

Alternatively you can roll your own test results by passing the -PassThru parameter to Invoke-Pester, this will return the results as a typed object. You can use this to transform the results in any format you want.

Francois Delport

VSTS Sql Server Database Deployment Task

In this post I’ll be having a quick look at the VSTS Sql Server Database Deployment Task. You can find it in the marketplace as part of the IIS Web App Deployment Using WinRM package. It is a bit confusing that you have to look for it under the IIS section not the SQL section in the marketplace.

Take note this task is using WinRm, the instructions to enable it is on the marketplace page and includes a link to a PowerShell script you can run to configure WinRM.

Lets take it for a spin. Follow the installation process from the marketplace to install the extension on your account or download it for on-prem TFS servers. You will see the new WinRM – SQL Server DB Deployment tasks in the Deploy tasks menu.sqlsvsts

Add the task to your deployment and set a few properties, this was quick test I did. You will need a task before this one to copy the dacpac file to a location where the agent can reach it.

SampleConfig

I didn’t have ports open on my firewall for the VSTS hosted agent to reach my machine so I installed the VSTS agent locally and set the task to use localhost. You can specify multiple machines or even use Machine Groups, you will find it in the Test hub in VSTS.

The output from the task doesn’t show much about the actual database changes taking place but you will at least know if the deployment failed.

dacpacoutput

Side Note: Don’t put plain text passwords in your build tasks, use variables and mark them as secret by clicking the padlock icon next to the variable value.

Secret

You can find some more information in the readme file for the task, which they include as a link in error messages when a step fails, which is really helpful.

If you are looking for more information around  continuous deployment of databases have a look at these posts in my continuous deployment of databases series.

Part 1 covers the logic behind the deployment options.
Part 2 covers SqlPackage.exe.
Part 3 covers ReadyRoll.
Part 4 covers FlyWay.

Francois Delport

Visual Studio Team Services Environments And Machines

In my previous post I showed a very simple example using Visual Studio Team Services Release Management albeit to the default environment. In this post I’m going to dive deeper into the concept of Visual Studio Team Services environments and machines.

Environments
When you think of the term environment in the context of deploying software the first thought is usually one or more servers where you deploy your application to. But in VSTS environments are something different and this is bit confusing in the beginning. In VSTS environments are a logical container for a set of variables, approvers, tasks and agent queues etc. I think the most important point is your set of deployment tasks are defined per environment. You have to put some thought into the design of your deployment process to balance the trade off between the re-use of assets and the ease of making changes per environment.

If I contrast the VSTS approach with Octopus Deploy where you have one deployment process, you could craft some control logic using variables, environments and life cycles but it could become very messy and difficult to follow. Changes to your deployment process would impact all the environments using that project making it more cumbersome when you have changes for instance to your dev environment only. This is often the case since you would introduce functionality incrementally per environment from dev to production.

In VSTS you can change the deployment tasks for one environment without affecting other environments but if you have the same change in all environments at once you have to repeat the change for each environment. From experience this should not happen very often since you do it incrementally from dev to production. It will be interesting to see how this plays out in the long run

Also keep in mind how you structure your deployment scripts, ideally you want to have the same script for all your environments but with different parameters passed in for different environments. If you have different logic for each environment it will become a maintenance burden and also leave you open to human error since you will be crafting a script for production that was never tested in dev or qa, missing the whole point of continuous deployment. You can’t  completely escape errors but making changes to production by adding new variables is less error prone than running a new script.

Where do I specify my servers
This leads to the obvious question, where do I specify which servers to deploy to if that is not in my environment. Some deployment tasks have a section for machines where you can provide a comma separated list of machine names or IP address, a variable that will contain the names or a machine group name.

Visual Studio Team Services Environments And Machines

A machine group is a collection of machines, you could make one called Dev for instance and add all you development machines to it. To create machine groups open the Test menu in VSTS and then the Machines sub menu. The machines must have WinRM configured and accessible.

Visual Studio Team Services Environments And Machines

You can also use output variables from steps that create new VMs like the Azure Resource Group Deployment Task and pass those to subsequent steps. Some tasks like Command Line or Batch Script doesn’t have the ability to specify a machine name and they will execute on the server where the agent is hosted. If you really have to use these steps instead of remote PowerShell you can control the agents that are selected using agent queues that are configured at the environment level and agent capabilities that are configured at the agent level.

Links:
VSTS Deployment Guide

Francois Delport

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

In my previous post I showed how to host a private agent to build your solutions on-premise. Today I’m going to show how to release from Visual Studio Team Services to on-premise servers using Web Deploy and a private agent.

Just like the build experience the release management features got an overhaul in VSTS, the previous Release Management product is now rolled into VSTS and TFS Update 2. Most of the current functionality is focused on releasing to Azure but you can use PowerShell or the command line to execute your own install scripts.

For this demo I’m going to release a simple web application using a web deploy package. You could deploy to IIS using remote agent deployment straight from the VSTS servers to on-premise but that is not always possible or allowed in secure environments. When you build a web deploy package the build process will retrieve some settings from you local IIS instance to set some defaults for the package. This won’t work if you use a hosted agent, I’ll be using my private agent for building as well as releasing the web deploy package. In a future post I’ll dive into web deploy in more detail but for now I’ll be using the defaults for deployment since the post is about VSTS release management not web deploy.

Firstly you have to modify your build and pass in the arguments to instruct MSBuild to create the deployment package, as shown here:

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

I’m only interested in the deployment package output from the build process so I’m going to publish the deployment package folder to my artifact output.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

In Visual Studio set your publish settings for the web deployment package, take note of the package location, it is the folder you specified in the artifact publish step and I’m creating it in the root of the solution folder to keep things easy. Check the change in and kick off a build.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

Back in VSTS open the release menu. To create a new release, click on the + sign to create a new release definition and start with a blank definition.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

This demo deployment will have only one step to execute the web deploy package with its default parameters. Click on Add tasks and choose Command Line from the Utility sub section. To get the correct path to the web deploy .cmd file you can browse the artifacts published in the build step. Remember to save the new release definition you created.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

I’ll cover the details of environments and different release types in a future post but for now this will be a manual release to the default environment. Access the context menu for the definition you created and select Release.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

On the next screen accept all the defaults except under artifacts select the latest build of your code and click Create. This will not launch the deployment yet since we are doing it manually. If you look at your list of releases you will see a new release definition. Double click this release and click on the Deploy menu item and deploy to the default environment.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

Once the deployment is completed, you will see the new web application in IIS using defaults picked up from your solution.

This was just one way of many to accomplish on-premise deployments, if you look at the example from MSDN, they are using WinRM and DSC to install IIS, WebDeploy and to install the web app.

Note: On the destination IIS server you also have to take some steps to set up IIS for deployment. You have to install Web Deploy and the easiest way seems to be Web Platform Installer. Also make sure the IIS Management Service feature is installed.

Release From Visual Studio Team Services To On-Premise Servers Using Web Deploy

Francois Delport

Visual Studio Team Services Private Build Agents

In this post I’m going to show you how to use Visual Studio Team Services private build agents. Visual Studio Team Services (VSTS) supports two types of build agents, hosted and private. Hosted agents run on Microsoft servers in the cloud and private agents are hosted by you. When you create your VSTS account you will see two agent pools, Hosted containing your default hosted agent and Default which will be empty. I’ll be adding my private build agent to the Default pool for this demo.

Visual Studio Team Services Private Build Agents

Hosted agents make it easy to get started and work great for building most applications but there are limitations since you have no control over the build server environment, hosted agents can also be used to deploy to Azure. If the VSTS build environment doesn’t meet the requirements for your application build you can host your own build agents in your own environment. These locally hosted agents can also be used to deploy your application locally.

To get started click on the Download agent link in your agent pools control panel, unzip the file and run ConfigureAgent.cmd. Fill in the prompts, they are pretty self explanatory but keep in mind depending on your application your build can get very big and I/O intensive, it could be worth it to put your working directory on a separate drive. If you get stuck the documentation is over here.

If the installation was successful you will see the newly installed agent in your pool.

Visual Studio Team Services Private Build Agents

Note: Initially I installed the agent to run as a service using the default local service account and it worked for most of my applications but I had one build that required running as a specific user account. As per the documentation I used the “C:\Agent\Agent\VsoAgent.exe /ChangeWindowsServiceAccount” command from an elevated command prompt to change the service account but that didn’t work. The service didn’t update with the new credential and the agent showed as off line in VSTS.

To fix the problem I had to run “C:\Agent\ConfigureAgent.cmd” again specifying the new account name and then it worked.

Next step is to configure certain builds to use my on-premise agent by default since the build won’t work using the hosted agent. The simplest but least dynamic way is the set the build to only use agents from a specific pool. In this example I set the build to use the Default pool.

Visual Studio Team Services Private Build Agents

You can for instance limit builds that take very long to a certain pool so they won’t prevent other applications from building. Depending on the complexity of your environment and projects it would be better to use demands and capabilities as well. On your agent there is a list of capabilities and you can add custom ones, in this case I called the capability OnPrem.

Visual Studio Team Services Private Build Agents

In my build definition I can now specify the agent to be used for building must meet this demand.

AgentDemand

Now it will choose an agent from the pool that satisfies the demand. If you create a rule that cannot be satisfied, you’ll get this error message to warn you or else your build would just be stuck.Visual Studio Team Services Private Build Agents

Free VSTS accounts include one free private agent and charge $15 per agent there after. Even if the hosted agent is able to build your application look into the private agents, depending on the machine hosting the agent, your build can be a lot faster.

Francois Delport

Building A MVC3 Project In Visual Studio Team Services/TFS 2015

In this post I’m going to cover building a MVC3 project in Visual Studio Team Services/TFS 2015.

With the release of Team Foundation Server 2015 Microsoft overhauled the build experience with a completely new build server. The new build experience is way better than the old XAML build and I decided to take it for a spin and share some of the problems or gothas I came across.

There are tons of demos on building MVC projects most of which start with a new MVC project but I wanted to try it out with something more realistic and decided to use a very old MVC3 project I have that has never been successfully built on a build server before. This meant quite a few errors along the way I had to fix first but it didn’t take very long and everything worked fine in the end.

If you want a step by step introduction read this, I will mostly be focusing on the deviation from the happy path in this post and documenting the steps to fix it in case I need it again one day.

First lesson
The retention policy for your builds is 10 days by default so I lost all the build logs from my old builds containing the error message before I got around to writing this post. So most of what I’ll be writing is from memory without screenshots.

Second Lesson
I got this error while restoring packages during the build:

The process cannot access the file NuGet.exe because it is being used by another process.

To fix it was very simple, just update the nuget.exe file in your solution to the newest version.

Third Lesson
I’m using a nuget repository that requires authentication and if you try to run a build you will get error message that it can’t find your packages. To resolve this issue you have to store the credentials in nuget.config for the build server to be able to authenticate against your nuget repository. To do that use the following command:

nuget sources add -Name "YourFeed" 
-source "https://urltonuget/nuget" 
-User username -pass password 
-configFile "Path\To\nuget.config" -StorePasswordInClearText

Sadly this will store it as clear text but the encrypted credentials will only work on the same machine where it was encrypted so you won’t be able to use it on the build server.

Fourth Lesson
In this project all the packages were checked into source control, this is not good practice, it takes up lots of space, pollutes your repository and downloading the project from VSO takes a lot longer. To prevent this from happening use .tfignore files. In this case I placed the file in the root of my project.

Building A MVC3 Project In Visual Studio Team Services/TFS 2015

The contents of the file is very simple.

\packages
!\packages\repositories.config

This will ignore the contents of the packages folder but not the repositories.config since we still need it.

Fifth Lesson
It is also not good practice to include your bin folder in source control, rather use nuget for all your dependencies, in this project which was always built locally all the developers had MVC3 installed on their machines. The project failed to build on the build server since it didn’t (and shouldn’t have MVC3 installed). The fix for this is very simple, install MVC3 as nuget packagein your web project.

Install-Package Microsoft.AspNet.Mvc -Version 3.0.50813.1

Sixth Lesson
Build definitions can become very complex and it is easy to mess it up, luckily VSO will keep track of the changes made to your build definitions, you can even do a diff to see the exact changes. It is like a mini source control for your build definitions.

Building A MVC3 Project In Visual Studio Team Services/TFS 2015

Francois Delport