In a previous post about the “VB6 problem” I wrote that salvaging business critical classic Visual Basic applications involved these steps:

  1. Build it
  2. Test it
  3. Change it
  4. Repeat

That post (Setting up a VB6 Environment) concerned the first step and will take you through setting up an environment which can build legacy applications using Visual Studio 6. This post starts the discussion about the second step: testing.

I’ll start by repeating a critical thing to remember about legacy code: in its current state, the legacy code supports today’s business.

Consider the case where that statement is not true. Imagine that the legacy application does not support today’s business. If this were true then it would follow that either the business is failing or the application is no longer being used.

Although the application supports today’s business, we often feel that the application could support the business better. An application could be more efficient in terms of computing or human resources by taking less time to run or interact with. We may want to capture new business by adding features. Whatever the changes and our reasons for them, we need to make these changes without breaking the current functionality, and that’s where testing comes in. We can write tests to characterize the application’s current behavior. We assume this behavior is correct because it supports today’s business. Then we make changes and re-run our tests to ensure that we haven’t broken anything in the process.

We must take this characterization step even when we don’t assume that the legacy code is “correct by default”. If we are changing the code to fix a long standing bug, we still want to know how the code behaves today. Once we have characterized the current behavior with a test, we can change the test to expect the desired behavior. Finally, we change the code to correctly express the new behavior.

Before we can apply these concepts to the specific case of salvaging classic Visual Basic code we need to know more about the testing tools available for VB6. In this post we will look at a specific unit testing tool for Visual Basic called SimplyVBUnit. SimplyVBUnit is an MIT licensed open source project, which is actively maintained (the most recent update as of this writing was April 18, 2015–not that long ago at all). There are actually a couple more unit testing frameworks for VB6, but SimplyVBUnit seems like a good way to get our feet wet.

Install

If you followed my first guide to setting up a VB6 environment, then you will want to install SimplyVBUnit inside XP Mode. Use the Start Menu to select Windows Virtual PC and then Windows XP Mode. (If you set up your environment differently, then I will trust you to install it wherever is best for your environment.)

The SimplyVBUnit project provides an installer program, so fire up IE8 and download the latest version from SourceForge. You may need to click a little warning banner to allow the download.

Download SimplyVBUnit
Download SimplyVBUnit

Once the download completes double click the installer to run. Again, you may have to click through a security warning to let XP know you really want to install.

SimplyVBUnit Setup Wizard
SimplyVBUnit Setup Wizard

The setup wizard is easy to use, just click Next until the wizard completes. Unfortunately, the installer is not the end of the story.

SimplyVBUnit has a decent wiki on SourceForge. This wiki includes a page on the installation and a few on setting up tests. The installation page reads like release notes and pretty much just tells us to run the wizard. When we get to the new project instructions, the very first instruction shows a SimplyVBUnit Project template in the VB6 New Project dialog. However, I don’t see that on my system after completing the wizard.

No Template
No Template

To see the template, you will need to take the following additional steps inside XP Mode:

  1. Open My Computer
  2. Navigate to C:\Program Files\SimplyVBUnit 4.1\Source\Projects
  3. Copy all files in this folder.
  4. Paste these files in C:\Program Fies\Microsoft Visual Studio\VB98\Template\Projects
Install Template
Install Template

Now when you start VB6, the template should appear. Close Visual Studio, then log off of XP Mode so that we can start experimenting with SimplyVBUnit.

Create Test Project

Now start VB6 as a virtualized application. Once VB6 starts, you should be able to follow along with the getting started guide on the Wiki. First, create a new SimplyVBUnit Project. Next use the Tools menu to select Options, then select the General tab in the dialog that appears. Change the Error Trapping option to Break on Unhandled Errors. Click Ok.

Now you can use the play button to start debugging. The SimplyVBUnit test runner will launch and you can click Run. Your test run should indicate success, since you currently have no tests, and therefore no test failures.

SimplyVBUnit Test Runner
SimplyVBUnit Test Runner

Create Production Library

Although our overall goal is to learn how to salvage legacy code, our immediate goal is to learn about SimplyVBUnit. So let’s take the easy path and continue to follow along with the wiki by creating a brand new class library to test.

Stop the debugger if it is still running. Next, use the File menu to select Add Project..., then choose ActiveX DLL. By default, this project will be created with the name Project1, and contain a class called Class1. I can’t stand such terrible names, even during a demo, so I will make up some better ones: CoolCalculator for the project and Calculator for the class.

With that very important step completed, we can continue by adding a reference to CoolCalculator in the SimplyVBUnitTesting project. Select SimplyVBUnitTesting in the Project Group pane, and then use the Project menu to select References.... CoolCalculator should be near the top of the Available References list, with its check box unchecked. Check the box, then click Ok.

Add References
Add References

The wiki advises us to save our work so far, and that seems like a good idea. Use the File menu to select Save Project Group. VB6 starts by saving each file, and by default it wants to put the files in the VB98 folder under Program Files. This is no good, navigate to My Documents and create a folder called CalculatorDemo and save your files there. You will need to save the Calculator class, the CoolCalculator project file, the frmTestRunner form from SimplyVBUnit, and the SimplyVBUnitTesting project file–also from the SimplyVBUnit template, and finally you need to save the project group file using the name CalculatorDemo.

Create Test Class

Now we will create a test class and use it to drive a feature in CoolCalculator. Right click on SimplyVBUnitTesting in the project group, and select Add then Class Module. Make sure Class Module is selected in the dialog that opens, and click Open.

Once again, this creates a class called Class, so rename it to CalculatorTests. Next we will register this test class with the test runner frmTestRunner. Right click on frmTestRunner and select View Code.

The frmTestRunner contains a stub for Form_Load with comments that explain how to setup a test case (which we have already started). SimplyVBUnit also provides a comment demonstrating how to register a test case with the runner. Register our test case now by adding the following code to the line below the example comment:

AddTest New CalculatorTests

Now we can add a test to our test suite. Let’s make sure our calculator can add. Type the following code into the CalculatorTests class.

Option Explicit

Public Sub Add_Two_Numbers()
Dim calc As New Calculator

Dim actual As Integer
actual = calc.Add(1, 1)

Assert.That actual, Iz.EqualTo(2), "1 + 1 = 2"
End Sub

This code creates a new Calculator instance, uses it to add 1 to itself, then constructs a test assertion to verify the result. We can hit the play button to see what happens when we try to run this test. We expect that the test runner will try to run the test, since we registered it. We also expect that the test will fail, since Calculator has no implementation.

Test Failure
Test Failure

As expected, the test runs then fails as predicted. If we click Ok on the compilation error dialog, we will drop into the debugger at the beginning of the Add_Two_Numbers method (yellow highlight). Notice also that the .Add method is highlighted in blue.

Having verified our expectations, lets stop the debugger and add some code to the production library. Open the Calculator class and add these lines of code:

Option Explicit

Public Function Add(ByVal left As Integer, ByVal right As Integer) As Integer

End Function

This code should get us past the compilation error, because it will provide the method Add, which is expected by the test. However, we still expect the test to fail, because Add has no body, and therefore we expect it to return the default value for integer, which is 0.

Another Failure
Another Failure

Once again, the test runner confirms our expectations. So lets add a little more code to see if we can get the test to pass. Stop the debugger and add the following line of code to the Add method body.

Add = left + right

Use the play button to run the test again. At this point we expect that the test should pass. The test runner confirms our expectation.

Passing Test
Passing Test

The wiki goes on to explain Testing Multiple Scenarios, which looks to me like data driven or theory tests, depending on which jargon you prefer. That’s a nice feature, but I’ll leave its exploration as an exercise for the reader.

We are done with the CalculatorDemo project for now, so close VB and save any changes.

Review

In this post we used the classic Visual Basic environment that we created in Setting up a VB6 Environment to explore a native Visual Basic testing tool called SimplyVBUnit. Although the SimplyVBUnit installer did not automatically copy the testing templates for us, we were able to work our way past that problem and build an example test which we used to drive the creation of a simple calculator feature.

Although working with SimplyVBUnit was relatively simple, there are two things to consider before choosing it as the means to salvage VB6 code and make it safe to update. First, remember that the example we built for this post did not focus on characterizing legacy code. Instead, we took the easy path of creating a new project so that we could become familiar with SimplyVBUnit mechanics. Before going further, it makes sense to explore characterizing an existing code base with SimplyVBUnit. What do I even mean by characterization, and might there be pitfalls that we have not yet uncovered on the easy path?

Second, we should ask ourselves if native VB6 unit testing is the way to go. As discussed in the first Postmodern VB6 post, our goal when working with VB6 should be to get to a state where we aren’t working with VB6 anymore. If we accept that goal, and plan to migrate to a new platform, then we should seriously consider writing our tests in the new platform. After all, if we succeed in migrating, then all VB6 code will be retired, including the tests we are writing now. Furthermore, all the tests we write in VB6 will just be more code we need to convert to the new platform later. Even if we are able to figure out how to add SimplyVBUnit tests to an existing codebase, then we should still explore the possibility of using a testing tool which is native to our target platform.

Those considerations aside, it’s good to have SimplyVBUnit in our tool set, and I hope this post makes it easier to started.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s