EntityManagerTestSuite - UnitTest Template Added

Posts   
 
    
Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 18-Dec-2004 22:16:47   

I've added a couple of tempates to SubVersion for generating UnitTests for the EntityManagers. simple_smile

These are very early and really only intended to spark some dicussion about how best to automate the geneartion of tests and whether in fact generating tests is even a good idea at all!

At the moment they only test that an Entity can be created (EntityManager.Create) and that the Entity can be saved (EntityManager.Save) to the database successfully, both with and without passing a DataAccessAdapter. All dependent Entities are also created and the save is recursive, which is great for testing that your database is fully in sync with your code...

The tests save the entity with LLBLGen and then use Microsoft's Data Access Block to check that row was written correctly to the database.

Also, I using a trick with COM+ to automatically clean up the database after each test. The unfortunate thing is that this particular trick only is that it only works on WinXP SP2 (so I'm told disappointed ). Furthermore the projects and DLLs need to be signed to work with COM+, so you will need to re-compile the MS DAAB and sign it. (You can always comment out the [SetUp] and [TearDown] EnterpriseServices code and clean up the database manually after each test run...)

To set up the templates, you must create a project and add the following references:

  • Both LLBLGen Projects
  • EntityManagers Project
  • NUnit 2.1 or later
  • Microsoft Data Access Application Block v2
  • System.EnterpriseServices

You also need to add an app.config to the project and put the connection string and key in the appSettings section. This key (your key) will also need to be set in the TestSuiteBase class. This will need to be all cleaned up later... but for now I'm having a nightmare with getting this kind of configuration into some sort of generic format. disappointed

Be happy to take any feedback, good or bad! stuck_out_tongue_winking_eye

Marcus

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 19-Dec-2004 12:20:00   

Just a tip: if you add experimental stuff, it's perhaps wise to first create a tag of the version that's currently trunk (copy trunk to tags/tagname ) and create a branch (copy trunk to branches/branchname), then switch your local copy (with tortoisesvn) to the branch, and commit to the branch.

But if it doesn't hurt much, you can also leave the files in the head revision in the trunk of course wink simple_smile Just a tip.

Another tip about database cleaning: add a GUID column to your test entities, and create in the test setup method a new GUID which you store in each entity saved. Then at teardown you call a single stored procedure which removes all entities with the GUID passed in.

You also could use a transaction in an adapter, run all code in a test and in the end simply rollback the transaction.

I use 2 databases for unittesting, one for writing and one for reading. The reading tests database is used for only fetch testing. The writing database is used for only writing data. This way your tests never fail when you test how many objects should be returned and it doesn't match because another test has written another row into the same table wink .

(and why not use llblgen pro's logic to test if an entity is written ok? IMHO your tests should focus on your own code, and assuming the logic below it (the one it's build on top of) is correct. Should limit the scope of your tests a lot, which saves time I think. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 19-Dec-2004 12:59:08   

Otis wrote:

Just a tip: if you add experimental stuff, it's perhaps wise to first create a tag of the version that's currently trunk (copy trunk to tags/tagname ) and create a branch (copy trunk to branches/branchname), then switch your local copy (with tortoisesvn) to the branch, and commit to the branch.

But if it doesn't hurt much, you can also leave the files in the head revision in the trunk of course wink simple_smile Just a tip.

I need to read up on SubVersion... fair points! simple_smile Althought the template does work 100% (just clumsy to setup) I generated 300+ tests on one of my larger DBs which all run with GREEN lights. The slightest change to the DB without re-generation causes REDs. Exactly what I want smile

Otis wrote:

Another tip about database cleaning: add a GUID column to your test entities, and create in the test setup method a new GUID which you store in each entity saved. Then at teardown you call a single stored procedure which removes all entities with the GUID passed in.

How can you add a GUID column to test entities without having this column present in the DB? And if you have to add it to the DB, isn't this adding additional logic to production code in order to facilitate testing? mmm. Not convinced about this one... stuck_out_tongue_winking_eye

Otis wrote:

You also could use a transaction in an adapter, run all code in a test and in the end simply rollback the transaction.

This assumes that you have the ability to pass an Adapter/Tansaction into the method being tested... Using COM+ to manage the transaction gives you the ability to forget about whether or not the database has been changed during the test. You don't need to explicitly create and pass a transaction context around and is altogether cleaner IMO. simple_smile

For instance, sometimes Log records are created even when a method throws an exception. Using a passed adapter/transaction context will not delete these log records as they are created outside the scope of the main transaction...

Otis wrote:

I use 2 databases for unittesting, one for writing and one for reading. The reading tests database is used for only fetch testing. The writing database is used for only writing data. This way your tests never fail when you test how many objects should be returned and it doesn't match because another test has written another row into the same table wink .

Interesting...

Otis wrote:

(and why not use llblgen pro's logic to test if an entity is written ok? IMHO your tests should focus on your own code, and assuming the logic below it (the one it's build on top of) is correct. Should limit the scope of your tests a lot, which saves time I think. simple_smile

Now here's a real bone of contention... It's not that I don't trust LLBLGen... wink BUT... What if there's a bug in LLBLGen (impossible I know stuck_out_tongue_winking_eye ) which might be caused by some future cache or other problem... If you use LLBLGen to write the row and then read it back, is this a real test of whether LLBLGen worked and actually wrote the row to the DB?

I'm really in favour of using all means available to test, especially as we become more reliant on UnitTests before releasing code to production. I need to be 100% sure that new code works and need to catch any possible bugs that exist now or in the future. simple_smile

The Manager classes for instance enable abstraction of the DataAccessAdapter. Save and Fetch can be done without explicitly creating an Adapter. If there's a bug or if a cache is ever implemented (which is buggy), then the test might pass when it should have failed. frowning

I definately think that tests should avoid using the code being tested as a means of validating that the test passed... Or am I being pedantic! wink

cmartinbot
User
Posts: 147
Joined: 08-Jan-2004
# Posted on: 19-Dec-2004 19:42:20   

This is really nice Marcus.

I'm gonna check it out later tonight!

This really should be branched though. wink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 20-Dec-2004 09:56:54   

Marcus wrote:

Otis wrote:

Just a tip: if you add experimental stuff, it's perhaps wise to first create a tag of the version that's currently trunk (copy trunk to tags/tagname ) and create a branch (copy trunk to branches/branchname), then switch your local copy (with tortoisesvn) to the branch, and commit to the branch.

But if it doesn't hurt much, you can also leave the files in the head revision in the trunk of course wink simple_smile Just a tip.

I need to read up on SubVersion... fair points! simple_smile Althought the template does work 100% (just clumsy to setup) I generated 300+ tests on one of my larger DBs which all run with GREEN lights. The slightest change to the DB without re-generation causes REDs. Exactly what I want smile

Cool! simple_smile

Otis wrote:

Another tip about database cleaning: add a GUID column to your test entities, and create in the test setup method a new GUID which you store in each entity saved. Then at teardown you call a single stored procedure which removes all entities with the GUID passed in.

How can you add a GUID column to test entities without having this column present in the DB? And if you have to add it to the DB, isn't this adding additional logic to production code in order to facilitate testing? mmm. Not convinced about this one... stuck_out_tongue_winking_eye

No, not a production database, a database setup for testing the code. The philosophy is that if the code works for these situations it also works with other schemas (but the same situations), so it doesn't matter if I save data in northwind or my own, as long as the constructs are tested. simple_smile

Otis wrote:

You also could use a transaction in an adapter, run all code in a test and in the end simply rollback the transaction.

This assumes that you have the ability to pass an Adapter/Tansaction into the method being tested... Using COM+ to manage the transaction gives you the ability to forget about whether or not the database has been changed during the test. You don't need to explicitly create and pass a transaction context around and is altogether cleaner IMO. simple_smile

For instance, sometimes Log records are created even when a method throws an exception. Using a passed adapter/transaction context will not delete these log records as they are created outside the scope of the main transaction...

Good points.

Otis wrote:

(and why not use llblgen pro's logic to test if an entity is written ok? IMHO your tests should focus on your own code, and assuming the logic below it (the one it's build on top of) is correct. Should limit the scope of your tests a lot, which saves time I think. simple_smile

Now here's a real bone of contention... It's not that I don't trust LLBLGen... wink BUT... What if there's a bug in LLBLGen (impossible I know stuck_out_tongue_winking_eye ) which might be caused by some future cache or other problem... If you use LLBLGen to write the row and then read it back, is this a real test of whether LLBLGen worked and actually wrote the row to the DB?

heh simple_smile Well I don't mind extra testing of course wink

I'm really in favour of using all means available to test, especially as we become more reliant on UnitTests before releasing code to production. I need to be 100% sure that new code works and need to catch any possible bugs that exist now or in the future. simple_smile

Ok, good point simple_smile

Frans Bouma | Lead developer LLBLGen Pro
cmartinbot
User
Posts: 147
Joined: 08-Jan-2004
# Posted on: 20-Dec-2004 22:34:36   

Marcus,

Would you mind moving the unit test bits into a new branch? I don't really mind the extra templates being here but, with the new Create* methods, things can get a little crazy. For instance, I have a couple of entities with about 80 fields. That's a one crazy method signature! wink

Those methods are fine for your unit tests but, I don't think they have any real use outside of testing. confused

Plus keeping it simple for newbs is always a good idea simple_smile

Thanks.

henginy
User
Posts: 1
Joined: 29-Jul-2008
# Posted on: 29-Jul-2008 16:57:38   

Hi,

Re-opening a very old thread,, but i wonder if Marcus' work can be publicly accessed atm?

Testing the llblgen schema against db is very important for our project. Many bugs arise because of the changes made to the db but not reflected to llblgen schema. I'm guessing other people might be facing this situation too..however my search on this forum and the net yielded no results.

So if you know any tool/library/method for llblgen schema-to-db comparison, it would be very helpful..

Thanks for your time..

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 30-Jul-2008 10:41:04   

If the out-of-sync state of a project is your concern, you could use the command line tools for refresh and generation (in the SDK) which are then called from a single batch file, so you always have an up-to-date project right before code generation.

Frans Bouma | Lead developer LLBLGen Pro