Archive for the ‘.net’ Category.

C# Selenium Integration Tests using Chrome Ghost PhantomJs headless driver

A lot has changed since my last post using Selenium to test web pages. Then you had to install a few things both on the client, browser and server. Today it has been simplified a lot. All you need really is the webdriver and you are in business. You can use the webdriver on your development machine and the server machine as well to run the Selenium tests. In my case I’m using the Ghost-PhanthomJS webdriver as I need to do headless testing ( no GUI ). Since it’s a lot harder to run tests automatically on the server if there is need for GUI, it will complicate things a lot, has to do with security restrictions etc.

Lets take a look at what is needed.
Create a new C# project in VS

Install xUnit Package Manger Console in VS using nuget.
Note I’m specifically using 1.9.2 and 2.0 as I know these two work on the build machine, I had trouble with other version combinations.
PM> Install-Package xunit -Version 1.9.2
Install xUnit VS Runner
PM>Install-Package xunit.runner.visualstudio -Version 2.0.0

Install the Chrome webdriver and libraries
PM> Install-Package WebDriver.ChromeDriver

Install the PhantomJS headless driver and libraries
PM> Install-Package PhantomJS

Then we write the test that will run after the build does the web deployment to the local server. The sample below just loads google.com and checks for the title, then shuts down.

//
using System;
//
using Xunit;
//
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.PhantomJS;

namespace IntegrationTesting
{

    public class HelloIntegration
    {
        // Proofs that google can be pulled up in the browser and has the right title
        [Fact]
        public void GoogleCheckTitle()
        {
            // Init
            IWebDriver driver = new PhantomJSDriver();

            // Test
            driver.Navigate().GoToUrl(“http://www.google.com”);
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3));
            var title = driver.Title;

            // Proof
            Assert.Equal( “Google”, title);

            // Close down
           driver.Quit();

        }
    }
}

If you are using TFS you also need to point your build agent to the xUnit runner, in my case I just check it in as part of the project and set it like that.
Path to custom test adapters
$(Build.SourcesDirectory)\TestWebSite\xunit_runner\

That’s all you need, then you can write your own tests to test specific functionality tailored to your needs. Selenium is pretty powerful for Integration testing.

msTest Initialization UnitTest Framework error – No types found implementing

I started getting the following error when running specific UnitTests on the server, and only on the server. Running the tests from Visual Studio both using msTest and TestDriven was fine. But obviously something was missing. The good part about using different runners to run tests is that you often find niche cases that you would have otherwise missed. I was able to duplicate the behavior using msTest from the command line on the development machine. Then I noticed that when msTest runs it creates a whole new directory for each run ( based on timestamp ) in order to run the tests in isolation. I started to realize my problem as the files needed for the test need to be copied to the new directory. As I was using reflection to load some of the dlls msTest would have no instructions that I needed those dlls to be copied over as well.

Initialization method Framework.Conventions.UnitTests.ConventionAdapterExtensionsTests.Initialize threw exception. Framework.FrameworkUsageException: Framework.FrameworkUsageException: No types found implementing IConventionAdapterProvider.

The trick is to declare the needed dlls as deployment items for your UnitTests test class and you are in business. In my case I needed these three dlls.

[DeploymentItem(“Framework.Compiler.dll”)]
[DeploymentItem(“Framework.Conventions.Compiler.dll”)]
[DeploymentItem(“Framework.Logging.dll”)]
[TestClass]
public class ConventionAdapterExtensionsTests
{

Log4Net configuration and scope extension

I had the need to setup Log4Net logging in a new project the other day. It is fairly easy to setup, just add the listeners you want in the configuration files. Then use it, of course you get most things for free the log level etc. We also wanted to make it super easy to use Scope, so I added a LogExtension that takes care of that. The idea is if you forget to close the scope it will be automatically done once the scope object gets garbage collected. Below is example code including UnitTests.

logger_sample

Could not load type Microsoft.VisualStudio.Services.Common.VssHttpClientBase

If your getting the following error on your TFS server web interface odds are that you are using incompatible version between TFS and VS or other Microsoft product. The object in question was moved from the common Dll to another. In my case I installed TFS RC and then never version of VS2013, after that I got the error.

Could not load type ‘Microsoft.VisualStudio.Services.Common.VssHttpClientBase’ from assembly ‘Microsoft.VisualStudio.Services.Common, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’.

To remedy the situation I upgraded TFS 2013 with the RTM version. After the upgrade I’m not getting the error anymore ant the TFS web interface works as expected.

Chocolatey

I played with Chocolatey today, I figured lets create an package to setup a development machine. Add handy packages that you might want starting out on a new machine. This is handy as well when you have a new developer joining your team, you can set them up with some common tools.

First create the spec file as below

<?xml version=“1.0”?>
<package>
  <metadata>
    <id>SoftwareCreations.devset</id>
    <title>SoftwareCreations.devset</title>
    <version>0.09</version>
    <authors>Orn Kristjansson</authors>
    <summary>Software Creations, installs dev tools.</summary>
    <owners>Orn Kristjansson</owners>
    <description>Installs handy development tools.</description>
    <projectUrl>https://github.com/ornatwork/</projectUrl>
    <tags>SoftwareCreations devset tools development</tags>
    <copyright>Software Creations</copyright>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <iconUrl>http://kristjansson.us/favicon.ico</iconUrl>
    <dependencies>
      <dependency id=“fiddler” />
      <dependency id=“filezilla” />
      <dependency id=“winrar” />
      <dependency id=“sublime” />
      <dependency id=“gimp” />
      <dependency id=“dotpeek” />
      <dependency id=“grepwin” />
      <dependency id=“skype” />
      <dependency id=“testdriven.net” />
      <dependency id=“MagicDisc” />
      <dependency id=“winmerge” />
      <dependency id=“tortoisesvn” />
      <dependency id=“TortoiseGit” />
      <dependency id=“windowstelnet” />
    </dependencies>
    <releaseNotes>
    </releaseNotes>
  </metadata>
  <files>
    <file src=“tools\**” target=“tools” />
    <file src=“content\**” target=“content” />
  </files>
</package>

For this spec I have only dependencies which means I’m not really installing anything myself. Rather pulling and installing the dependencies. As such there is a /tool directory that has a PowerScript file that doesn’t do anything. Secondly since some of these packages have /content directory that needs to be created as well. If not an error will be thrown when the package is run ( that’s a bug ). There for I just put fake.txt file in that directory that is enough to get around the error.

My source can be found on GitHub

Since I don’t like doing tasks by hand that can be automated I created a nant script to create the package and push it up on the Chocolatey server. When I make a change to the package I save it and then on the command line just run the nant script.

For example
> nant -D:version=0.10

<?xml version=“1.0”?>

<!– Chocolatey fun –>
<project name = “SofwareCreateions.devset”
                 default = “PackAndDeploy”
                 basedir=“.”>

  <!–  Register the sys.* properties; most specifically, sys.env.* for all environment vars   –>
  <sysinfo failonerror=“false” />

  <!– The version number for the package –>
  <property name=“version” value=“0.01” dynamic=“true” overwrite=“true” />
  <property name=“BuildDrive” value=“${string::substring(project::get-base-directory(), 0, 1)}”  dynamic=“true” />
  <property name=“path.base.drive” value=“${BuildDrive}:\” />
  <property name=”cmdChocolateyPath” value=”${path.base.drive}\Chocolatey\bin\” />
  <property name=”cmdChocolatey” value=”chocolatey.bat” />
  <property name=”nugetFile” value=”softwarecreations.devset” />

  <!– This is the main / default target –>
  <target name=”PackAndDeploy” depends=”Start, UpdateVersion, Package, Deploy“>
    <echo message=”Done !“/>
  </target>

  <!– Individual targets below, those should NOT have any dependancies –>
  <target name=”Start” >
    <echo message=”*** Version number=${version} “/>

  </target>

  <!– Update version number –>
  <target name=”UpdateVersion” description=”Update version files to the current version being built.”  >
   
    <echo message=”*** Start updateVersions: ver=${version}“/>
   
    <!– Update NuGet package version –>
    <xmlpoke file=”softwarecreations.devset.nuspec” xpath=”/package/metadata/version” value=”${version}” />

  </target>

  <!– Package –>
  <target name=”Package“>
    <echo message=”Start Package:“/>

    <echo message=”Push to Nuget feed:“/>
    <!– Deploy to Nuget Gallery –>
    <exec program=”${cmdChocolateyPath}${cmdChocolatey}” verbose=”true
          commandline=”
pack ${nugetFile}.nuspec“/>
   
  </target>

  <!– Deploy –>
  <target name=”Deploy“>
    <echo message=”Start Deploy:“/>
   
    <exec program=”${cmdChocolateyPath}${cmdChocolatey}” verbose=”true
          commandline=”
push ${nugetFile}.${version}.nupkg“/>
   
  </target>

</project>

My package and it’s content can be found here If your have Chocolatey installed you can run it from the command line, like so.

> cinst SoftwareCreations.devset

Chocolatey is like apt-get on the Linux box, when you start using it its hard to go back to the manual search – webpage – download – install routine. There are only about 1200+ packages available at this point but that will grow going forward for sure.

Text to speech sample in C#

I found out that I had not played with Text to speech in .net yet. So naturally I went to take a look how easy or hard it is to use TTS in C#. It turns out the hardest part is to find the download link for the TTS install. Its hard to understand how Microsoft sometimes seems to hide download links. Once you find the SAPI SDK page, you would think they would have download links, but not so. However you do not need the whole SDK just to do Text to speech. You only need the TTS download which has a much smaller footprint. But again, where is the download link… ? I found one Microsoft page that doesn’t make it clear, and another third party page that I used to download the TTS install.

And now for the code it self, it’s very straight forward. After installing TTS add reference to your project, choose the COM “Microsoft Speech Object Library” that will create interop dll for your project. Add a reference to the speech library in code and the Hello world sample is only two lines of code.

using System;
//
using SpeechLib;

namespace tester
{
    class Program
    {
        static void Main(string[] args)
        {
            SpVoice myVoice = new SpVoice();
            myVoice.Speak(“Hello world”);
        }
    }
}

Another choice is to do the same without using the COM object, as COM is heavy. In that case add reference to System.Speech .net library and the code will look like this.

using System;
//
using System.Speech.Synthesis;

namespace tester
{
    class Program
    {
        static void Main(string[] args)
        {
            SpeechSynthesizer synth = new SpeechSynthesizer();
            synth.Speak(“Hello World”);
        }
    }
}