Setup Selenium, NUnit, and Visual Studio

Update

This article is still relevant but a more comprehensive guide exists at http://timothycope.com/c-selenium-automation. This new guide also covers Page Object Design Pattern (POM) and Selenium Server (Grid).

Background

Selenium automates browsers. That’s it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) also be automated as well.
http://docs.seleniumhq.org/

NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.6, is the seventh major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages.
http://www.nunit.org/

Install NUnit

You will need NUnit to execute your automated tests. Download the win MSI file and run it. Select a complete installation when prompted.

Setup Visual Studio

  1. Open Visual Studio
  2. Click File, click New, and select Project…
  3. In the left navigation pane, expand Templates, then Visual C#, and then select Class Library in the center window pane.
  4. In Package Manager Console, type Install-Package Selenium.WebDriverBackedSelenium
  5. In Package Manager Console, type Install-Package Selenium.Support
  6. In Package Manager Console, type Install-Package NUnit

Creating Your First Test

I renamed Class1.cs to AutomatedTest01.cs and that is reflected in the code below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using NUnit.Framework;
using OpenQA.Selenium.Firefox;

namespace SeleniumClassLibrary
{
    [TestFixture]
    public class AutomatedTest01
    {

        IWebDriver driver;

        [TestFixtureSetUp] // http://www.nunit.org/index.php?p=testFixture&r=2.5
        public void TestSetUp()
        {
            // Set the IWebDriver to use FireFox
            driver = new FirefoxDriver();

            // Set the timeout to 30 seconds
            driver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0, 0, 30));

        }

        [Test] // http://www.nunit.org/index.php?p=test&r=2.5
        public void NavigateToGoogle()
        {
            // Navigate to URL
            driver.Navigate().GoToUrl("http://www.google.com");

            // Assert that the IWebDriver window's title is "Google"
            Assert.AreEqual("Google", driver.Title);
        }

        [TestFixtureTearDown] // http://www.nunit.org/index.php?p=fixtureTeardown&r=2.5
        public void FixtureTearDown()
        {
            // Closes all windows associated with the IWebDriver
            driver.Quit();
        }
    }
}

Save and build the project.

Run the Automated Test

  1. Open NUnit
  2. Click File and select Open Project…
  3. Find the .dll from your Visual Studio Project
  4. Click Run in the center window pane

Importing Code from Selenium IDE for Firefox

You can download the Firefox add-on that allows you to record-and-click basic webpage tasks.

  1. In Selenium IDE:
    1. Click File, select Export Test Case As…, and select C# / NUnit / WebDriver
  2. You can copy+paste the code into a new .cs file in your project or import the cs file
  3. Save and Build your project

Note: You may have to make some manual changes to the code to have it playback correctly in NUnit.

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

namespace SeleniumClassLibrary
{
    // Genereated by Selenuim IDE for Firefox
    [TestFixture]
    public class AutomatedTest02
    {

        private IWebDriver driver;
        private StringBuilder verificationErrors;
        private string baseURL;
        private bool acceptNextAlert = true;

        [SetUp]
        public void SetupTest()
        {
            driver = new FirefoxDriver();
            baseURL = "http://timothycope.com/";
            verificationErrors = new StringBuilder();
        }

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

        [Test]
        public void The01Test()
        {
            driver.Navigate().GoToUrl(baseURL + "/");
            Thread.Sleep(2500);
            driver.FindElement(By.LinkText("ABOUT TIMOTHY COPE")).Click();
            Thread.Sleep(2500);
            for (int second = 0; ; second++)
            {
                if (second >= 60) Assert.Fail("timeout");
                try
                {
                    if (IsElementPresent(By.XPath("//img[@alt='logo']"))) break;
                }
                catch (Exception)
                { }
                Thread.Sleep(1000);
            }
        }
        private bool IsElementPresent(By by)
        {
            try
            {
                driver.FindElement(by);
                return true;
            }
            catch (NoSuchElementException)
            {
                return false;
            }
        }

        private bool IsAlertPresent()
        {
            try
            {
                driver.SwitchTo().Alert();
                return true;
            }
            catch (NoAlertPresentException)
            {
                return false;
            }
        }

        private string CloseAlertAndGetItsText()
        {
            try
            {
                IAlert alert = driver.SwitchTo().Alert();
                string alertText = alert.Text;
                if (acceptNextAlert)
                {
                    alert.Accept();
                }
                else
                {
                    alert.Dismiss();
                }
                return alertText;
            }
            finally
            {
                acceptNextAlert = true;
            }
        }
    }
}

Solution on GitHub

You can download the project I made from GitHub:
https://github.com/kirbycope/SeleniumClassLibrary

Create a BootStrap Enabled MVC5 Web Application

About MVC

The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the controller. The ASP.NET MVC framework provides an alternative to the ASP.NET Web Forms pattern for creating MVC-based Web applications. The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web Forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication. The MVC framework is defined in the System.Web.Mvc namespace and is a fundamental, supported part of the System.Web namespace.
http://www.asp.net/mvc/tutorials/older-versions/overview/asp-net-mvc-overview

About Bootstrap

Bootstrap was created at Twitter in mid-2010 by @mdo and @fat. Prior to being an open-sourced framework, Bootstrap was known as Twitter Blueprint. A few months into development, Twitter held its first Hack Week and the project exploded as developers of all skill levels jumped in without any external guidance. It served as the style guide for internal tools development at the company for over a year before its public release, and continues to do so today.
http://getbootstrap.com/about/

What you need to get started

Creating your new project

With MVC4 templates you had to remove/replace the css and html, which was a time consuming practice. The MVC4 template require a lot more work so MVC5 is a boon for developers needing to crank out multiple sites.

  1. Open Visual Studio
  2. Click File, hover over New, and select Project
  3. In the left navigation tree go to click Installed, select Visual C#, then select Web
  4. Name your project and click the OK button
  5. Select MVC as the template and click the OK button
    • You can also select Web API and Unit Test in the add folders and core references section
      • Unit tests are a must for professional/production projects
      • The Web API is a RESTful http service that can be called from other projects like a mobile app
  6. Press [F5] to preview the web application in debug mode
  7. (Optional) Change the web.config file’s database settings
    • By default, the template will create and mount databases as needed.
    • Change the connection string if;
      • You cannot create and mount databases programmatically (an issue I ran into with Arvixe web hosting)
      • You are using database first rather than model first or code first

Further Reading

Getting started with MVC5

  • An in-depth guide from Microsoft

Bootstrap Components

  • An overview of everything included in Bootstrap

 

C# Primer

About C#

C# is one of the programming languages designed for the Common Language Infrastructure. C# is built on the syntax and semantics of C++, allowing C programmers to take advantage of .NET and the common language runtime.
http://en.wikipedia.org/wiki/C_Sharp_(programming_language)

Download C#

The fastest way to start developing applications for Windows 8.1, Windows Phone, the web or the cloud. Visual Studio Express products provide a free development environment to develop applications for the latest platforms. Since it is Visual Studio, applications created in Express can be supported in other versions of Visual Studio as your needs grow.
http://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx

Starting C#

Learn how easy it is to set up Visual Studio and connect to Visual Studio Online. Once you’re set up, we’ll show you how to create and organize your backlog, share your code with your team, and configure your app for continuous builds and deployment. Choose any of the sections below to get started.
http://www.visualstudio.com/get-started/overview-of-get-started-tasks-vs

Hello World!

The following procedure creates a C# version of the traditional “Hello World!” program. The program displays the string Hello World!
http://msdn.microsoft.com/en-us/library/k1sx6ed2.aspx

To create and run a console application

  1. Start Visual Studio.
  2. On the menu bar, choose File, New, Project.
  3. The New Project dialog box opens.
  4. Expand Installed, expand Templates, expand Visual C#, and then choose Console Application.
  5. In the Name box, specify a name for your project, and then choose the OK button.
  6. The new project appears in Solution Explorer.
  7. If Program.cs isn’t open in the Code Editor, open the shortcut menu for Program.cs in Solution Explorer, and then choose View Code.
  8. Replace the contents of Program.cs with the following code:
// A Hello World! program in C#.
using System;
namespace HelloWorld
{
    class Hello
    {
        static void Main()
        {
            Console.WriteLine("Hello World!");

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}
"Hello World!"

Variables

The C# typing system contains the following categories: Value types, Reference types, and Pointer types.
Variables that are value types store data, and those that are reference types store references to the actual data. Reference types are also referred to as objects. Pointer types can be used only in unsafe mode.
It is possible to convert a value type to a reference type, and back again to a value type, by using boxing and unboxing. With the exception of a boxed value type, you cannot convert a reference type to a value type.
This section also introduces void.
Value types are also nullable, which means they can store an additional non-value state. For more information, see Nullable Types.
http://msdn.microsoft.com/en-us/library/3ewxz6et.aspx

// A Hello World! program in C#.
using System;
namespace HelloWorld
{
    class Hello
    {
	string message = "Hello World!";
        static void Main()
        {
            Console.WriteLine(message);

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}
"Hello World!"

Functions

A method is a code block that contains a series of statements. A program causes the statements to be executed by calling the method and specifying any required method arguments. In C#, every executed instruction is performed in the context of a method. The Main method is the entry point for every C# application and it is called by the common language runtime (CLR) when the program is started.
http://msdn.microsoft.com/en-us/library/ms173114.aspx

using System;
namespace HelloWorld
{
	class Hello
	{
		string message = "Hello World!";
		static void Main()
        	{
			// Call the method
			WriteMessage()

			// Keep the console window open in debug mode.
			Console.WriteLine("Press any key to exit.");
			Console.ReadKey();
        	}

		static void WriteMessage()
		{
			Console.WriteLine(message);
		}
	}
}
"Hello World!"

Passing Variables to Functions

Previously, message was accessible because its accessibility level is private (default). Meaning it is accessible from within the Hello class. In this example, we will pass a string value to a method as a parameter.

using System;
namespace HelloWorld
{
    class Hello
    {
        static void Main()
        {
            // Call the method
            WriteMessage("Hello World!")

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }

		static void WriteMessage(string message)
		{
			Console.WriteLine(message);
		}
    }
}
"Hello World!"

Error Handling

A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
http://msdn.microsoft.com/en-us/library/dszsf989.aspx

using System;
namespace HelloWorld
{
    class Hello
    {
        static void Main()
        {
            try
			{
				// Call the method
				WriteMessage("Hello World!");
			}
			catch (Exception e)
			{
				// Write exception to console
                Console.WriteLine(e.Message);
			}
            finally
			{
				// Keep the console window open in debug mode.
				Console.WriteLine("Press any key to exit.");
				Console.ReadKey();
			}
        }

        static void WriteMessage(string message)
        {
            Console.WriteLine(message);
        }
    }
}
"Hello World!"

Further Reading

C# Programming Guide

  • Most of this section assumes that you already know something about C# and general programming concepts. If you are a complete beginner with programming or with C#, you might want to visit the C# Developer Center, where you can find many tutorials, samples and videos to help you get started.

.Net Pearls

  • Documentation intended to be as simple as possible. Shows examples and performance(speed, memory, etc.).

Related Reading

StackOverflow

  • If you have a question, then chances are someone else did to. Chances are if you search you question on Goggle, you will get a StackOverflow result.