NUnit ExampleChapter 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."NOTENUnit 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 AttributesTo 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.
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. ExampleTo 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 Taskusing 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) + "\\" 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 } [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.NOTEThe 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] ![]() NUnit AssertionsIn 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.
ExpectedExceptionIn 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 ExceptionsTable 6.3 shows the exceptions used by NUnit.
|

