Opening the Tests
Zanebug comes with two pre-compiled dlls that demonstrate both NUnit and Zanebug tests. Both examples are located under the \Zanebug v1.4\examples folder.
NUnit v2.1 Example C:\Program Files\Adapdev\Zanebug v1.4\examples\NUnit v2.1\Examples.NUnit.v21.dll Zanebug v1.4 Example C:\Program Files\Adapdev\Zanebug v1.4\examples\Zanebug v1.4\bin\Examples.Zanebug.dll
The NUnit v2.1 example will not work if you have NUnit v2.2 installed. This will be fixed in the next release
In order to load and test the dlls, do the following:
Open the Zanebug GUI (use the desktop shortcut, or go to Start -> Program Files -> Adapdev -> Zanebug v1.4)
Once the GUI is open, select File -> Open Assembly
Navigate to one of the .dlls listed above (both are located under the \examples folder)
Press Run to run the tests and look at the results
Source Code
Both examples come with full source code, located under the \src directory for each example. This is an excellent place to start when writing tests.
Writing tests with Zanebug is easy. There are 4 steps that you must take:
Add a reference to the test engine .dll
Adapdev.UnitTest.dll
This is located in the Zanebug directory, located at:
C:\Program Files\Adapdev\Zanebug v1.4\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...)
Add the namespace reference to your test class
using System;
using Adapdev.UnitTest;
namespace UnitTest
{
public class SimpleClassTest
{
}
}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.
Add the [Test] attribute above each method that you want to run as a test, and the specific test logic
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.
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);
}
}
}