[AccessD] AccessD Digest, Vol 98, Issue 7

Jim Dettman jimdettman at verizon.net
Tue Apr 12 09:09:29 CDT 2011


John,

  If your doing any type of n-tier design, unit testing is a must and you
write the tests as you develop the objects.

  As to your point about bugs and lines of code, unit tests are very simple
and limited by nature. You only test one very specific thing with each. It's
not one all encompassing test against your entire app, but rather a series
of test (possibly thousands).

  For example, I develop a customer class, which handles CRUD operations for
customers.

  As result, I would develop four separate basic unit tests for that object:

  1. Adding a record.
  2. Deleting a record.
  3. Reading a record.
  4. Updating a record.

  Then I would develop a unit test for each of the business rules, say on
credit limit, can't delete a customer with open items, etc.

  So just for the customer object alone, I might have dozens of unit tests.

Jim. 

-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Tuesday, April 12, 2011 9:03 AM
To: Access Developers discussion and problem solving
Subject: Re: [AccessD] AccessD Digest, Vol 98, Issue 7

I guess I just don't "get it".  OTOH there are a lot of things I don't get.

When I write a class, I look at the functions that class needs to perform
it's job.  If it needs a 
function that is used elsewhere (in Access) I go to a lib to execute that
function.  To a smaller 
extent I do the same in C# (static class methods).

But in general the class functions are only used in the class.  A function
can be made to accept 
args and return a value and never modify anything external to itself.  It
would make programming 
some functionality much more complicated however.  Let's take an example.

I have records in SQL server where the record itself represents an object.
A "supervisor" 
represents a database which needs a specific process applied (address
validation).  Due to 
limitations of the third party address validation program, the sets of tens
of millions of addresses 
have to be broken down into 2 million record "chunks".  The process table is
child to the supervisor 
and each process record represents a chunk of up to 2 million records.

Address validation of a table of addresses is an extremely complex task
requiring dozens of steps. 
The Supervisor (parent) and process (child) tables contain flags to store
state, "Process X has 
completed".  It takes an entire SQL statement to write that flag back to the
appropriate table 
(parent or child) / field.  So I have a "flag class" where I initialize the
class with the PKID of 
the record that contains this data (flag), the field name, and the table
name.  Now the flag class 
can accept a data and write that data to its specific table / record /
field.

So (to get back to the subject at hand) there is a process that creates a
temporary database and a 
table to hold the tens of millions of records needing processing.  The
process builds that.  No flag 
is used, we just ask SQL server whether the objects exist and create them if
not.  When we *fill* 
that table, a piece of SQL code executed in a function.  That function takes
database / src view 
information (which it does not modify) and returns a boolean true (SQL
Server says it did the 
operation) or false (SQL Server threw an error).

However the function also logs to NLog (modifies information outside of the
function) with logging 
type of stuff such as the database name, table, number of records affected
etc.  *IF* the table 
filled, the function also directly calls the class property to set the flag
(remember the flag 
class?) saying that it successfully filled the table in the temp database.
The pro[erty actually 
calls the flag class and the flag class writes the data back to SQL server
right then and there.

The function's reason to exist is to fill a table in a temp database with
data from a view in a 
"live" database.  The function itself does not modify the parameters passed
in.  It returns a true / 
false which makes the control logic a simple if (the table filled) then
else.

However it also writes to the NLog the results for status debug and it
writes the flag saying that 
it succeeded, which is immediately written back to SQL Server.  There are
threads in other processes 
polling SQL Server every N seconds asking whether there are any processes
where flag XYZ has been 
set, IOW it is ready to move to the next stage of processing.

Could I break this down into umpteen other functions that (in the end) every
one only does one 
thing?  Of course, but I ain't gonna!

I like that the function logs its state in NLog and that the function logs
its state in the property 
and I like that the property immediately writes the information back to SQL
Server.  I went to a 
great deal of effort to get all of this stuff working this way.  I want a
system where every step of 
the process immediately logs its completion and if I stop the big picture
for any reason (power loss 
or simply shutting down the server) I can pick right up where I left off.

Each such flag is written to (initialized) from the code that loads the
class instance from SQL 
Server and then modified in the function that actually performs that step.
These process step 
functions are only used in one place, precisely and only in the class that
performs that step.  They 
will never be called from anywhere else (in fact they are private to the
class) because no other 
code anywhere in the world performs that step of address validation
processing.

As for testing... an interesting read.

http://en.wikipedia.org/wiki/Unit_testing

particularly "Unit testing limitations".  I am not here to get in a peeing
match about whether or 
not... But where is the unit test of the unit test code...  This article
claims that the unit test 
requires 2-3 lines of code for every line tested, and we all know that there
is (statistically) 1 
bug in every 20 lines of code...

Since unit testing code is code, and since it introduces 2-3 lines of test
code for every line 
tested and since there are going to be bugs in the unit test code, then we
need unit test code for 
the unit test code for the unit test code for the unit test code for...

Kind of like looking in a mirror at a reflection in a mirror behind you.

Sounds like the stuff sci-fi novels are made of.  ;)

At any rate, as a sole proprietor I have to pick a tool which can implement
the systems that I 
design.  I am not sitting at a desk collecting a paycheck regardless of what
I produce.  I do not 
have a test department, I am the test department.  I am actually fascinated
with the unit testing 
concept but I barely have the time to write the code itself, never mind code
to test the code which 
tests the code...

Whats a guy to do?

John W. Colby
www.ColbyConsulting.com

On 4/11/2011 4:09 PM, Kenneth Ismert wrote:
> John,
>
> I understand the reasoning and all however... because the code is no
longer
>> contained within the object that needs it, you now open yourself up to
the
>> old "I need to modify this method... oops... that change breaks something
>> else that uses the code".

...
-- 
AccessD mailing list
AccessD at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/accessd
Website: http://www.databaseadvisors.com




More information about the AccessD mailing list