views:

594

answers:

6

I'm still learning the dark arts of TDD and recently I've been trying to learn how to do TDD in VB6 and what I basically narrow down the list to was the free simplyvbunit and the most costly vbunit3.

My application is an richtext editor with plenty of 3rd party dll and I was scouring high and low in Google to find how to do unit test this exe file.

So my question is how do you unit test an exe file? Especially in the context for VB6 and if you have any good example with vbunit3 or simplyvbunit, you're simply a lifesaver as I'm drowing in the material right now and I still can't write one unit test yet :(

Edit

Actually the app consists of many forms, modules and class modules and when I compile it, it of course becomes nice neatly packaged .EXE file. And to make things more complicated there are quite a number of global variables flying around.

But my main intention is to unit test all or most breakable part of the code. And i want to ensure that i can keep the test and the code separate. So i thought that the best way to do is, is to somehow directly test the exe via add reference, etc.

Is there a better way to do this?

+5  A: 

There is a difference between unit tests and integration tests. You don't unit test an executable. You unit test small, self-contained units of computation, like a method or a procedure, depending on what language you are using. An integration test would test larger components, like APIs, third-party components, or even executables to make sure that they work as expected for a given set of inputs (good or bad). While you can do some integration testing of APIs or plug-in components with unit testing tools, I don't think you'll find many unit testing tools that work to test executables. There are other types of test tools that will do a better job at this. Simply writing scripts that provide different types of inputs and check their outputs may be sufficient for many scenarios.

If you want to learn more about TDD and unit testing, you should apply it to functions or procedures in VB6 -- although, I'd recommend VB.NET (or C#) and doing object-oriented development. Typically the tools are oriented towards OO-style programming.

tvanfosson
@tvan, but all my functions are compiled in the exe so how do i test those functions that are in the exe? thanks.
melaos
Test before you compile. When I write a program I have a project that is a class library of all of my functionality. I have another project that contains unit tests. The unit test project classes are run using a test runner from the unit testing tool and test the library classes not the exe.
tvanfosson
-1 for not answering his question about TEST DRIVEN DEVELOPMENT. which involves a mix of intregration and unit testing. Don't be so dogmatic.
RS Conley
@RS -- given the title, there seemed to be some confusion about what unit testing is. I chose to try and clarify rather than add to it. Of course, there's a lot of non-unit testing in projects using TDD -- acceptance testing, performance testing. Just write the tests first, driving development.
tvanfosson
This type of general answer sends him down the wrong path in finding out how to use TDD with Visual BASIC 6. Note the first comment repeats the question about the EXE.
RS Conley
@tvan, well the app consists of many forms, class modules and modules. so in my case what's the best method to unit test while separating test and code? thanks.
melaos
I think @RS Conley is on the right track with his answer -- and it's more than I can put in a comment anyway. Essentially, you need to migrate your logic to a DLL that can be linked with your unit test suite. If you end up having to do a major restructure, you might want to consider moving to .NET
tvanfosson
A: 

About the only useful piece of advice I might be able to give is to pick up Michael Feathers Working Effectively with Legacy Code. I think your biggest challenge is going to be your toolset, as I know the tools for VB6 unit testing just aren't as strong.

You could also try asking on the TDD Yahoo! List as I know at least a couple of people are using vbunit3 on there.

Cory Foy
Maybe link to the book on Amazon or somewhere?
MarkJ
Done. Thanks for the suggestion.
Cory Foy
+1  A: 

ActiveX Controls in VB are great time savers however they are the bane of effective test driven development.

In order to effectively test a entire VB6 application ideally you need to have a design where the EXE is a thin shell over a ActiveX DLL that does all the work. The forms implement a interface and register themselves with the DLL. So if you have Order Entry Form, it will implement that IOrderEntryForm interface and it's events will call methods on the OrderEntry Class located in MyAppUI dialog.

To emphasize in Visual Basic 6, FORMS can IMPLEMENT a interface. The form then registers itself with a UI Class in it's LOAD event. The form's events (like MyButton_Click) calls methods on the UI Class. The UI Class using the methods of the Form Interface to change what is displayed. It is extra work but it saves a lot of time for testing. Also maintenance as you can change what the form looks like as long the implemented interface remain the same.

This also means that before you have something like MYEXE->MyActiveXDLL will turn into MYEXE->MyUIDLL->MyActiveXDLL.

For your test environment you create a ActiveX DLL that mocks up the UI by creating classes that implement the various form interface. The UI DLL doesn't know the difference and you have total control over what inputs are sent and what you read.

Note that this type of design pattern is talked about here. I used it as the basis for developing and maintaining my company's CAD/CAM application for metal cutting machines.

Third party ActiveX Controls are the bane of this scheme. This is because the code doing the heavy lifting is inside the control itself. The more sophisticated the ActiveX control the worse the problem is. The trend at my company is to reduce our reliance on third party controls in favor of in-house applications.

However like any algorithm and design pattern this involves a judgment call. How many issues do you get in the areas of your software involving the rich text control. If not many then you can probably get away with a test script either manual or automated (i.e. sending key strokes to the application) and use a unit test framework for the rest.

The critical element of using Unit Testing your ENTIRE application is to stuff as much of it as you can behind interfaces. Just do what you can for now and make note of the areas you want to change for when you do future development. Don't despair if you don't have 100% coverage right away or even for the next year.

RS Conley
sounds interesting! hope my newbie vb6 skill is enough to carry me through this. thanks.
melaos
Based on your comments in tvan answer, I think you have a good shot at doing this. Just make two test projects (EXE and ActiveX DLL) to get the hang of using the implements keyword for forms.
RS Conley
+1  A: 

Another technique to use is to make you application an ActiveX EXE. Your unit test app can then reference your application as if it were an ActiveX DLL. You'll need to do quite a bit of research to get this to work properly as its a while since I last worked with VB6 and I'm sure there were a few tricks to get it working.

quamrana
Sounds interesting but i think i might need to look at some code examples to see how to do this. It's Googling time. thanks :)
melaos
A: 

Of course you can unit test an individual EXE. Look at how many applications are comprised of multiple EXEs.

As for the 3rd party components, how do you address testing with standard VB6 components? Other MS components? Same thing with a 3rd party component.

Bob
A: 

And to make things more complicated there are quite a number of global variables flying around.

The first refactoring is transfer the global variables to a class in a ActiveX DLL. The instancing property of that class needs to be set to GLOBAL MULTIUSE. When set the EXE to reference the ActiveX the variables will be still be global however you when you rip out your EXE to replace it with a test harness, the harness can access the global variables.

Once you have the tests going you can do further refactoring to reduce the number of global variables.

RS Conley