unit testing in a controlled loop

G

Guest

Here's my problem.
Have a database interface with several methods.
I created a database class to implement the interface,
and a set of unit tests to test each method.
Now I want to support another database provider.
The implementation is very easy: I simply
create a new database class, and implement all the methods using the new
database provider.
My question is: How do I get this same set of unit tests to run in a loop?
My problem is that I have one test class with many test methods,
and I want the testing framework to run each of those tests once for every
different database implementation that I've coded.
I certainly could have a single test method that has a loop that calls a
hand-crafted set of test method's.
But that would put the looping and every single test method in one single
unit test method. Then I would lose the nice partitioning that the
conventional test architecture provides.
I know this may be confusing when you read it.
Just imagine one of your typical unit tests. Now imagine you want to repeat
all of those unit tests exactly as they are structured, except you want to
change one single variable for each run.
Thanks
 
R

Randy A. Ynchausti

David,
How do I get this same set of unit tests to run in a loop?

I wouldn't think of it that way. What I would do is to have a base
test-class with an instance variable (testObject) of the type of the
interface that you have implemented. That base class has all of the test
methods that test the proper implementation of the interface. In the
"SetUp" method, instantiate the right implementation class and cast it to
the interface and store the reference in the testObject variable. In the
"TearDown" method, clean the testObject up. All of the test methods should
test against the object stored in the testObject instance variable.

Then I would subclass that base for each database implementation and inherit
all of the testing from the base test-class. Then override "SetUp" and
"TearDown" and any other test methods appropriately. This will effectively
test all of the different database implementations that you want to support
without having a ton of duplicated test code; and without a looping
structure.
My problem is that I have one test class with many test methods,
and I want the testing framework to run each of those tests once for every
different database implementation that I've coded.

The architecture that I have described above does this.


Regards,

Randy
 
G

Guest

Thanks, Randy.
This will indeed work.
But I must create test methods in each inheritor and decorate them with the
[TestMethod] attribute. As you suggest, those test methods will call the
parent where the interesting code can exist (at least we avoid duplicating
that part, which would be tedious and error-prone.
But I was hoping to avoid duplicating the method shells as well.
If I'm going to do this, I don't even need inheritance,
I can use composition.

Anyway, when I add a new method to the interface, I have to add the complex
logic once (good) but I have to create a shell method in every database
implementation.

A looping approach would allow me to create only one test method.
thanks
--
David K Allen
Carlson School of Management
University of Minnesota
Minneapolis, MN


:
....
Then I would subclass that base for each database implementation and inherit
all of the testing from the base test-class. Then override "SetUp" and
"TearDown" and any other test methods appropriately.
....
 
L

Luke Zhang [MSFT]

If your new database class has same methods and properties, you may have a
collection containing all your database objects, fill the collection in
TestInitialize() method. In a test method, test all objects in the
collection.

Anyway, Unit test is intend to test a module or a class. For multiple
classes, I think it is better to create multiple Uint tests since you may
get different results from different database provider.


Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Thanks. Between your suggestion and Randy's, I have a nice range of choices.
I get your point about unit testing.
But in this particular case, I am really testing that each implementation
confroms to the same interface and I expect them all to honor the same
contracts, regardless of how they implement them.

So to summarize the patterns:

If uniformity of behavior is expected from every implementation,
and there may be several implementations,
then creating a collection in TestInitialized and having every test loop
over every item is the easiest way to handle the change "add a new
implmentation and ensure it conforms."

If some variety is expected in behavior from implementation to implementation,
then having a common class with shared methods is the easiest way to handle
changes, because copy and paste isn't so bad and it allows tailoring certain
methods that vary.

David K Allen
Carlson School of Management
University of Minnesota
Minneapolis, MN
 
L

Luke Zhang [MSFT]

This is a good summary on this issue. Thank you for sharing.

Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top