[AccessD] AccessD Digest, Vol 98, Issue 7

Shamil Salakhetdinov shamil at smsconsulting.spb.ru
Tue Apr 12 13:02:26 CDT 2011


Hi Jim -- 

<<<
  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.
>>>
That would be called "integration tests" wouldn't they?

That above is a bit "provocative" question I must admit to "fire" new here
(?) 

Unit testing vs. Integration testing vs. Regression testing vs. ... testing 

Great Debate :)

Thank you.

--
Shamil
 
-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of Jim Dettman
Sent: 12 ?????? 2011 ?. 18:09
To: 'Access Developers discussion and problem solving'
Subject: Re: [AccessD] AccessD Digest, Vol 98, Issue 7

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".

...




More information about the AccessD mailing list