NUnit Core Concepts


Now that you have successfully coded, compiled, and executed your first programmer tests, let s spend some time exploring the vocabulary of the NUnit Framework. So far, we have talked about test fixtures, test cases, and test runners.

In the following section, we discuss test case.

Test Case

Test case is a self-validating programmer test that can be automatically discovered and executed independently of other test cases by a test runner. Following are a few important points about test case:

  • Test case is a programmer test . Although it is a pretty loose concept to pin down, the general rule of thumb is that the programmer test is a low-level test that aims to verify either method-level or class-level behavior.

  • Test case is a self-validating test , which means that each programmer test has a built-in mechanism to verify and report its success or failure status. A self-validating test does not require human intervention or interpretation.

  • Test case can be automatically discovered by a test runner, which implies that there should be a mechanism in place to unambiguously identify test cases to a test runner.

  • Test case can be automatically executed by a test runner. Again, this means that there should be no human intervention required to complete execution of a test case. (For example, a test case should not pause and prompt for a user input; all the information and additional resources that the test requires should be made available to the test at the time it is coded, or an automated mechanism should be developed to acquire such resources at run time.)

  • Test case can be executed independently of other test cases . This requirement implies that there should be no dependency between the tests, and the tests should be able to run as if they are executed in isolation. (In particular, test cases should not produce side effects that may change the result of running other test cases.) [1]

  • Test cases are units of organization and execution . As units of organization, test cases are grouped into test suites.

Test Suite

A test suite is a collection of test cases or other test suites. The relationship between test cases and test suites is described by the Composite [2] pattern.

Test Fixture

A test fixture is a group of test cases sharing a common set of run-time resources.

Now that the concepts are defined, let s look at our test again:

 using System; using NUnit.Framework; namespace NUnitQuickStart {    [TestFixture]    public class NumbersFixture    {       [Test]       public void AddTwoNumbers()       {          int a = 1;          int b = 2;          int sum = a + b;          Assert.AreEqual(3, sum);       }    } } 

The second line ( using NUnit.Framework; ) references the NUnit namespace, which contains all the classes you need to use to write your programmer tests. Classes populating this namespace are packaged in nunit.framework.dll .

Tests and Test Fixtures

One of the features of the NUnit Framework is its use of custom attributes. Attributes in .NET are the standard mechanisms to extend metadata about run- time entities. In this case, the run-time entities of interest are as follows :

  • Test classes are the classes that contain test code; each test assembly has to have at lease one test class.

  • Test methods are test cases; each test method represents a single test case that can be run independently of other test cases.

As the previous example demonstrates , the [TestFixture] attribute can be used to mark a class as a test class. The test class has to be public to be discovered by the test runner. The [Test] attribute is used to mark a method as a test method. A test method must follow these rules:

  • The method must be declared as public.

  • The method has to be an instance method (nonstatic).

  • The return type is void .

  • The method can t take any parameters.

Working with Test Runners

A test runner is a program that can be used to automatically discover, organize, run, and collect the results of execution of programmer tests. Until now, we have been working with NUnit-Gui test runner. One of the features of this test runner is its capability to represent the composite structure of the test assembly using a tree control, which provides a good visualization of the structure of the tests in the assembly. The test runner performs an automatic discovery of the tests in the assembly by following this simple two-step process:

  1. Find all classes marked with the [TestFixture] attribute in the assembly.

  2. For each fixture found, create a test suite and populate this test suite with all the test methods discovered in the test fixture.

After the test suite for the assembly is built, the test runner renders a visual representation of the test suite. In this tree, each non-leaf node maps to a test suite, and each leaf node maps to a test case. When the assembly is loaded, the tests can be run. You can run the entire suite or you might choose to run an individual node in the tree (a test suite or a test case) and run only that node and all its descendants. The test runner collects the results of the execution of each test case it runs and presents these results to you.

Assertions

A test case must be self-verifying. To write a self-verifying test case, we need a mechanism that supports such a verification process. In NUnit, the mechanism is called an assertion , which is a simple statement of truth (or what the programmer believes to be the truth). Here are some examples of assertions:

  • 1 + 2 = 3. (In most number systems, this is so.)

  • A dollar today is worth more than a dollar tomorrow. (If you disagree , we will be glad to hold your paychecks for you until you can figure out the one directly following.)

  • E=mc 2

Assertions can be rather arbitrary and might lack mechanisms to support their verification. In NUnit, we decided to support the mechanisms to verify the first type of assertions.

In the example we wrote, we used the mechanism of assertions to verify the results of adding two numbers . Let s make a little change to this example. The only statement we will change is the following:

 Assert.AreEqual(  4  ,sum); 

Obviously, this assumption will fail. To indicate failure, the progress bar turns red, and the tree nodes turn red to indicate which test failed. Note that the test tree represents a failure ”the parent nodes are colored red if at least one child note is red (sibling nodes of a failing node are not affected by its failure). Figure A-5 demonstrates the NUnit-Gui window after we rerun the test:

click to expand
Figure A-5: Assertion failure in the NUnit-Gui test runner

This simple example demonstrates the role that assertions play in NUnit Framework. This role is twofold:

  • Assertions are the mechanism to implement the self-verification property of test cases.

  • Assertions are also used by test runners to collect and report failures.

Let s move on to a few more examples to demonstrate some other capabilities of NUnit.

[1] This requirement is an adaptation of the idea of referential transparency , which is borrowed from functional programming languages. A purely applicative program is completely devoid of any side effects, so it is much more conducive to mathematical verification of the program s correctness.

[2] See Design Patterns.




Test-Driven Development in Microsoft .NET
Test-Driven Development in Microsoft .NET (Microsoft Professional)
ISBN: 0735619484
EAN: 2147483647
Year: 2004
Pages: 85

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net