<p>With the code, forms and data inside the same database I am wondering what are the best practices to design a suite of tests for a Microsoft Access application (say for Access 2007).</p>

<p>One of the main issues with testing forms is that only a few controls have a <code>hwnd</code> handle and other controls only get one they have focus, which makes automation quite opaque since you cant get a list of controls on a form to act on.</p>

<p>Any experience to share?</p>

[{'answer_id': 47404, 'author': 'Knox', 'author_id': 4873, 'author_profile': 'https://Stackoverflow.com/users/4873', 'pm_score': 2, 'selected': False, 'text': "<p>I would design the application to have as much work as possible done in queries and in vba subroutines so that your testing could be made up of populating test databases, running sets of the production queries and vba against those databases and then looking at the output and comparing to make sure the output is good.  This approach doesn't test the GUI obviously, so you could augment the testing with a series of test scripts (here I mean like a word document that says open form 1, and click control 1) that are manually executed.</p>\n\n<p>It depends on the scope of the project as the level of automation necessary for the testing aspect.</p>\n"}, {'answer_id': 47407, 'author': 'Xian', 'author_id': 4642, 'author_profile': 'https://Stackoverflow.com/users/4642', 'pm_score': 1, 'selected': False, 'text': '<p>I have not tried this, but you could attempt to <a href="http://office.microsoft.com/en-us/access/HA101314691033.aspx" rel="nofollow noreferrer">publish your access forms as data access web pages to something like sharepoint</a> or <a href="http://office.microsoft.com/en-us/access/HA010547311033.aspx" rel="nofollow noreferrer">just as web pages</a> and then use an tool such as <a href="http://selenium.openqa.org/" rel="nofollow noreferrer">selenium</a> to drive the browser with a suite of tests.</p>\n\n<p>Obviously this is not as ideal as driving the code directly through unit tests, but it may get you part of the way. good luck</p>\n'}, {'answer_id': 67541, 'author': 'David-W-Fenton', 'author_id': 9787, 'author_profile': 'https://Stackoverflow.com/users/9787', 'pm_score': -1, 'selected': False, 'text': "<p>Data Access Pages have been deprecated by MS for quite some time, and never really worked in the first place (they were dependent on the Office Widgets being installed, and worked only in IE, and only badly then).</p>\n\n<p>It is true that Access controls that can get focus only have a window handle when they have the focus (and those that can't get focus, such as labels, never have a window handle at all). This makes Access singularly inappropriate to window handle-driven testing regimes.</p>\n\n<p>Indeed, I question why you want to do this kind of testing in Access. It sounds to me like your basic Extreme Programming dogma, and not all of the principles and practices of XP can be adapted to work with Access applications -- square peg, round hole.</p>\n\n<p>So, step back and ask yourself what you're trying to accomplish and consider that you may need to utilize completely different methods than those that are based on the approaches that just can't work in Access.</p>\n\n<p>Or whether that kind of automated testing is valid at all or even useful with an Access application.</p>\n"}, {'answer_id': 69026, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>Access is a COM application. Use COM, not Windows API. to test things in Access.</p>\n\n<p>The best Test environment for an Access Application is Access. All of your Forms/Reports/Tables/Code/Queries are available, there is a scripting language similar to MS Test (Ok, you probably don't remember MS Test), there is database environment for holding your test scripts and test results, and the skills you build here are transferable to your application.</p>\n"}, {'answer_id': 70572, 'author': 'Philippe Grondier', 'author_id': 11436, 'author_profile': 'https://Stackoverflow.com/users/11436', 'pm_score': 4, 'selected': False, 'text': '<p>I appreciated knox\'s and david\'s answers. My answer will be somewhere between theirs: just make <strong><em>forms that do not need to be debugged</em></strong>!</p>\n\n<p>I think that forms should be exclusively used as what they are basically, meaning graphic interface <strong><em>only</em></strong>, meaning here that they do not have to be debugged! The debugging job is then limited to your VBA modules and objects, which is a lot easier to handle. </p>\n\n<p>There is of course a natural tendency to add VBA code to forms and/or controls, specially when Access offers you these great "after Update" and "on change" events, but I definitely advise you <strong>not</strong> to put any form or control specific code in the form\'s module. This makes further maintenance and upgrade very costy, where your code is split between VBA modules and forms/controls modules.</p>\n\n<p>This does not mean you cannot use anymore this <code>AfterUpdate</code> event! Just put standard code in the event, like this:</p>\n\n<pre><code>Private Sub myControl_AfterUpdate()  \n    CTLAfterUpdate myControl\n    On Error Resume Next\n    Eval ("CTLAfterUpdate_MyForm()")\n    On Error GoTo 0  \nEnd sub\n</code></pre>\n\n<p>Where:</p>\n\n<ul>\n<li><p><code>CTLAfterUpdate</code> is a standard procedure run each time a control is updated in a form</p></li>\n<li><p><code>CTLAfterUpdateMyForm</code> is a specific procedure run each time a control is updated on MyForm</p></li>\n</ul>\n\n<p>I have then 2 modules. The first one is </p>\n\n<ul>\n<li><code>utilityFormEvents</code><br>\n where I will have my CTLAfterUpdate generic event</li>\n</ul>\n\n<p>The second one is </p>\n\n<ul>\n<li><code>MyAppFormEvents</code><br>\n containing the specific code of all specific forms of the MyApp application\n and including the CTLAfterUpdateMyForm procedure. Of course, CTLAfterUpdateMyForm\n might not exist if there are no specific code to run. This is why we turn the \n "On error" to "resume next" ...</li>\n</ul>\n\n<p>Choosing such a generic solution means a lot. It means you are reaching a high level of code normalization (meaning painless maintenance of code). And when you say that you do not have any form-specific code,  it also means that form modules are fully standardized, and their production can be <strong><em>automated</em></strong>: just say which events you want to manage at the form/control level, and define your generic/specific procedures terminology.<br>\nWrite your automation code, once for all.<br>\nIt takes a few  days of work but it give exciting results. I have been using this solution for the last 2 years and it is clearly the right one: my forms are fully and automatically created from scratch with a "Forms Table", linked to a "Controls Table".<br>\nI can then spend my time working on the specific procedures of the form, if any.</p>\n\n<p>Code normalization, even with MS Access, is a long process. But it is really worth the pain!</p>\n'}, {'answer_id': 74393, 'author': 'Ray', 'author_id': 4872, 'author_profile': 'https://Stackoverflow.com/users/4872', 'pm_score': 3, 'selected': False, 'text': '<p>Another advantage of <a href="https://stackoverflow.com/questions/47400/best-way-to-test-a-ms-access-application#69026">Access being a COM application</a> is that you can create an <a href="http://support.microsoft.com/kb/317114/en-us" rel="nofollow noreferrer">.NET application to run and test an Access application via Automation</a>. The advantage of this is that then you can use a more powerful testing framework such as <a href="http://www.nunit.org/index.php" rel="nofollow noreferrer">NUnit</a> to write automated assert tests against an Access app. </p>\n\n<p>Therefore, if you are proficient in either C# or VB.NET combined with something like NUnit then you can more easily create greater test coverage for your Access app.</p>\n'}, {'answer_id': 74492, 'author': 'Ray', 'author_id': 4872, 'author_profile': 'https://Stackoverflow.com/users/4872', 'pm_score': 2, 'selected': False, 'text': '<p>If your interested in testing your Access application at a more granular level specifically the VBA code itself then <a href="http://vb-lite-unit.sourceforge.net/" rel="nofollow noreferrer">VB Lite Unit</a> is a great unit testing framework for that purpose.</p>\n'}, {'answer_id': 1015027, 'author': 'Steve Mallory', 'author_id': 120097, 'author_profile': 'https://Stackoverflow.com/users/120097', 'pm_score': 2, 'selected': False, 'text': "<p>There are good suggestions here, but I'm surprised no one mentioned centralized error processing. You can get addins that allow for quick function/sub templating and for adding line numbers (I use MZ-tools). Then send all errors to a single function where you can log them. You can also then break on all errors by setting a single break point.</p>\n"}, {'answer_id': 6959038, 'author': 'mwolfe02', 'author_id': 154439, 'author_profile': 'https://Stackoverflow.com/users/154439', 'pm_score': 3, 'selected': False, 'text': '<p>I\'ve taken a page out of <a href="http://docs.python.org/library/doctest.html" rel="nofollow noreferrer">Python\'s doctest</a> concept and implemented a DocTests procedure in Access VBA.  This is obviously not a full-blown unit-testing solution.  It\'s still relatively young, so I doubt I\'ve worked out all the bugs, but I think it\'s mature enough to release into the wild.</p>\n\n<p>Just copy the following code into a standard code module and press F5 inside the Sub to see it in action:</p>\n\n<pre><code>\'&gt;&gt;&gt; 1 + 1\n\'2\n\'&gt;&gt;&gt; 3 - 1\n\'0\nSub DocTests()\nDim Comp As Object, i As Long, CM As Object\nDim Expr As String, ExpectedResult As Variant, TestsPassed As Long, TestsFailed As Long\nDim Evaluation As Variant\n    For Each Comp In Application.VBE.ActiveVBProject.VBComponents\n        Set CM = Comp.CodeModule\n        For i = 1 To CM.CountOfLines\n            If Left(Trim(CM.Lines(i, 1)), 4) = "\'&gt;&gt;&gt;" Then\n                Expr = Trim(Mid(CM.Lines(i, 1), 5))\n                On Error Resume Next\n                Evaluation = Eval(Expr)\n                If Err.Number = 2425 And Comp.Type &lt;&gt; 1 Then\n                    \'The expression you entered has a function name that \'\'  can\'t find.\n                    \'This is not surprising because we are not in a standard code module (Comp.Type &lt;&gt; 1).\n                    \'So we will just ignore it.\n                    GoTo NextLine\n                ElseIf Err.Number &lt;&gt; 0 Then\n                    Debug.Print Err.Number, Err.Description, Expr\n                    GoTo NextLine\n                End If\n                On Error GoTo 0\n                ExpectedResult = Trim(Mid(CM.Lines(i + 1, 1), InStr(CM.Lines(i + 1, 1), "\'") + 1))\n                Select Case ExpectedResult\n                Case "True": ExpectedResult = True\n                Case "False": ExpectedResult = False\n                Case "Null": ExpectedResult = Null\n                End Select\n                Select Case TypeName(Evaluation)\n                Case "Long", "Integer", "Short", "Byte", "Single", "Double", "Decimal", "Currency"\n                    ExpectedResult = Eval(ExpectedResult)\n                Case "Date"\n                    If IsDate(ExpectedResult) Then ExpectedResult = CDate(ExpectedResult)\n                End Select\n                If (Evaluation = ExpectedResult) Then\n                    TestsPassed = TestsPassed + 1\n                ElseIf (IsNull(Evaluation) And IsNull(ExpectedResult)) Then\n                    TestsPassed = TestsPassed + 1\n                Else\n                    Debug.Print Comp.Name; ": "; Expr; " evaluates to: "; Evaluation; " Expected: "; ExpectedResult\n                    TestsFailed = TestsFailed + 1\n                End If\n            End If\nNextLine:\n        Next i\n    Next Comp\n    Debug.Print "Tests passed: "; TestsPassed; " of "; TestsPassed + TestsFailed\nEnd Sub\n</code></pre>\n\n<p>Copying, pasting, and running the above code from a module named Module1 yields:</p>\n\n<pre class="lang-none prettyprint-override"><code>Module: 3 - 1 evaluates to:  2  Expected:  0 \nTests passed:  1  of  2\n</code></pre>\n\n<p>A few quick notes:</p>\n\n<ul>\n<li>It has no dependencies (when used from within Access)</li>\n<li>It makes use of <code>Eval</code> which is a function in the Access.Application object model; this means you <em>could</em> use it outside of Access but it would require creating an Access.Application object and fully qualifying the <code>Eval</code> calls</li>\n<li>There are some <a href="https://stackoverflow.com/questions/6440912/ms-access-vba-brain-teaser">idiosyncrasies associated with <code>Eval</code></a> to be aware of</li>\n<li>It can only be used on functions that return a result that fits on a single line</li>\n</ul>\n\n<p>Despite its limitations, I still think it provides quite a bit of bang for your buck.  </p>\n\n<p><strong>Edit</strong>:  Here is a simple function with "doctest rules" the function must satisfy.</p>\n\n<pre><code>Public Function AddTwoValues(ByVal p1 As Variant, _\n        ByVal p2 As Variant) As Variant\n\'&gt;&gt;&gt; AddTwoValues(1,1)\n\'2\n\'&gt;&gt;&gt; AddTwoValues(1,1) = 1\n\'False\n\'&gt;&gt;&gt; AddTwoValues(1,Null)\n\'Null\n\'&gt;&gt;&gt; IsError(AddTwoValues(1,"foo"))\n\'True\n\nOn Error GoTo ErrorHandler\n\n    AddTwoValues = p1 + p2\n\nExitHere:\n    On Error GoTo 0\n    Exit Function\n\nErrorHandler:\n    AddTwoValues = CVErr(Err.Number)\n    GoTo ExitHere\nEnd Function\n</code></pre>\n'}, {'answer_id': 21731961, 'author': 'paulroho', 'author_id': 571213, 'author_profile': 'https://Stackoverflow.com/users/571213', 'pm_score': 3, 'selected': False, 'text': '<p>Although that being a very old answer:</p>\n\n<p>There is <a href="http://accunit.access-codelib.net" rel="noreferrer">AccUnit</a>, a specialized Unit-Test framework for Microsoft Access.</p>\n'}, {'answer_id': 28347000, 'author': 'RubberDuck', 'author_id': 3198973, 'author_profile': 'https://Stackoverflow.com/users/3198973', 'pm_score': 6, 'selected': True, 'text': '<h1>1. Write Testable Code</h1>\n\n<p>First, stop writing business logic into your Form\'s code behind. That\'s not the place for it. It can\'t be properly tested there. In fact, you really shouldn\'t have to test your form itself at all. It should be a dead dumb simple view that responds to User Interaction and then delegates responsibility for responding to those actions to another class that <strong><em>is</em></strong> testable.</p>\n\n<p>How do you do that? Familiarizing yourself with the <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" rel="noreferrer">Model-View-Controller pattern</a> is a good start. </p>\n\n<p><img src="https://i.stack.imgur.com/iY37U.png" alt="Model View Controller diagram"></p>\n\n<p>It can\'t be done <em>perfectly</em> in VBA due to the fact that we get either events or interfaces, never both, but you can get pretty close. Consider this simple form that has a text box and a button.</p>\n\n<p><img src="https://i.stack.imgur.com/ts6jl.png" alt="simple form with text box and button"></p>\n\n<p>In the form\'s code behind, we\'ll wrap the TextBox\'s value in a public property and re-raise any events we\'re interested in.</p>\n\n<pre><code>Public Event OnSayHello()\nPublic Event AfterTextUpdate()\n\nPublic Property Let Text(value As String)\n    Me.TextBox1.value = value\nEnd Property\n\nPublic Property Get Text() As String\n    Text = Me.TextBox1.value\nEnd Property\n\nPrivate Sub SayHello_Click()\n    RaiseEvent OnSayHello\nEnd Sub\n\nPrivate Sub TextBox1_AfterUpdate()\n    RaiseEvent AfterTextUpdate\nEnd Sub\n</code></pre>\n\n<p>Now we need a model to work with. Here I\'ve created a new class module named <code>MyModel</code>. Here lies the code we\'ll put under test. Note that it naturally shares a similar structure as our view.</p>\n\n<pre><code>Private mText As String\nPublic Property Let Text(value As String)\n    mText = value\nEnd Property\n\nPublic Property Get Text() As String\n    Text = mText\nEnd Property\n\nPublic Function Reversed() As String\n    Dim result As String\n    Dim length As Long\n\n    length = Len(mText)\n\n    Dim i As Long\n    For i = 0 To length - 1\n        result = result + Mid(mText, (length - i), 1)\n    Next i\n\n    Reversed = result\nEnd Function\n\nPublic Sub SayHello()\n    MsgBox Reversed()\nEnd Sub\n</code></pre>\n\n<p>Finally, our controller wires it all together. The controller listens for form events and communicates changes to the model and triggers the model\'s routines.</p>\n\n<pre><code>Private WithEvents view As Form_Form1\nPrivate model As MyModel\n\nPublic Sub Run()\n    Set model = New MyModel\n    Set view = New Form_Form1\n    view.Visible = True\nEnd Sub\n\nPrivate Sub view_AfterTextUpdate()\n    model.Text = view.Text\nEnd Sub\n\nPrivate Sub view_OnSayHello()\n    model.SayHello\n    view.Text = model.Reversed()\nEnd Sub\n</code></pre>\n\n<p>Now this code can be run from any other module. For the purposes of this example, I\'ve used a standard module. I highly encourage you to build this yourself using the code I\'ve provided and see it function.</p>\n\n<pre><code>Private controller As FormController\n\nPublic Sub Run()\n    Set controller = New FormController\n    controller.Run\nEnd Sub\n</code></pre>\n\n<hr>\n\n<p>So, that\'s great and all <strong><em>but what does it have to do with testing?!</em></strong> Friend, it has <strong><em>everything</em></strong> to do with testing. What we\'ve done is make our code <em>testable</em>. In the example I\'ve provided, there is no reason what-so-ever to even try to test the GUI. The only thing we really need to test is the <code>model</code>. That\'s where all of the real logic is. </p>\n\n<p>So, on to step two.</p>\n\n<h1>2. Choose a Unit Testing Framework</h1>\n\n<p>There aren\'t a lot of options here. Most frameworks require installing COM Add-ins, lots of boiler plate, weird syntax, writing tests as comments, etc. That\'s why I got involved in <a href="https://github.com/rubberduck-vba/Rubberduck" rel="noreferrer">building one myself</a>, so this part of my answer isn\'t impartial, but I\'ll try to give a fair summary of what\'s available.</p>\n\n<ol>\n<li><p><a href="http://accunit.access-codelib.net/" rel="noreferrer">AccUnit</a></p>\n\n<ul>\n<li>Works only in Access.</li>\n<li>Requires you to write tests as a strange hybrid of comments and code. (no intellisense for the comment part.</li>\n<li>There <strong><em>is</em></strong> a graphical interface to help you write those strange looking tests though.</li>\n<li>The project has not seen any updates since 2013.</li>\n</ul></li>\n<li><p><a href="http://vb-lite-unit.sourceforge.net/" rel="noreferrer">VB Lite Unit</a>\nI can\'t say I\'ve personally used it. It\'s out there, but hasn\'t seen an update since 2005.</p></li>\n<li><p><a href="http://xlvbadevtools.codeplex.com/" rel="noreferrer">xlUnit</a>\nxlUnit isn\'t awful, but it\'s not good either. It\'s clunky and there\'s lots of boiler plate code. It\'s the best of the worst, but it doesn\'t work in Access. So, that\'s out.</p></li>\n<li><p>Build your own framework</p>\n\n<p>I\'ve <a href="https://codereview.stackexchange.com/questions/62781/unit-testing-in-vba">been there and done that</a>. It\'s probably more than most people want to get into, but it is completely possible to build a Unit Testing framework in Native VBA code.</p></li>\n<li><p><a href="https://github.com/rubberduck-vba/Rubberduck/wiki/Unit-Testing" rel="noreferrer">Rubberduck VBE Add-In\'s Unit Testing Framework</a><br>\n<em>Disclaimer: I\'m one of the co-devs</em>.</p>\n\n<p>I\'m biased, but this is by far my favorite of the bunch.</p>\n\n<ul>\n<li>Little to no boiler plate code.</li>\n<li>Intellisense is available.</li>\n<li>The project is active.</li>\n<li>More documentation than most of these projects.</li>\n<li>It works in most of the major office applications, not just Access.</li>\n<li>It is, unfortunately, a COM Add-In, so it has to be installed onto your machine.</li>\n</ul></li>\n</ol>\n\n<h1>3. Start writing tests</h1>\n\n<p>So, back to our code from section 1. The only code that we <em>really</em> needed to test was the <code>MyModel.Reversed()</code> function. So, let\'s take a look at what that test could look like. (Example given uses Rubberduck, but it\'s a simple test and could translate into the framework of your choice.)</p>\n\n<pre><code>\'@TestModule\nPrivate Assert As New Rubberduck.AssertClass\n\n\'@TestMethod\nPublic Sub ReversedReversesCorrectly()\n\nArrange:\n    Dim model As New MyModel\n    Const original As String = "Hello"\n    Const expected As String = "olleH"\n    Dim actual As String\n\n    model.Text = original\n\nAct:\n    actual = model.Reversed\n\nAssert:\n    Assert.AreEqual expected, actual\n\nEnd Sub\n</code></pre>\n\n<h2>Guidelines for Writing Good Tests</h2>\n\n<ol>\n<li>Only test one thing at a time.</li>\n<li>Good tests only fail when there is a bug introduced into the system or the requirements have changed.</li>\n<li>Don\'t include external dependencies such as databases and file systems. These external dependencies can make tests fail for reasons outside of your control. Secondly, they slow your tests down. If your tests are slow, you won\'t run them.</li>\n<li>Use test names that describe what the test is testing. Don\'t worry if it gets long. It\'s most important that it is descriptive.</li>\n</ol>\n\n<hr>\n\n<p>I know that answer was a little long, and late, but hopefully it helps some people get started in writing unit tests for their VBA code.</p>\n'}, {'answer_id': 32775460, 'author': 'AndrewM', 'author_id': 3133514, 'author_profile': 'https://Stackoverflow.com/users/3133514', 'pm_score': 2, 'selected': False, 'text': '<p>I find that there are relatively few opportunities for unit testing in my applications.  Most of the code that I write interacts with table data or the filing system so is fundamentally hard to unit test.  Early on, I tried an approach that may be similar to mocking (spoofing) where I created code that had an optional parameter.  If the parameter was used, then the procedure would use the parameter instead of fetching data from the database.  It is quite easy to set up a user defined type that has the same field types as a row of data and to pass that to a function.  I now have a way of getting test data into the procedure that I want to test.  Inside each procedure there was some code that swapped out the real data source for the test data source.  This allowed me to use unit testing on a wider variety of function, using my own unit testing functions.  Writing unit test is easy, it is just repetitive and boring.  In the end, I gave up with unit tests and started using a different approach.</p>\n\n<p>I write in-house applications for myself mainly so I can afford wait till issues find me rather than having to have perfect code.  If I do write applications for customers, generally the customer is not fully aware of how much software development costs so I need a low cost way of getting results.   Writing unit tests is all about writing a test that pushes bad data at a procedure to see if the procedure can handle it appropriately.  Unit tests also confirm that good data is handled appropriately.  My current approach is based on writing input validation into every procedure within an application and raising a success flag when the code has completed successfully.  Each calling procedure checks for the success flag before using the result.  If an issue occurs, it is reported by way of an error message.  Each function has a success flag, a return value, an error message, a comment and an origin.  A user defined type (fr for function return) contains the data members.  Any given function many populate only some of the data members in the user defined type.  When a function is run, it  usually returns success = true and a return value and sometimes a comment.  If a function fails, it returns success = false and an error message.  If a chain of functions fails, the error messages are daisy changed but the result is actually a lot more readable that a normal stack trace.  The origins are also chained so I know where the issue occurred.   The application rarely crashes and accurately reports any issues.  The result is a hell of a lot better than standard error handling.  </p>\n\n<pre><code>Public Function GetOutputFolder(OutputFolder As eOutputFolder) As  FunctRet\n\n        \'///Returns a full path when provided with a target folder alias. e.g. \'temp\' folder\n\n            Dim fr As FunctRet\n\n            Select Case OutputFolder\n            Case 1\n                fr.Rtn = "C:\\Temp\\"\n                fr.Success = True\n            Case 2\n                fr.Rtn = TrailingSlash(Application.CurrentProject.path)\n                fr.Success = True\n            Case 3\n                fr.EM = "Can\'t set custom paths – not yet implemented"\n            Case Else\n                fr.EM = "Unrecognised output destination requested"\n            End Select\n\n    exitproc:\n        GetOutputFolder = fr\n\n    End Function\n</code></pre>\n\n<p>Code explained.\neOutputFolder is a user defined Enum as below</p>\n\n<pre><code>Public Enum eOutputFolder\n    eDefaultDirectory = 1\n    eAppPath = 2\n    eCustomPath = 3\nEnd Enum\n</code></pre>\n\n<p>I am using Enum for passing parameters to functions as this creates a limited set of known choices that a function can accept.  Enums also provide intellisense when entering parameters into functions.  I suppose they provide a rudimentary interface for a function.</p>\n\n<pre><code>\'Type FunctRet is used as a generic means of reporting function returns\nPublic Type  FunctRet\n    Success As Long     \'Boolean flag for success, boolean not used to avoid nulls\n    Rtn As Variant      \'Return Value\n    EM As String        \'Error message\n    Cmt As String       \'Comments\n    Origin As String    \'Originating procedure/function\nEnd Type\n</code></pre>\n\n<p>A user defined type such as a FunctRet also provides code completion which helps.  Within the procedure, I usually store internal results to an anonymous internal variable (fr) before assigning the results to the return variable (GetOutputFolder).  This makes renaming procedures very easy as only the top and bottom have be changed.  </p>\n\n<p>So in summary, I have developed a framework with ms-access that covers all operations that involve VBA.  The testing is permanently written into the procedures, rather than a development time unit test.  In practice, the code still runs very fast.  I am very careful to optimise lower level functions that can be called ten thousand times a minute.  Furthermore, I can use the code in production as it is being developed.  If an error occurs, it is user friendly and the source and reason for the error are usually obvious.  Errors are reported from the calling form, not from some module in the business layer, which is an important principal of application design. Furthermore, I don\'t have the burden of maintaining unit testing code, which is really important when I am evolving a design rather than coding a clearly conceptualised design.  </p>\n\n<p>There are some potential issues.  The testing is not automated and new bad code is only detected when the application is run.  The code does not look like standard VBA code (it is usually shorter).  Still, the approach has some advantages.  It is far better that using an error handler just to log an error as the users will usually contact me and give me a meaningful error message.  It can also handle procedures that work with external data.  JavaScript reminds me of VBA, I wonder why JavaScript is the land of frameworks and VBA in ms-access is not.</p>\n\n<p>A few days after writing this post, I found an <a href="http://www.codeproject.com/Articles/1032569/Handling-Errors-and-Exceptions-Part-Intro" rel="nofollow">article on The CodeProject</a> that comes close to what I have written above.  The article compares and contrasts exception handling and error handling.  What I have suggested above is akin to exception handling.</p>\n'}]
['https://Stackoverflow.com/questions/47400', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3811/']