Using VBA-Unit-Tester with data providers, and to test for errors.

0 68
Avatar for Beakerboy
2 years ago

In Part 1 we built our first Test Case and configured the Test Suite. In that example, the test would run only once, and all the logic was encapsulated within the test function. Many times you have built a function with edge conditions, and would prefer to run the same test with a variety of differing inputs. These are the cases that call for a Data Provider.

Our Matrix class has a method called ExcludeRow() that behaves slightly different in three different situations. Instead of writing three different tests, we will write one and feed it three different inputs.

The first thing to note is the method signature is slightly different. First, the name of sub must end with “ProviderTest”. Second, the sub takes inputs. The first two are Variants. I like to use arrays to pass in everything I need to set up the object we are testing and the object we are comparing to. Last is the string that will be logged if the test fails.

Sub ExcludeRowProviderTest(Inputs, Expected, Message As String)
    Set M = Identity(3)
    Dim Column as Integer
    Column = Inputs(0)
    Dim ExpectedMatrix = MatrixFromJaggedArray(Expected)
    AssertMatrixEqual M.ExcludeColumn(Column), M2, Message
End Sub

Function ExcludeRowProviderTest_Data()
    Test1 = Array( _
        1, _
        Array( _
            Array(0, 1, 0), _
            Array(0, 0, 1) _
        ), _
        “Excluding First Row” _
    )
    Test2 = Array( _
        2, _
        Array( _
            Array(1, 0, 0), _
            Array(0, 0, 1) _
        ), _
        “Excluding Second Row” _
    )
    Test3 = Array( _
        3, _
        Array( _
            Array(1, 0, 0), _
            Array(0, 1, 0) _
        ), _
        “Excluding Third Row” _
    )
    ExcludeRowProviderTest_Data = Array(Test1, Test2, Test3)
 End Function 

As you see, a function with the same name as the ProviderTest has “_Data” appended to it. This function will automatically be called, and one by one, each Array will be passed to the Test.

The last special type of test is used to verify that specific error raising code is executed correctly. Our Matrix.ReplaceRow() function will raise an error when the supplied new row is an incompatible size for the Matrix. To ensure that this error is raised when it should, we will create a scenario that should cause an error and make a call to EnsureError. This configures the TestLogger to catch any errors and mark the test as passed, if and only if an error is raised.

Sub ReplaceRowErrorTest()
    ‘ Create a 2x2 Matrix
    Set M = Identity(2)
    Dim V as Vector

    ‘ Create a one element Vector
    Set V = CreateVector(Array(2))

    Dim Result as Matrix

    ExpectError
    Set Result = M.ReplaceRow(1, V)
End Sub

As you can see it is very straightforward. The ExpectError statement is a special type of assertion, one that ensures there will be an error before the test subroutine ends. Because we expect the final line to raise an error, no code after that line will ever execute, so if you want to use multiple assertions in a test, make sure you only have one ExpectError statement, and that the error causing code is the final statement in the subroutine.

In the next chapter we will discuss making a custom assertion to give us better diagnostic information if we find a failure in our custom code.

1
$ 0.00
Avatar for Beakerboy
2 years ago

Comments