Monday, 29 February 2016

Unit Test for ASP.Net 5 with xUnit

Unit testing plays a significant role in assuring the quality of the applications we develop. To unit test an ASP.Net 5 RC1 Update1 (ASP.Net Core 1.0 now), web application we can use xUnit.
To add xUnit test to the solution add a Class Library (Package) project.image
image
Edit the default project.json shown below.image
Add dependency to the ASP.Net 5 web project, and to xUnit and xUnit.Runner.Final project.json should be similar to below.image

{
  "version": "1.0.0-*",
  "description": "BookMyEvents.UnitTests Class Library",
  "authors": [ "Chaminda" ],
  "tags": [ "" ],
  "projectUrl": "",
  "licenseUrl": "",

  "dependencies": {
    "BookMyEvents": "1.0.0-*",
    "xunit": "2.1.0",
    "xunit.runner.dnx": "2.1.0-rc1-build204"
  },

  "commands": {
    "test": "xunit.runner.dnx"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": {}
  }
}
Once the project.json saved the references get updated.image
Let’s write a test for a very simple controller method.image
Test method as a Fact (There are two types of Unit Tests in xUnit. Fact and Theory. More information here).image
Go to test explorer in VS to view the test.image
image
If you cannot see test as above build your solution. Test will be then available in the explorer. Execute and you can see the results.image
Next post let’s learn how to run the unit tests (xUnit), with VS Team Service build and publish test results.

Wednesday, 17 February 2016

ASP.Net 5 (RC1 Update1) Deploy to Azure Website with Visual Studio Team Services Release

How to setup a build with Visual Studio Team Services, for building ASP.Net 5 (ASP.Net Core 1.0 now) is explained in here. Let’s look at steps necessary to create a release pipeline to deploy, ASP.Net 5 website to Azure, with VS Team Service Release.
First requirement is to develop a poweshell script, whcih is capable of deploying, the built ASP.Net package to Azure. Information on how to write such script is available here.image
Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
param($websiteName, $packOutput)

$website = Get-AzureWebsite -Name $websiteName

# get the scm url to use with MSDeploy.  By default this will be the second in the array
$msdeployurl = $website.EnabledHostNames[1]


$publishProperties = @{'WebPublishMethod'='MSDeploy';
                        'MSDeployServiceUrl'=$msdeployurl;
                        'DeployIisAppPath'=$website.Name;
                        'Username'=$website.PublishingUsername;
                        'Password'=$website.PublishingPassword}


$publishScript = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\Publish\Scripts\default-publish.ps1"


. $publishScript -publishProperties $publishProperties  -packOutput $packOutput
Add this script to version control.image
Modify our release build in previous blog to copy deploy script to build output.image
image
image
Let’s create Azure Web Application as the target.image
image
Site created and ready.image
In Visual Studio Team Services, Release tab create a new empty Release Definition.image
image
To link the release definition to the build created earlier, click on Link to a build definition.image
Select the build definition and link it to release definition.image
Rename the Default Environment to DevInt(Or what ever name you prefer).image
In the DevInt environment create a configuratoin varibale to hold the Azure web site name.image
image
It is possible to set approvers to the stage. So that an approval requires to get the build deploy to the stage/environment DevInt. Let’s set it to autimated and after deployment set a manual approval, to allo get it approved before deploying to next stage/enviornment in the pipeline.image
image
In the release definition add a Azure Powershell task to execute the deployment script. Azure subscription how to link to VS Team Services account can be found here. Set the deployment script to Azure Powershell release task in Dev Intimage
image
For Web Site Name environment variable can be used in the cript arguments.
-websiteName $(WebSiteName) -packOutput $(System.DefaultWorkingDirectory)\Event.Rel\EventRelOutput\image
Eventhough trigger can be set to continuous deployment like below.image
Let’s leave trigger to manua for the time being.image
Now you can trigger a release with the any successful build output you have using the release definition.image
image
image
Build get deloyed to DevInt environment and wait for the post deployment approval.image
DevInt environment site is running now.image
An Improvement to the build number can be made like following.image
Release name format also can be set to use build number for it to be more meaningful.
Release No $(Build.DefinitionName)-$(Build.BuildNumber)-R-$(rev:r)image
Multiple environements in the pipeline can be configured.image
Deployement logs in the pipeline. You can view these logs, while a release is happening.image
Release history can be viewed.image
Release definition change history is available as well t diagnose any issue which might have ocuured with a change to the definition.image
Difference between two defnitions.image
image
New release managment services with VS Team Services is awsome, and let’s explore more in the coming posts.

Tuesday, 2 February 2016

Build ASP.Net 5 (RC1 Update1) Project with Visual Studio Team Services Build

Building ASP.Net 4 MVC witth VS Team Services Build and deploying it to Azure web site with VS Team Services Release, is somewhat straight forward. But building an ASP.Net 5 MVC 6 (EF 7) web application with VS Team Services hosted build services, and deploying it with VS Team Services Release, requires some addtional steps.

(Asp.Net 5 is now no more and named as ASP.Net Core 1.0. It is a name change and still the ASP.Net 5 RC1 Update1 is the available version. ASP.Net Core 1.0 is not released yet.)

Let’s look at steps required to build ASP.Net 5 RC1 Update1, MVC 6 web application with Visual Studio Team Services build.

Simple web application with ASP.Net 5 should be created and checked in to TFS.image

CI Build

First try to create a CI build which builds each changeset checked in. Create a build definition and add a Visual Studio Build step.image

When a build is triggered with above defintition it fails giving below error.

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DNX\Microsoft.DNX.targets(126,5): Error : The Dnx Runtime package needs to be installed. See output window for more details.image

This is because hosted build server does not have dnx Runtime packages available in it. As explained in article here use the script to download the required packages before build. Slight modification done to support the releative path of the project, with the location of the script in the verision control.image

image

A gobal.json file added to supply the dnx version that is required to dnu restore.image

image

A new build step should be added to execute the Pre Build script, to install the dnx packages using dnu restore.image

Dnx packages (rc1 update1) get installed with the pre build step. image

But the build step still look for beta8 of dnx packages, and dnu restore does not seem to be working.image

To install the latest dnx in the hosted build server, add to “dnvm upgrade -r clr” Pre Build script.image

Because of a missing mistake in the path of the project.json location, in the script below error occured.

CS0234: The type or namespace name 'AspNet' does not exist in the namespace 'Microsoft'image

This error fixed by making sure relative path to the is correct.image

Final script here.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# bootstrap DNVM into this session.
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}

# load up the global.json so we can find the DNX version
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore

if($globalJson)
{
    $dnxVersion = $globalJson.sdk.version
}
else
{
    Write-Warning "Unable to locate global.json to determine using 'latest'"
    $dnxVersion = "latest"
}

# install DNX
# only installs the default (x86, clr) runtime of the framework.
# If you need additional architectures or runtimes you should add additional calls
# ex: & $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -r coreclr
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent

# run DNU restore on all project.json files in the src folder including 2>1 to redirect stderr to stdout for badly behaved tools
Get-ChildItem -Path $PSScriptRoot\..\..\EventBooking -Filter project.json -Recurse | ForEach-Object { & dnu restore $_.FullName 2>1 }

dnvm upgrade -r clr

Then works dnu restore and build succeeds.image

image

With CI build the build output is not made available. But for release bbuild we need artifacts to be able to downloaded and deployed with Visual Studio Team Services Release.image

Release Build and Publich Artifacts

Let’s clone this CI build and create a release build. The steps to publish build artifacts for an ASP.Net 5 application is explained here. Using the script available in the article, a modification added to make it work without having a Team Project namea and releative path to project is set.image

Modified script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
param($projectName, $buildConfiguration, $buildStagingDirectory)
 
$VerbosePreference = "continue"
$ErrorActionPreference = "Stop"
     
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore
 
if($globalJson)
{
    $dnxVersion = $globalJson.sdk.version
}
else
{
    Write-Warning "Unable to locate global.json to determine using 'latest'"
    $dnxVersion = "latest"
}
 
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent
 
$dnxRuntimePath = "$($env:USERPROFILE)\.dnx\runtimes\dnx-clr-win-x86.$dnxVersion"
     
#& "dnu" "build" "$PSScriptRoot\src\$projectName" "--configuration" "$buildConfiguration"
Write-Warning "Path is $PSScriptRoot\..\..\EventBooking\$projectName"
 
& "dnu" "publish" "$PSScriptRoot\..\..\EventBooking\$projectName" "--configuration" "$buildConfiguration" "--out" "$buildStagingDirectory" "--runtime" "$dnxRuntimePath"

THis script is added to source control to a Post Build script folder.image

A build post step added to execute the post build ASP.Net 5 publish step and below arguments passed to script.

-projectName "BookMyEvents" -buildConfiguration $(BuildConfiguration) -buildStagingDirectory $(build.stagingDirectory)

$(build.stagingDirectory) is temporary location to publish and it is a predefined agent build variable.image

image

Above will publish the ASP.net 5 application but it is not available to download yet.To get the published output available to download, add Copy and Publish Build Artifact step. For this specify the $(build.stagingDirectory) as the Copy Root and provide an Artifact Name. Set the Artifact Type to Server.image

Downloaded build artifact containes the published ASP.Net 5 application.image

image

image

In the next post let’s look at how to get the ASP.Net 5 RC1 Update 1 application, deployed as Azure web application using Visual Studio Team Services Release.