Open Source .NET Development [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Open Source .NET Development [Electronic resources] - نسخه متنی

Brian Nantz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


NUnit Example


Chapter 9. But to demonstrate the usefulness of NUnit, let's write a test to test the custom <mkisofs> NAntContrib task we wrote in Chapter 4's "Extending NAntContrib."

NOTE

NUnit 2.0 was used for this chapter. There have been some changes to NUnit 2.1, which was recently released. Most of the concepts discussed here are applicable to any NUnit 2.x version.

NUnit Attributes


To begin the test, we have to understand how to create a TestFixture or Test. One of the features of NUnit 2.0 is the use of C# Custom Attributes. Figure 6-1 that can be applied to your testing component.

Table 6.1. Unit Testing Pseudo-Code

Attribute

Description

TestFixture

A collection of tests.

Test

A unit test.

Ignore

Ignore this test.

Setup

NUnit calls this method before running the test.

TearDown

NUnit calls this method after running the test.

ExpectedException

Tell NUnit to Expect an Exception.

Suite

A depreciated attribute supported for backward compatibility.

TestFixture usually equates to a class attribute. All other attributes are associated with a method. The Ignore, Setup, and TearDown attributes are not required. Note that the method marked with TearDown will be run even in the case that the test fails. Listing 6.1 shows some pseudo-code for a unit test.

Listing 6.1. Unit Testing Pseudo-Code

[TestFixture]
public class TestAClass
{
[Setup]
public void ThisMethodIsCalledBeforeAnyTests() {...}
[Test]
public void FirstTestOfTheClass() {...}
...
[Test]
public void LastTestOfTheClass() {...}
[Teardown]
public void ThisMethodIsCalledAfterAllTheTests() {...}
}

Listing 6.1 shows how easily NUnit uses reflection to enumerate any class decorated with the TestFixture custom attribute. Once a class with TestFixture is found, NUnit looks for a method marked with the Setup attribute and executes it first. Then each method with a Test attribute is executed. Finally, the TearDown method is run.

Example


To properly test mkIsoFs, we need to create a test directory structure with several files from which to create an iso file. After the test is done, we want to delete the directory structure and corresponding iso file. This is a perfect opportunity to use the TearDown and Setup methods.

Listing 6.2. NUnit Test for the mkisofs NAntContrib Task

using System;
using System.IO;

using NUnit.Framework;
namespace Tests.NAnt.Core.Tasks
{
/// <summary>Some simple Tests.</summary>
///

[TestFixture]
public class MkIsoFsTest : BuildTestBase
{
private string DIR = Path.Combine(Path.GetTempPath(), "\\isotest");
private string ISOFILE = Path.Combine(Path.GetTempPath(), "\\mkfsiso.iso");
private const string SUBDIRNAME = "Directory";
private const string FILENAME = "File";
private const string FILEEXTENSION = ".txt";
private const string FILECONTENT = "This will be written to each file.";
private const int NUMSUBDIR = 10;
private const int NUMFILEPERDIR = 10;

[SetUp]
public void Init()
{
// lets create a temp directory with same bogus files
Directory.CreateDirectory(DIR);
for(int i=0; i<NUMSUBDIR; i++)
{
Directory.CreateDirectory(Path.Combine(DIR, "\\" + SUBDIRNAME + i));
for(int j=0; j<NUMFILEPERDIR; j++)
{
FileStream fs = File.Create(Path.Combine(DIR, "\\" + SUBDIRNAME + i) + "\\"
+ FILENAME + j + FILEEXTENSION);
StreamWriter sw = new StreamWriter(fs);
sw.Write(FILECONTENT);
sw.Flush();
sw.Close();
fs.Flush();
fs.Close();
}
}
}

[TearDown]
public void Clean()
{
//Lets delete the iso file and bogus directory.
if(Directory.Exists(DIR))
Directory.Delete(DIR);
if(File.Exists(ISOFILE))
File.Delete(ISOFILE);
}

[Test]
public void MakeISO()
{
string _xml = "<project>" +
"<mkisofs inputdir='\" + DIR + "\"'" +
" isofilename ='\" + ISOFILE + "\"'" + "/>" +
"</project>";
string result = RunBuild(_xml);
Assertion.Assert("ISO File: " + result + " should have been created.", File
.Exists(ISOFILE));
}

[Test]

[Ignore("ignored test")]
public void FutureOptions()
{
}
}
}

Chapter 9. Thinking what tests your component should pass before writing the code can even make you think of use cases you may have initially overlooked for the component you are designing. Finding these cases in development instead of testing or worse in the field is a big time and money saver.

NOTE

The unit test for mkIsoFs is using the infrastructure of NAnt's NUnit tests (thus the BuildTestBase parent class), even though this task exists in NAntContrib. This means that the test would actually have to be integrated into the NAnt task's tests to work properly. This of course is not an issue for the svn unit test since the svn task already is a part of NAnt proper. "Why did I cheat like this?" you may ask. Mostly because NAntContrib does not have an infrastructure for testing. This is somewhat of a sore spot between the projects that will surely be resolved soon.

After compiling the test, running it is simple. Figure 6-2 is a common test run from NUnit.

Figure 6-2. NUnit Graphical Interface.

[View full size image]

NOTE

NUnit 2.1 is now working on Mono and has a very useable graphical interface called NUnit-Gtk. NUnit-gtk is a gtk# port of the NUnit tool shown in Figure 6-2 and is therefore useable on multiple operating systems. You can get NUnit-gtk from the Mono distribution.

If a test were to fail, it would appear in red with the failure text. The example tests in this chapter do not need any information from a configuration file. Normally, this is not the case. Since .NET configuration files are only used by applications, NUnit uses reflection to allow your test to have a [testname].dll.config file. This configuration information can be accessed as normal, even though your application is really being hosted, or tested, by NUnit.

NUnit Assertions


In Listing 6.2, you can see the use of Assertions. The example checks to see if the ISO file was created. If the mkisofs task somehow completes without error but doesn't create the iso file, then I want to fail the test. NUnit allows this by implementing Assertions. Table 6.2 shows the Assertions available in NUnit.

Table 6.2. NUnit Assertions

Assertion Type

Description

Assert

Always Asserts

AssertNull

Assert if parameter is null

AssertNotNull

Assert if parameter is not null

AssertEquals

Assert if given values are equal

ExpectedException


In some situations, you may want to test the error handling of the code you are testing. In other words, the test may intentionally do something illegal and check to see that the proper exception is raised from the tested code. This functionality is available by using ExpectedException.

Listing 6.3. Testing Exceptions and Error code paths

[Test]
[ExpectedException(typeof(DivideByZeroException))]
public void DivideByZeroTest()
{
Decimal.Divide(1, 0);
}

Listing 6.3 shows a simple test of the Decimal Division static method to ensure that you cannot divide by zero.

NUnit Exceptions


Table 6.3 shows the exceptions used by NUnit.

Table 6.3. NUnit Exceptions

Attribute

Description

AssertionException

Indicates that an Assertion has failed. Replaces the AssertionFailedError in NUnit 1.x.

InvalidSuiteException

Depreciated exception for the Depreciated Suite Attribute. Indicates an Invalid Test Suite.

InvalidTestFixtureException

Indicates an Invalid TestFixture.

NoTestFixtureException

Missing TestFixture attribute, which is equivalent to nothing to test.

NUnitException

General NUnit exception.

TargetInvocationException

An error occurred when invoking a target.

This is not an exhaustive list of exceptions. NUnit does use some of the exceptions from the .NET framework, but Table 6.3 is the explanation of the exceptions that NUnit defines.


    / 275