Skip to content
lucas-v edited this page Sep 12, 2013 · 2 revisions

As we could not find any tutorial on the Internet specific to VBA Unit, here is our try to pass our knowledge around.

Introduction

VBA Unit is a framework for unit testing in VBA Projects, very much inspired by the famous JUnit written in and for Java. It is rather old and not maintained anywore, but it works and it is useful.

It consists in a variety of modules and class modules that just need to be imported in the workbook you are working in.

They are embedded by default in VBAToolKit.

How does it work

Name logistics
  • The unit tests are written exclusively in Tester modules.
  • The Tester modules are class modules that must respect the template of the TesterTemplate module
  • The Tester modules must have their name ending with Tester
  • The unit tests are the Subs in a Tester module that have their name beginning with Test
The Tester template

This template has two important subroutines to us :

  • The ITestCase_SetUp() subroutine will be run before each unit test : it is typically used to create the test environment.

  • The ITestCase_TearDown() subroutine will be run after each unit test : it is typically used to wipe clean the test environment.

Other parts of the template are worth knowing :

  • The TestNothing() subroutine is just here for example purporses. You shall delete it or replace it by a proper test.

  • The ITestCase_RunTest() subroutine is a little bit special, as its code will not be written by the developer ! More on that later.
    It runs all the tests that have been written in the module.

Writing a test
  • For any failure to be recorded, a unit test Sub has to use one of the two satements provided by VBA Unit :

    • mAssert.Should (Condition As Boolean, Optional Comment As String)

    • mAssert.Equals (Actual As Variant, Expected As Variant, Optional Comment As String)

  • The Equals statement is generally nice to use as it prints the actual and expected value when a test fails.

Running the tests
  • In the "Immediate Window" of VBA IDE, type prep and press Enter.

    • In each Tester module, the ITestCase_RunTest() and ITest_Suite() subroutine will get updated with the Subs whose name begins with Test.

    • It is recommended to type prep every time you want to run the tests, even though (you could swear !) you did not change any name or deleted any test.

  • In the "Immediate Window" of VBA IDE, type run and press Enter.

    • All the tests will be ran. Then, VBA Unit will display a list of the tests that failed and their associated comments.

Tips

  • When you're working on a class or module, you certainly don't need to re-run all the tests all the time. You can run a sole Tester class by specifying it as a parameter for the run command: run("MyClassTester"). Don't forget sometimes to run all the tests, particularly just before a commit!

  • It is also possible to compose a particular Test suite. Create a Sub in a standard Module to:

  1. Create an instance of the TestSuite class Dim mySuite as new TestSuite.
  2. Add test classes with mySuite.AddTest("MyClassTester") or specific methods with mySuite.AddTest("MyClassTester","testMethodName").
  3. Run this specific Test Suite with mySuite.Manager.Run(mySuite).
  • Sometimes, you might want to run only one Test sub in a Tester class, but you still need the Setup and Teardown. Instead of commenting manually all the subs you don't need, just copy paste all the code of the class in a new Tester class, remove all the subs you don't want, and run this new Tester class.

  • When an error occurs in one unit test that was not ready for it, it will break the whole testing sequence. This is both unpleasant and time consuming. You may want to systematically use error handlers with mAssert.Should Not,"Unexepected error " & err.Number & " in " & err.Source : " & err.Description statements in your test Subs.

  • If it happens anyhow, some weird error messages may pop-up the next time you do your prep run. This is usually caused by the Test folder not being empty. Delete everything in it manually, and do prep run again.

  • It's impossible to isolate VBAUnit in its own VBA Project. Due to strict dependance relation between VBA projects, it's impossible to not include VBAUnit into the project under test. Tests classes needs to call VBAUnit, and ClassLister in VBAUnit calls Tests classes. As a workaround, it is certainly possible to create a TestProject including Tester classes and VBAUnit modules to separate the project under test and the test project

  • When testing Excel workbooks containing macros, the test may be longer because VBA IDE displays the code panes of the opened Excel workbook. Solution: close all code panes from the Excel templates used for test.