Walkthrough: Creating and Running Unit Tests

This walkthrough will step you through creating, running, and customizing a series of tests using the Team System testing tools. You start with a C# project that is under development, create tests that exercise its code, run the tests, and examine the results. Then, you can change your project code and re-run the tests.

Note

For information about how to run tests from a command line, see Walkthrough: Using the Command-line Test Utility.

In this walkthrough, you will complete the following tasks:

  • Prepare a "Bank Account" project to use in a walkthrough.

  • Open an existing project.

  • Create unit tests for public and private methods.

  • Run those tests on the code.

  • Find and correct errors in tests.

  • Find and correct errors in the code.

Prerequisites

Prepare the Walkthrough

To prepare the walkthrough for C#

  1. Open Visual Studio Team System Test Edition.

  2. On the File menu, point to New and then click Project.

    The New Project dialog box appears.

  3. Under Project Types, click Visual C#.

  4. Under Templates, click Class Library.

  5. On the Name line, type BankCS and then click OK.

    Note

    If the name "BankCS" is already used, choose another name for the project.

    The new BankCS project is created and displayed in Solution Explorer.

  6. Double-click the file Class1.cs in Solution Explorer to open it in the Visual Studio Code Editor.

  7. Copy the C# source code from the Unit Test Sample.

  8. Replace the original contents of Class1.cs with the code from the Unit Test Sample.

  9. On the Build menu, click Build Solution.

You now have a project named BankCS. It contains source code to test and tools to test it with. The namespace for BankCS, BankAccountNS, contains the public class BankAccount, whose methods you will test in the following procedures.

To prepare the walkthrough for Visual Basic

  1. Open Visual Studio Team System Test Edition.

  2. On the File menu, point to New and then click Project.

    The New Project dialog box appears.

  3. Under Project Types, click Visual Basic.

  4. Under Templates, click Class Library.

  5. On the Name line, type BankVB and then click OK.

    Note

    If the name "BankVB" is already used, choose another name for the project.

    The new BankVB project is created and displayed in Solution Explorer.

  6. Double-click the file Class1.vb in Solution Explorer to open it in the Visual Studio Code Editor.

  7. Copy the Visual Basic source code from the Unit Test Sample.

  8. Replace the original contents of Class1.vb with the Visual Basic code from the Unit Test Sample.

  9. On the Build menu, click Build Solution.

You now have a project named BankVB. It contains source code to test and tools to test it with. The namespace for BankVB, BankAccountNS, contains the public class BankAccount, whose methods you will test in the following procedures.

Create a Unit Test

Prerequisite: Follow the steps in the procedure, Prepare the Walkthrough.

To create a unit test

  1. In Solution Explorer, double-click the Class1.cs or Class1.vb file in the project, depending on the language you chose.

    This opens the source file for viewing and editing.

  2. In the BankAccount class in the Class1.cs or Class1.vb file, scroll to the Debit() method.

  3. Right-click the Debit() method and select Create Unit Tests.

    This displays the Create Unit Tests dialog box.

    Under Current selection, a tree structure shows the class and member hierarchy of the assembly that houses the BankAccount class. You can use this page to generate unit tests for any selection of those members, and to choose a test project into which you want the generated unit tests to be placed.

    In the tree structure, only the Debit() method is selected. Leave it selected and also select the Credit() method.

  4. For Output project, select Create a new Visual C# test project or Create a new Visual Basic test project.

  5. Click Settings.

    The Test Generation Settings dialog box appears. Under Naming settings, you can change the way test files, test classes, and test methods are named as they are generated. Under General, you can change other aspects of test generation. Leave the default values for these settings and then click OK.

  6. In the Create Unit Tests dialog box, click OK.

    The New Test Project dialog box is displayed.

  7. Accept the default name and then click Create.

    This creates a project named TestProject1, which is displayed in Solution Explorer.

    A file named BankAccountTest.cs or BankAccountTest.vb, which contains a test class, is added to TestProject1. The class is populated with a TestContext property and with methods to test the Debit() and Credit() methods.

    Note

    Every test method is automatically assigned the TestMethod() attribute. Each test corresponds to a single method in the code under test that you want to test. Test methods are housed in a test class that is assigned the TestClass() attribute.

  8. In the BankAccountTest class, specify values for the variables to be tested. Scroll to the DebitTest method, where you see TODO comments that indicate variables to set. What values should you use? To answer that, you must know the values that will be used when the application is run. We determine those values in the following step.

  9. Open the Class1.cs or Class1.vb file and scroll to the Main method. Notice that the customer name is initialized to Mr. Bryan Walton, the account balance is initialized to 11.99, the Credit method is called with a parameter of 5.77, and the Debit method is called with a parameter of 11.22. Therefore, if this account starts with a Balance of 11.99, a call to the Debit method while passing 11.22 should give you a new Balance of 0.77.

    Note

    You will use this expected Balance value (0.77) in the procedure Run and Customize a Unit Test.

  10. In the BankAccountTest class, scroll to the DebitTest method.

  11. Set the following values:

    BankAccount target = new BankAccount("Mr. Bryan Walton", 11.99);
    double amount = 11.22;
    
    Dim target As BankAccount = New BankAccount("Mr. Bryan Walton", 11.99)
    Dim amount As Double = 11.22
    
  12. Make these same changes in the CreditTest method.

  13. Save the BankAccountTest.cs or BankAccountTest.vb file.

You have created a source-code file that contains tests for the Bank project. You are now ready to run the tests in the BankAccountTest class on the code of the Bank project.

Run and Customize a Unit Test

Prerequisite: Perform the steps in the procedure Create a Unit Test.

To run and customize a unit test

  1. Open the Test View window.

  2. Right-click DebitTest and click Run Selection.

    If the Test Results window is not already open, it opens now. The DebitTest test runs.

    In the Result column in the Test Results window, test status is displayed as Running while the test is running. After the test run finishes, the outcome of the test changes to Inconclusive.

  3. In the Test Results window, double-click the row that represents the test.

    This opens the test Results Details page, which contains information about the results of the test.

  4. Notice that the test Results Details page displays the error message "Assert.Inconclusive failed. A method that does not return a value cannot be verified." To work toward creating a successful test, start by finding and evaluating this Assert statement.

  5. To find the test method that contains the Assert statement, open the BankAccountTest.cs file and scroll to the DebitTest() method.

  6. The Assert statement is the last line in the DebitTest method. It reads as follows:

    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    

    Comment out this Assert statement.

  7. If you ran the test now, it would give a Passed result, but only because it tests for nothing. You must add code that tests for expected results. Add the following statement to the end of the DebitTest method:

    Assert.AreEqual((System.Convert.ToDouble(0.77)), target.Balance, 0.05);
    
    Assert.AreEqual((System.Convert.ToDouble(0.77)), target.Balance, 0.05)
    

    This statement compares the expected result (0.77) with the actual result from a call to the Balance method of the BankAccount class. If the two values are unequal, the Assert returns False, which makes the test fail.

    Note

    This Assert statement includes a third parameter, delta, with a value of 0.05. The delta parameter is required in this overload of the Assert.AreEqual method; it compensates for the rounding error intrinsic in floating-point types such as Doubles.

You have run the generated DebitTest method of your BankAccountTest test class, noted that it needed changes, and made those changes. It is now ready to test for the accuracy of the Debit method in your application.

Run a Unit Test and Fix Your Code

Prerequisite: Perform the steps in the procedure Run and Customize a Unit Test.

To run a unit test and fix your code

  1. Run the Debit test again: In the BankAccountTest.cs or BankAccountTest.vb file, right-click the DebitTest() method and then click Run Tests.

    In the Result column in the Test Results window, test status is displayed as Running while the test is running. After the test run finishes, the outcome of the test changes to Failed.

  2. In the Test Results window, double-click the row that represents the test.

    This opens the test Results Details page, which displays the error message "Assert.AreEqual failed. Expected a difference no greater than <0.05> between expected value <0.77> and actual value <23.21>". These numbers seem to indicate a faulty mathematical operation. Because the DebitTest method of the BankAccountTest class tests the Debit method of the BankAccount class, start by checking the Debit method.

  3. Open the Class1.cs or Class1.vb file and scroll to the Debit method.

  4. Notice the following assignment:

    Balance += amount;
    
    Balance += amount
    

    This assignment adds an amount to a balance when, in a Debit method, it should be subtracting. Change this line to read as follows:

    Balance -= amount;
    
    Balance -= amount
    
  5. Run the Debit test again.

    The Result column of the Test Results window displays Passed for DebitTest.

    Note

    You did not have to rebuild the project after changing the source code because running a test silently builds the project.

You have created a unit test that works and, through it, found and fixed an error in your code.

Create and Run a Unit Test for a Private Method

Prerequisite: Perform the steps in the procedure, Run a Unit Test and Fix Your Code.

To create and run a unit test for a private method

  1. Open the Class1.cs or Class1.vb file in the project.

  2. Right-click the FreezeAccount() method and select Create Unit Tests.

    This displays the Create Unit Tests dialog box.

    In the displayed tree structure, only the FreezeAccount() method is selected.

  3. (Optional) Click Filter, and then clear Display Non-public items. Notice that the FreezeAccount() method is removed from the list of child methods of the BankAccount class. Click Filter again, and then select Display Non-public items to re-display the FreezeAccount() method.

  4. Make sure that the FreezeAccount() method is selected, and then click OK.

    This creates a new private accessor file that is named Bank.accessor. It contains special accessor methods that the test uses to indirectly call private methods in the BankAccount class. You can see the new file displayed in Solution Explorer in the Test References folder.

  5. Open the BankAccountTest.cs file and scroll to the FreezeAccountTest() method.

  6. Change the code of the FreezeAccountTest() method so that it reads as follows. Changed or new areas are indicated:

    public void FreezeAccountTest()
    {
    BankAccount_Accessor target = new BankAccount_Accessor("Mr. Bryan Walton", 11.99); // TODO: Initialize to an appropriate value
    target.FreezeAccount(); 
        // Assert.Inconclusive("A method that does not return a value cannot be verified.");
         
        bool creditAccount = false; // False means account could be credited: Fail test.  
        // Try to credit account 
        try 
        { 
            target.Credit(1.00);  
        } 
        catch (System.Exception) 
        { 
            // Threw exception. FreezeAccount worked correctly: Pass test.  
            creditAccount = true; 
        } 
         
        // Assert fails if 'creditAccount' condition is false. Fail test. 
        Assert.IsTrue(creditAccount, "Was able to credit account.");
    }
    
    Public Sub FreezeAccountTest()
        Dim target As New BankAccount_Accessor("Mr. Bryan Walton", 11.99)
        ' TODO: Initialize to an appropriate value
        target.FreezeAccount()
        ' Assert.Inconclusive("A method that does not return a value cannot be verified.");
    
        Dim creditAccount As Boolean = False
        ' False means account could be credited: Fail test. 
        ' Try to credit account
        Try
        target.Credit(1.0)
        Catch generatedExceptionName As System.Exception
        ' Threw exception. FreezeAccount worked correctly: Pass test. 
        creditAccount = True
        End Try
    
        ' Assert fails if 'creditAccount' condition is false. Fail test.
        Assert.IsTrue(creditAccount, "Was able to credit account.")
    End Sub
    
  7. Run the FreezeAccountTest test.

    In the Result column in the Test Results window, the final test status appears as Passed. This is the expected result because the test called the Credit() method after freezing the account by calling the FreezeAccount() method.

You have added a private method, created a new unit test for it, and run the test. You can run it additional times, using other borderline values, such as 15.00, for the balance variable.

Next Steps

When you run tests on code in an assembly, you can see the proportion of your project's code that is being tested by collecting code coverage data. For more information, see Walkthrough: Run Tests and View Code Coverage.

You can run tests on a command line instead of in Visual Studio. For more information, see Walkthrough: Using the Command-line Test Utility.

See Also

Tasks

Unit Test Sample

Concepts

Test Results Reported

Other Resources

Unit Testing Framework