4. Getting Started

4.1. Using the Example Tests

Opening the Tests

Zanebug comes with four pre-compiled dlls that demonstrate both NUnit and Zanebug tests. Examples are located under the C:\Program Files\Zanebug\Examples folder.

NUnit v2.1.4 Example
C:\Program Files\Zanebug\Examples\Examples.NUnit.v214\bin\Debug\Examples.NUnit.v214.dll

NUnit v2.2.0 Example
C:\Program Files\Zanebug\Examples\Examples.NUnit.v220\bin\Debug\Examples.NUnit.v220.dll

Zanebug v1.4.1 Example
C:\Program Files\Zanebug\Examples\Examples.Zanebug.v141\bin\Debug\Examples.Zanebug.v141.dll

Zanebug v1.4.2 Example
C:\Program Files\Zanebug\Examples\Examples.Zanebug.v142\bin\Debug\Examples.Zanebug.v142.dll

In order to load and test the dlls, do the following:

  1. Open the Zanebug GUI (use the desktop shortcut, or go to Start -> Program Files -> Zanebug)

  2. Once the GUI is open, select File -> Open Assembly

    Note

    You can also try File -> Open Recent. Upon installation, a reference is placed for all of the example files in the recent files menu.

  3. Navigate to one of the .dlls listed above

  4. Press Run to run the tests and look at the results

Source Code

All examples come with full source code, located in the root directory for each example. This is an excellent place to start when writing tests.

4.2. Writing Tests - Quick Start

Writing tests with Zanebug is easy. There are 4 steps that you must take:

  1. Add a reference to the test engine .dll

    • Adapdev.UnitTest.dll

    This is located in the Zanebug directory, located at:

    C:\Program Files\Zanebug\Adapdev.UnitTest.dll

    (It would be more user-friendly to store it in the GAC, but this was not the preferred approach for various reasons...)

  2. Add the namespace reference to your test class

    using System;
    using Adapdev.UnitTest;
    
    namespace UnitTest
    {
    	public class SimpleClassTest
    	{
    	}
    }
  3. Add the [TestFixture] attribute above the class name

    using System;
    using Adapdev.UnitTest;
    
    namespace UnitTest
    {
    	[TestFixture]
    	public class SimpleClassTest
    	{
    	}
    }

    This tells the Zanebug engine that this class is a test class and should be included in the TestSuite tree. If you have a class that contains [Test] methods, but is not marked with the [TestFixture] attribute, the class will be ignored by Zanebug.

  4. Add the [Test] attribute above each method that you want to run as a test, and the specific test logic

    Note

    The signature for all [Test] methods must be public void with no return value

    using System;
    using Adapdev.UnitTest;
    
    namespace UnitTest
    {
    	[TestFixture]
    	public class SimpleClassTest
    	{
    		[Test]
    		public void FirstTest()
    		{
    			// ... test logic goes here ...
    		}
    
    		[Test]
    		public void SecondTest()
    		{
    			// ... test logic goes here ...
    		}
    	}
    }

Although Zanebug contains several other attributes and features, the above steps are at the heart of any unit test.

4.3. Writing Tests - Example

In order to demonstrate a full test, let's use a modified version of the famous "Hello World" example. We first create a simple class with two methods:

  • SayHello() - simply returns "Hello!"

  • SayHello(string name) - returns "Hello [name]!"

using System;

namespace Examples
{
	public class HelloWorld
	{
		public static string SayHello()
		{
			return "Hello!";
		}

		public static string SayHello(string name)
		{
			return String.Format("Hello {0}!", name);
		}
	}
}

In a traditional testing environment, this would most likely be validated with a simple console application:

using System;
using Examples;

namespace ConsoleApplication1
{
	class Class1
	{
		[STAThread]
		static void Main(string[] args)
		{
			Console.WriteLine(HelloWorld.SayHello());
			Console.WriteLine(HelloWorld.SayHello("Sean"));
			Console.ReadLine();
		}
	}
}

This would produce the following output:

Hello!

Hello Sean!

Unfortunately, this is a very rudimentary way to test and relies on human interaction to validate that a component behaved correctly. The more complex the component, the more error-prone.

Using Zanebug, automated tests can be easily written and rerun on a continual basis. To address the above example, we would write the following unit test:

using System;
using Adapdev.UnitTest;
using Examples;

namespace Examples.Test
{
	[TestFixture]
	public class HelloWorldTest
	{
		[Test]
		public void SayHello()
		{
			Assert.AreEqual("Hello!", HelloWorld.SayHello());
		}

		[Test]
		public void SayHelloWithName()
		{
			Assert.AreEqual("Hello Sean!", HelloWorld.SayHello("Sean"));
		}
	}
}

The above test is very simple. The first test, SayHello(), simple validates that the text being returned from the HelloWorld.SayHello() method is the expected text. The second test does the same thing, but tests the result with a name being passed in.

In both instances, the Assert class is used to test behavior. Assert is a key part of writing unit tests, since it does the actual work. When an assertion is performed, only one of two outcomes is possible -- correct or incorrect. If the response is correct, then that portion of the test passes. If the response is incorrect, an AssertionException is thrown and the test immediately fails without continuing.

The Assert class contains multiple methods. Listed below are some of the more common ones (see the API documentation for a full list):

  • AreEqual(object o1, object o2)

    Validates that the two objects are equal

    string name1 = "Joe";
    string name2 = "Joe";
    string name3 = "Joe Schmoe";
    
    Assert.AreEqual(name1,name2); // Passes
    Assert.AreEqual(name1,name3); // Fails
    
  • AreSame(object o1, object o2)

    Validates that the two objects have the same reference (i.e. point to the same object)

    CustomObject o1 = new CustomObject();
    CustomObject o2 = new CustomObject();
    CustomObject o3 = o1;
    
    Assert.AreSame(o1, o2); // Fails
    Assert.AreSame(o1, o3); // Passes
    
  • IsFalse(bool condition)

    Validates that a given condition is false

    int i = 1;
    int j = 2;
    int k = 2;
    
    Assert.IsFalse(i == j); // Passes
    Assert.IsFalse(j == k); // Fails
    
  • IsTrue(bool condition)

    Validates that a given condition is true

    int i = 1;
    int j = 2;
    int k = 2;
    
    Assert.IsTrue(i == j); // Fails
    Assert.IsTrue(j == k); // Passes
    

Test methods can (and normally should) contain multiple assertions. Revisiting our original HelloWorld example, we'll add some more assertions:

using System;
using Adapdev.UnitTest;
using Examples;

namespace Examples.Test
{
	[TestFixture]
	public class HelloWorldTest
	{
		[Test]
		public void SayHello()
		{
			Assert.AreEqual("Hello!", HelloWorld.SayHello());
			Assert.IsTrue(HelloWorld.SayHello().Length == 6);
		}

		[Test]
		public void SayHelloWithName()
		{
			Assert.AreEqual("Hello Sean!", HelloWorld.SayHello("Sean"));
			Assert.IsTrue(HelloWorld.SayHello("Sean").Length == 11);
		}
	}
}

The multiple assertions in the above example don't add much value in this instance, but it gets the point across...

Now, to round things out, let's show an explicit example of a test failing:

using System;
using Adapdev.UnitTest;
using Examples;

namespace Examples.Test
{
	[TestFixture]
	public class HelloWorldTest
	{
		[Test]
		public void SayHello()
		{
			// Test passes and continues
			Assert.AreEqual("Hello!", HelloWorld.SayHello()); 

			// Test fails because length is 6
			Assert.IsTrue(HelloWorld.SayHello().Length == 5); 
		}

		[Test]
		public void SayHelloWithName()
		{
			// Test fails because the returned value is Hello instead of Bonjour
			Assert.AreEqual("Bonjour Sean!", HelloWorld.SayHello("Sean")); 

			// Not tested, since the test has already failed
			Assert.IsTrue(HelloWorld.SayHello("Sean").Length == 11); 
		}
	}
}

4.4. Basic Steps - Summary

In summary, to write a test you need the following basic components:

  1. Add a reference to the test engine in your project (Adapdev.UnitTest.dll)

  2. Add a namespace reference in your code

    ...
    using Adapdev.UnitTest
    ...
    
  3. Add a TestFixture attribute above your class declaration

    ...
    using Adapdev.UnitTest
    ...
    
    namespace XXX{
    
        [TestFixture]
        public class YYY{
    
        }
    }
    
  4. Add a Test attribute above a test method

    ...
    using Adapdev.UnitTest
    ...
    
    namespace XXX{
    
        [TestFixture]
        public class YYY{
    
            [Test]
            public void ZZZ(){
            }
    
        }
    }
    
  5. Add any assertions within your test method

    ...
    using Adapdev.UnitTest
    ...
    
    namespace XXX{
    
        [TestFixture]
        public class YYY{
            ...
            Assert.IsTrue(some statement);
            ...
        }
    }