VSoft Technologies Blogs

rss

VSoft Technologies Blogs - posts about our products and software development.


One of the most asked for features in Continua CI 1.0 was the ability to control which stages run, ie the ability to skip stages dynamically, based on what happened earlier in the build, and to be able to control whether the build should continue on to the next stage or wait for user intervention.  In Continua CI 1.5, we made this possible with Skip and Promote Conditions.

Skip Conditions

Skip Conditions allow you to controll whether a Stage is skipped or run based on expressions. All the expressions must evaluate to true for the stage to run (if there are no expressions then the stage will not be skipped). 

Skip Conditions

In the above example, we have a Stage called Obfuscate, and we want it to be skipped if you turn off obfuscation (by setting a variable) or if we are not deploying a build (again, controlled by a variable). You can also disable a stage completely so it is always skipped.

Promote Conditions

In Continua CI 1.0, you can chose if the next Stage is automatically run, or the builds stops and requires a manual promotion to continue to the next Stage. In Continua CI 1.5, Promote Conditions allow you control whether to automatically promote or not, based on expressions.  All the expressions must evaluate to true for the build to continue to the next stage (if there are no expressions then the build will stop with a status of waiting for promotion). 

Skip Conditions

In the above example, our build will continue on to the next Stage if the Deploy variable is set to true. 

Continua CI 1.5 is currently in Beta - you can get it here :
http://www.finalbuilder.com/downloads/continuaci/continuaci-beta-version-history 

So you've got your Continua CI server set up to automatically build, run unit tests and produce reports for your awesome new web application. Now you're ready to try out your project in its natural environment and then eventually release it to the wild for well-deserved public applause.

Up until now, your options were either to use a Copy action to push the files up to test server and a PowerShell action to set up web services, or preferably run a FinalBuilder script utilising the plethora of actions available for transferring files and interacting with web servers.

As of version 1.5, Continua CI can also work together with Octopus Deploy server to provide an end-to-end continuous delivery mechanism. Using the new build event handlers feature, Continua CI builds can now be set up to create Octopus Deploy releases and initiate deployment to test and production environments, at key points in the build process.

This post will walk through the steps required to push a .Net web application built in Continua to Octopus Deploy and trigger a deployment process to effortlessly get your application running on your test and production servers.

Preparing your solution


Octopus Deploy requires that you provide your applications as NuGet packages. You can create and push the package to the Octopus Deploy server using Nuget Pack and Push actions, or create and push an OctoPack from MSBuild or VisualStudio build runner actions.

Lets go with the recommended OctoPack option. First prepare your Visual Studio solution - use the NuGet package manager to install the OctoPack package into the projects you want to deploy. This will include web application projects, console application projects and Windows service projects but not class libraries and unit test projects.



You can now optionally add a .nuspec file to the root folder of your project to describe the contents of your package. If you don't provide a .nuspec file, OctoPack will automatically create one based on your project settings.



Setting up the deployment process


Next head over to your Octopus server and set up a deployment project. This should include a “Deploy a NuGet package” process step as below.



We will set this to retrieve the application package from the built-in NuGet feed. Note that the NuGet package id should match the id element in your .nuspec file - this will default to the name of your assembly.

We added a few more steps:



And some variables:



Setting up the build process


You can now get back to Continua and set up a configuration for building your project. Once you have entered the configuration details and linked up the repository containing your project, move on over to the Stages page:



For this simple example you'll need two actions: a NuGet Restore action to ensure that the OctoPack package is available for the build and an MSBuild action to build and push the application to your Octopus Deploy server.
Just enter the path to your solution for the NuGet Restore action (the other fields can be left as is) and complete the main tab of the MSBuild action as required for your project.



You then need to enter some additional properties to tell MSBuild to run OctoPack and tell it where to send your package.



Set the RunOctoPack property to true and the OctoPackPublishPackageToHttp property to the URL for the NuGet feed on the Octopus Deploy server e.g. http://octopusserver/nuget/packages.

You will also need to provide an OctoPackPublishAPIKey property – you can generate an API key on your profile page on the Octopus Deploy server.

Optionally, you can  use the OctoPackPackageVersion to specify up the package version. Here we use Continua expressions to set this based on the build version. If you leave this out then OctoPack will get this value from the AssemblyVersion property in your AssemblyInfo.cs file.

Once the actions are set up and saved, run a build and check that your package gets uploaded to the Octopus Deploy server. Then create a release for your deployment project and test that it deploys ok. Now we are ready to look into how to run this process automatically from Continua CI.

Build event handler


On the Continua CI configuration wizard after Stages, we have a new area titled Events. Here you can add Build Event Handlers for tagging repository changesets, updating the GitHub status and interacting with Octopus Deploy.

Create a new build event handler, give it a name and select the Octopus Deploy as the Type.




You can now provide general project details under the Octopus Deploy tab.



The Octopus Deploy URL should end with '/api' e.g. http://octopusserver/api. Enter the API key generated under your Octopus Deploy profile and the name of your deployment project.
  
You can then choose one or more actions to run. The available options are Create, Deploy and Promote and are used to create a new deployment release, deploy a release to an environment and promote a release from one environment to another. As you select each action, new tabs open so you can provide further details and hook the action to a build event.

Creating a release


Before you can deploy an application you need to create a Octopus Deploy release




When creating a release you can specify the Release Version or leave this blank to automatically create a number based on the highest package version. You must provide either a Default Package Version or Step Package Versions for each step which requires one e.g.




Flip over to the Create Options tab to tell Continua when to create the release.




There are six Build Events available to choose from. Some allow you to select a Stage and some allow you to select a successful or failed Build Status

  • On Before Stage Start
  • On Sending Stage To Agent
  • On Stage Completed
  • On Build Pending Promotion
  • On After Build Continued
  • On Build Completed

Generally we want to create the release at the start of the build before the first stage starts.

Deploying to an environment


Now on to the crux of this whole process - deploying your application. We generally deploy to a Test environment first and then, once we are happy with the outcome, promote to a User Acceptance environment or directly to Production. Continua CI allows you to deploy a release previously created by a Create action in the same build event handler, the highest release version in the project or a specific release version. It's up to you to ensure that the release version exists before the deploy action is run. An environment can consist of multiple machines - you can specify which machines you want to deploy to. If no machines are specified then the release will be deployed to all machines in the environment.





When selecting the Build Event for deployment, ensure that it is triggerred after the package has been built and pushed to the Octopus Deploy server. Here we have set this to be run once the Build stage has completed successfully.



Promoting a release


You can promote the latest release from one environment to another. Ideally this would be linked to the promotion of a stage e.g. a testing stage, so that the application can be promoted from a test environment to production environment.



We have set our test stage to require manual promotion;




and set our promote action to run when a build is continued after waiting for promotion.



Variables


You can also pass variables from Continua CI to your deployment, these will be sent to the Octopus Deploy server before each action is run, updating the variables for the deployment project. We have used expressions is this example to send the build versions number and branch name. These variables can then be used to update project files with details for display or configure services differently depending on the source of the project.



Running the configuration


Once your build event handler dialog has been completed and saved, its time to start running the configuration. As the build processes Continua CI will display status information mirroring the process running on Octopus Deploy.



You can also see full details of the deployment process in the build log.



And all going well you will now see a successful deployment on your Octopus Deploy server!








With the upcoming 1.5 release of ContinuaCI  we have made a number of enhancements to the dashboards, we think you'll love them!  Here is a peek at what's coming soon.

The New List View

all-projects-listview

Improvements:
  • - Stage indicator blocks provide quick drill-down into the build log.
  • - Improved viability and responsiveness of build actions buttons.
  • - Build action buttons moved to the left for easier access.
  • - Viability enhancements around projects.
  • - Improved Responsiveness and performance tweeks.

List View: With Builds Completed

all-projects-listview-completed-builds

List View: With Builds Running

all-projects-listview-completed-multibuilds

The New Details View

details-view

Improvements:
  • - Build and Queue times now have graphs!
  • - Build status card on the left hand side displays the status of the build as it progresses.
  • - Build action buttons are more obvious and responsive.
  • - Stage indicator blocks (present on the build status cards) provide quick drill-down into the build log.
  • - Improved Responsiveness and performance tweeks.

Details View: with Builds Queued

details-view-queued

Details View: with Builds Executing

details-view-building

Details View: with Builds Finished

details-view-finished

Stay tuned for more exciting details regarding the version 1.5 release!




Automated UI Testing Done Right with ContinuaCI

You have just completed an awesomely complex change to your shinny new webapp!  After running all your unit tests things are in the green and looking clean.

Very satisfied at the quality of your work you fire up the application to verify that everything is still working as advertised.  Below is what greets you on the root path of your app: 

Funny error

We have all been here at some time or another!  What happened!  Perhaps it was not your code that broke it!  Maybe the issue originated from another part of your organisation, or maybe it came from somewhere on the "inter-webs".  

Its time to look at the underlying problem however .....  testing web user interfaces is hard!  Its time consuming and difficult to get right.  Manual clicks, much typing, cross referencing client specifications etc, surely there must be an easier way.  At the end of the day we DO need to test our user interfaces

Automated Web UI Testing


Thankfully UI testing today can be Automated, running real browsers in real end to end functional tests, to ensure our results meet (and continue to meet) expectations.     

For the sake of brevity and clarity in this demonstration we will focus on testing an existing endpoint.  It is considered common place to find functional tests included as part of a wider build pipeline, which may consist of such steps as: 

  • Build
  • Unit Test
  • Deploy to Test Environment
  • Perform Functional Tests
  • Deploy to Production

In this article we will be focusing on the functional testing component of this pipeline.  We will proceed on the assumption that your code has already been, built unit tested and deployed to a Functional Test environment. Today we will;

Add Automated UI testing to an existing endpoint google.com
Configure ContinuaCI to automatically build our project, and perform the tests

Software Requirements: 


Step1: Prepare a Selenium endpoint

Firstly we will prepare for our UI tests by setting up a Selenium server.  Selenium is a browser automation framework which will be used to 'remote control' a real browser.  This machine will be designated for performing the UI tests against, preferably this will be a machine separate from your ContinuaCI server.

Log into the machine you have chosen for the Selenium server with administrator privileges
Download and install Mozilla Firefox (getfirefox.com), this will be the browser that we target as part of this example, however Selenium can target lots of other browsers.  For a full breakdown please see the docs page: .
Download Selenium Server (docs.seleniumhq.org/download), at the time of writing the latest version is 2.41.0.

Place it into a permanent location of you choosing, in our example ("C:\Program Files (x86)\SeleniumServer")     
Download NSSM (nssm.cc/download), unzip it and place into a permanent location of you choosing "C:\Program Files (x86)\nssm-2.22\"

Ensure that port 4444 is set to allow traffic (this is the default communications port for Selenium) 

Open a console and run the following commands: 
"C:\Program Files (x86)\nssm-2.22\win64\nssm.exe" install Selenium-Server "java" "-jar \"C:\Program Files (x86)\SeleniumServer\selenium-server-standalone-2.41.0.jar\""
net start Selenium-Server


name project
 
In order to uninstall the Selenium server service, the following commands can be run: 
net stop Selenium-Server
"C:\Program Files (x86)\nssm-2.22\win64\nssm.exe" remove Selenium-Server


name project

Step2: Create a test class and add it to source control

Create a new class library project in Visual Studio,  lets call it 'tests'
Open the Nuget Package Manager Console window (tools menu-> library package manager -> package manager console), select the test project as the default project and run the following script: 

Install-Package Selenium.Automation.Framework
Install-Package Selenium.WebDriver
Install-Package Selenium.Support
Install-Package NUnit
Install-Package NUnit.Runners

Create a new class called within the tests project (lets call it tests) and place the below code (Note: line 23 should be changed with location to the Selenium-Server we setup in the previous step):

using System;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumTests
{
    [TestFixture]
    public class test
    {
        private RemoteWebDriver driver;
       

        [SetUp]
        public void SetupTest()
        {

            // Look for an environment variable
            string server = null;
            server = System.Environment.GetEnvironmentVariable("SELENIUM_SERVER");
            if (server == null)
            {
                server = "http:// *** PUT THE NAME OF YOUR SERVER HERE ***:4444/wd/hub";
            }
            
            // Remote testing
            driver = new RemoteWebDriver(new Uri(server), DesiredCapabilities.Firefox());
        }

        [TearDown]
        public void TeardownTest()
        {
            try
            {
                driver.Quit();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
        }

        [Test]
        public void FirstSeleniumTest()
        {
            driver.Navigate().GoToUrl("http://www.google.com/");
            IWebElement query = driver.FindElement(By.Name("q"));
            query.SendKeys("a test");
            Assert.AreEqual(driver.Title, "Google"); 
        }
       
    }
}

Step3: Test the test!

Build the solution 
Open NUnit build runner (by default this is located at ~\packages\NUnit.Runners.2.6.3\tools\nunit.exe) , Select file -> Open Project, and locate the tests dll that you have build in the previous step
click the run button
~ 15 seconds or so you should have one green test!

name project

So what just happened?  Behind the scenes an instance of firefox was opened (on the Selenium Server), perform a simple google search query and undertook a simple Nunit assertion has verified the name of the window was equal to "Google", very cool!.  

Now lets make the test fail, go ahead and change line 78, lets say "zzGoogle", build, and rerun the test.  We now have a failing test.  Go ahead and change it back so that we have a single passing test.

name project

Create a source control repository

In this example, we're using mercurial

open a command prompt at ~\
type "hg init"
add a .hgignore file into the directory.  For convenience we have prepared one for you here 
type "hg add"
type "hg commit -m "initial commit""

Step 4: Setting up Automated UI testing in ContinuaCI

Navigate to the ContinuaCI web interface

Create a project


Open ContinuaCI
Select "Create Project" from the top tasks dropdown menu

create project

Name the project something memerable;  In our case: "pete sel test 1"
name project
Click the "Save & Complete Wizard" button

Create a configuration for this project


Click "Create a Configuration"
Name the config something memorable; in our case "sel-testconfig-1"
Click save & Continue
Click the 'Enable now' link at the bottom of the page to enable this configuration

Point to our Repository


under the section "Configuration Repositories", select the "Create" link

name project

Name the repository "test_repo"
Select "Mercurial" from the "type" dropdown list

name project

Select the Mercurial" tab from the top of the dialogue box
Enter the repository location under "source path"  in our case '\\machinename\c$\sel-blog-final'
Click validate to ensure all is well

name project

Click save, your repository is now ready to go!
name project

Add actions to our build


Click on the Stages tab
We will add a nuget restore action, click on the "Nuget" section from the categories on the left
Drag and drop the action "Nuget Restore" onto the design surface
Enter the location of the solution file: "$Source.test_repo$\tests.sln"

name project

Click Save
 

Build our tests


Click on the "Build runners" category from the categories on the left hand menu
Drag and drop a Visual Studio action onto the design surface (note that the same outcome can be achieved here with an MSBuild action).


name project

name project

Enter the name of the solution file: "$Source.test_repo$\tests.sln"
Specify that this should be a 'Release' build under the configuration option
Click save

Setup ContinuaCI to run our Nunit tests


Select the 'unit testing' category from the left hand menu
Drag and drop an NUnit action onto the design surface

name project

Name our action 'run UI tests'
Within the files: option, specify the name of the tests project '$Source.test_repo$\tests\tests.csproj'
Within the Project Configuration section specify 'Release'
Specify which version of NUnit
In order to provide greater configuration flexibility  we can pass in the location of our Selenium server to the tests at runtime.  This is done within the 'Environments' tab.  In our case the location of the Selenium server is http://SELSERVER:4444/wd/hub.

environment tab

Click Save

Click save and complete Wizard
We are now ready to build!

Start a build immediately by clicking the top right hand side fast forward icon 

name project
A build will start, and complete!

name project
When viewing the build log (this can be done by clicking on the green build number, then selecting the log tab) we can see that our UI tests have been run successfully.  They are also visible within the 'Unit Tests' tab which displays further metrics around the tests.

name project

name project

Step 5: Getting more advanced

Lets try a slightly more advanced example.  This time we will examine a common use case.  A physical visual inspection test needs to be conducted before a release can progress in the pipeline.

Place the following code within our test class.

using System;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumTests
{
    [TestFixture]
    public class test
    {
        private RemoteWebDriver driver;
       

        [SetUp]
        public void SetupTest()
        {

            // Look for an environment variable
            string server = null;
            server = System.Environment.GetEnvironmentVariable("SELENIUM_SERVER");
            if (server == null)
            {
                server = "http:// *** PUT THE NAME OF YOUR SERVER HERE ***:4444/wd/hub";
            }
            
            // Remote testing
            driver = new RemoteWebDriver(new Uri(server), DesiredCapabilities.Firefox());
        }

        [TearDown]
        public void TeardownTest()
        {
            try
            {
                driver.Quit();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
        }

        [Test]
        public void FirstSeleniumTest()
        {
            driver.Navigate().GoToUrl("http://www.google.com/");
            IWebElement query = driver.FindElement(By.Name("q"));
            query.SendKeys("a test");
            Assert.AreEqual(driver.Title, "Google"); 
        }
        [Test]
        public void MySecondSeleniumTest()
        {
            // Navigate to google
            driver.Navigate().GoToUrl("http://www.google.com/");
            IWebElement query = driver.FindElement(By.Name("q"));
            
            // Write a query into the window
            query.SendKeys("a test");

            // wait at maximum ten seconds for results to display
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
            IWebElement myDynamicElement = wait.Until< IWebElement >((d) =>
            {
                return d.FindElement(By.Id("ires"));
            });

            // take a screenshot of the result for visual verification
            var fileName = TestContext.CurrentContext.Test.Name + "-" + string.Format("{0:yyyyMMddHHmmss}", DateTime.Now) + ".png";
            driver.GetScreenshot().SaveAsFile(fileName, System.Drawing.Imaging.ImageFormat.Png);

            // perform an code assertion
            Assert.AreEqual(driver.Title, "Google");          
        }
    }
}


Build, and run the test.  

In this example we added an additional test to perform a google search, wait at maximum 10 seconds for  results to display, take a screenshot (stored it to disk), and perform an NUnit assertion.  The screenshot output from the test can be made available as an artifact within Continua!

Firstly lets commit our changes; "hg commit -m "added a more advanced test""

Open the configuration in Continua CI (clicking the pencil icon)
Navigate to the stages section 
Double click on the stage name (which will bring up the edit stage Dialogue box) 
Click on the Workspace rules tab
Add the following line to the bottom of the text area: "/ < $Source.test_repo$/tests/bin/Release/**.png".  This will tell Continua to return any .png files that we produced from this test back to the ContinuaCI Server.

name project

Click on the artifacts tab.
Add the following line : **.png"  This will enable any .png files within the workspace to be picked up and displayed within the Artifacts tab.
**.png
name project

Click save
Click Save & Complete Wizard
Start a new build


name project

Sweet!  A screenshot of our test was produced, and can be seen within the Artifacts tab!     

name project
Clicking on 'View' will display the image:  

name project
 
We have put the sourcecode of this article up on Github.

Please subscribe and comment!  We are very excited to see what you guys come up with on Continua, happy testing!

Some additional considerations:


  • The user which the Selenium service runs under should have correct privileges
  • The machine designated as the Selenium server may require access to the internet if your webapp has upstream dependencies (eg third party API's like github)
  •   

SmartBear recently discontinued development of Automated Build Studio and deleted pretty much all references to it from their website.

Within hours of the smartbear email going out to ABS users, we started getting questions about crossgrade discounts, and we're more than happy to help.  

If you are an ABS user, contact us (sales @ finalbuilder.com ) with proof of purchase (invoice) for ABS and we'll provide you with a 50% off discount coupon for FinalBuilder 7 Professional Edition. 

This is a limited time once only offer, valid until May 15th 2014.  Spread the word to your fellow ABS users. 

While you you are checking out FinalBuilder, be sure to take a look at our Continuous Integration Server product, Continua CI. It's vastly superior to the CI features in ABS, but still allows you to create your build process using a visual build tool (FinalBuilder).