Posts tagged ‘C#’

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.

Custom file extenstion in Visual Studio C#

I was using some files that have among other things some C# code in it in VS. When it dawned at me that I wasn’t getting the syntax highlighting which makes it much harder to read the code. Visual Studio just treats it as any other text file. In order to add a new one you just need to set new file association within VS. Tools – Options – Text editor – File Extensions. Add your extension and the editor you want to use, in my case Microsoft Visual C#. That will give you the code syntax, much better.

Team Foundation Server, msbuild unittest code coverage

If you are like me and wonder how much coverage your unittests have you can add coverage to your Team Foundation Server builds and see for yourself.

Note, I have only tried this using VS2008

First right click /Solution items in your solution explorer Add new item, choose Test run Configuration, let’s name it CodeCoverage.testrunconfig

Choose Code coverage on the left and choose the dll’s you want covered, save and check it in.

In your build.proj file find the first PropertyGroup, at the end of it add the line about the config file. You will need this in order for MsBuild to find the configuration. Then it will look similar to the xml below. Note the path, in my case I had to add \MYPROJECT to the mix as that’s where my source gets checked out on the build machine. You can see where that is on the server or check the build log and look at what directory the file is checked out to.

<PropertyGroup>
    …. snip
 
    <RunConfigFile>
        $(SolutionRoot)\MYPROJECT\CodeCoverage.testrunconfig
    </RunConfigFile>
  </PropertyGroup>

The coverage numbers will show up in the Unittest section of the build report. It is of course important to remember a well covered code does NOT mean that your unittests are any good. Most likely they are but the coverage number just means how much of the code was touched during the unittest run.

C# Base32

I had the need to use Base32 at work some time ago to compress numbers. I had forgotten about it until today when I ran across some old code. As I was researching implementation for a developer on another system we interact with. The problem at the time was that we had numbers that are too big to fit in the field where we needed to write it. In order to do so we needed to compress it and we choose Base32 for the task.

Simply put, you take a number and you convert it to the 32 characters in the convert table, for example.

123456789 becomes VITXVD

Of course when you have the Base32 encoded number you can decode it back to the original number. If you couldn’t do that it wouldn’t be very useful.

VITXVD becomes 123456789

The RFC 4648 Base 32 alphabet
Value Symbol Value Symbol Value Symbol Value Symbol
0 A 9 J 18 S 27 3
1 B 10 K 19 T 28 4
2 C 11 L 20 U 29 5
3 D 12 M 21 V 30 6
4 E 13 N 22 W 31 7
5 F 14 O 23 X
6 G 15 P 24 Y
7 H 16 Q 25 Z
8 I 17 R 26 2



Note that one and zero are not used so there is no confusion between them O and I. When shuffling data between different systems, legacy etc they might not be interpreted correctly. You can create the Base32 encoding in different ways. Therefor if your interacting with another system exchanging data that system needs to use the same encoding / decoding as your system.

Below is a C# sample Base32 code.

class CxBase32
    {
        //
        private const string BASE_32_ALPHABET = “ABCDEFGHIJKLMNOPQRSTUVWXYZ234567”;
        private static int BASE_LENGTH = BASE_32_ALPHABET.Length;
 
        // Encode number to base 32 string
        public static string toBase32( int piNumToCode )
        {
            StringBuilder sRet = new StringBuilder();
 
            // loop until nothing left
            do
            {
                // Set the encoded character using mod
                sRet.Append(BASE_32_ALPHABET[piNumToCode % BASE_LENGTH]);
                // Adjust the reminder
                piNumToCode = piNumToCode / BASE_LENGTH;
            }
            while (piNumToCode != 0);
 
            return sRet.ToString();
        }
 
 
        // Decode base 32 string to a number
        public static int fromBase32(string psCodedString)
        {
            int iRet = 0;
 
            // Decode the alphabet
            for (int i = psCodedString.Length1; i > –1; i–)
                { iRet = (iRet * BASE_LENGTH) + BASE_32_ALPHABET.IndexOf(psCodedString[i]); }
 
            return iRet;
        }
 
    }  // EOC
 

And unittests

[Test]
        // Make sure encoded number can be decoded correctly
        public void randomBase32Test()
        {
            // Try some random number
            string encoded = CxBase32.toBase32(123456789);
            Assert.AreEqual(“VITXVD”, encoded);
            int decode = CxBase32.fromBase32( encoded );
            Assert.AreEqual(123456789, decode);
           
            // Another number just for fun
            encoded = CxBase32.toBase32(987654321);
            Assert.AreEqual(“RF24N5”, encoded);
            decode = CxBase32.fromBase32(encoded);
            Assert.AreEqual(987654321, decode);
        }
       
        [Test]
        // Make sure zero will return a value
        public void zeroBase32Test()
        {
            // Zero test, should return a value as well
            string encoded = CxBase32.toBase32(0);
            Assert.AreEqual(“A”, encoded);
            int decode = CxBase32.fromBase32(encoded);
            Assert.AreEqual(0, decode);
        }

using nLog in C#

Finally I had a new project were I needed some logging and on opportunity to use nLog for the first time. I have wanted to check it out in the past but it just never came to that. So here is the quick run down, the sample is from their tutorial with a slight mods from me and is really all you need to get nLog up and running quickly.

//
using NLog;
using NLog.Targets;
using NLog.Config;
using NLog.Win32.Targets;

            // Step 1. Create configuration object
            LoggingConfiguration config = new LoggingConfiguration();

            // Step 2. Create targets and add them to the configuration
            ColoredConsoleTarget consoleTarget = new ColoredConsoleTarget();
            config.AddTarget(“console”, consoleTarget);
            //
            FileTarget fileTarget = new FileTarget();
            config.AddTarget(“file”, fileTarget);

            // Step 3. Set target properties
            consoleTarget.Layout = “${date:format=HH\\:MM\\:ss}: ${message}”;
            // set the file
            fileTarget.FileName = CxUtil.getDataDir() + \\log.txt”;
            fileTarget.Layout = “${date:format=HH\\:MM\\:ss}: ${message}”;
            // don’t clutter the hard drive
            fileTarget.deleteOldFileOnStartup = true;

            // Step 4. Define rules
            LoggingRule rule1 = new LoggingRule(“*”, LogLevel.Debug, consoleTarget);
            config.LoggingRules.Add(rule1);
           
            // Only log to file in non debug mode
            #if !DEBUG
                LoggingRule rule2 = new LoggingRule(“*”, LogLevel.Debug, fileTarget);
                config.LoggingRules.Add(rule2);
            #endif

            // Step 5. Activate the configuration
            LogManager.Configuration = config;

            // Create logger
            Logger logger = LogManager.GetLogger(“Example”);
            // Example usage
            logger.Trace(“trace log message”);
            logger.Debug(“debug log message”);
            logger.Info(“info log message”);
            logger.Warn(“warn log message”);
            logger.Error(“error log message”);
            logger.Fatal(“fatal log message”);

Mono on the Mac

As great as Mono can be allowing you to run .net application under Win, Linux, Mac and more.  There is a gotcha, if you intend to run on the Mac you can not use the Win forms.  As the Win forms have limited functionality on the Mac or just don’t run,  you are also required to install X11 on the Mac for starters.  What you will have to do is to use the Gtk# UI libraries instead as they are by far more mature in Mono on the Mac.  The strange part is that the Win forms work fine on the linux desktop under Mono.

This doesn’t make any sense, does it ?    If you want cross platform UI application that you intend to run under Mono including on the Mac you need to write it that way from the start, use Mono and Gtk# to develop.  That means for you MS VS .net developers you can’t use your favorite VS editor, at least not out of the box.  You have to get something else like MonoDevelop.   You also have to think about it if you have an old application that you want running under Mono on the Mac, you will have to go in and rip out the Win forms and replace them with the Gtk# forms.

As they put it on the Mono website,

There were two previous attempts to implement System.Windows.Forms in Mono. These initial attempts were done on top of other toolkits: first Gtk, then Wine. Each one had its share of problems, causing it to be abandoned.

Read more…

I’m not bashing Mono by any means, I think it’s a great effort and well worth investing some time using Mono.  Even getting involved if your so inclined.  There is just that gotcha about using Win Forms that I wanted to point out to the unaware Win C# developers.