Russell Keith-Magee scribit: > On 7/31/07, Nis Jørgensen <[EMAIL PROTECTED]> wrote: > >> I had the problem that any db error in any of my tests (including >> setups) would cause all following tests to fail (because the transaction >> was not rolled back). This was made even worse by the fact that I used >> the db in tearDown, which did not work very well either (I have since >> started using django.test.TestCase, so I don't use tearDown much). >> > > I can see how this problem could arise. The test framework doesn't > have any special handling for errors, so if one test pushes the > database into an error state, subsequent tests may fail. > > Ideally, test cases should be completely independent. It would be much > nicer to have a single test fail with a clean error than have one test > fail due to an error, and then all subsequent tests failing as a > consequence of the first failure. >
> >> I think the problem at the base of all this is that postgresql's >> transaction/error handling semantics are different from that of the >> other backends - while Django treats it as if it was the same. I would >> like to take a stab at fixing this (at the appropriate level, which I am >> not too sure I have identified). But before I do that, I would like to >> hear if anyone has any reasons why this should not be done ... >> > > I doubt this is a postgres-specific problem. The exact exception that > is thrown will be postgres specific, but all backends will throw > exceptions, and will require transaction rollback (or some other > handling) to allow the test suite to continue. > As far as I can tell, mySQL does not invalidate the current transaction when it encounters an error. Thus you can do """ mysql> create table foo (bar varchar(20) primary key) engine innodb; Query OK, 0 rows affected (0.28 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> insert into foo values ('foo'); Query OK, 1 row affected (0.19 sec) mysql> insert into foo values ('foo'); ERROR 1062 (23000): Duplicate entry 'foo' for key 1 mysql> insert into foo values ('bar'); Query OK, 1 row affected (0.00 sec) """ While in postgres you get: """ spider=> create table foo (bar varchar(20) primary key) ; NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo" CREATE TABLE spider=> begin; BEGIN spider=> insert into foo values ('foo'); INSERT 0 1 spider=> insert into foo values ('foo'); ERROR: duplicate key violates unique constraint "foo_pkey" spider=> insert into foo values ('bar'); ERROR: current transaction is aborted, commands ignored until end of transaction block """ For the record, I think mySQL is the one making sense here. sqlite behave the same way. I don't have an Oracle installation to test on (nor do I ever wish to get one). > This does raise the larger issue of generic error handling for the > database backends; It has been suggested that the various backend > exceptions should be wrapped by a generic Django database failure > exception. If database exceptions were normalized in this way, > catching the type of errors you describe would become much cleaner - > both in tests, and in the general case. > This sounds very much along the lines that I have been looking at for solving the issue. Out of interest, which versions of postgres are we supporting? I am asking because I think the mySQL behavior can only be mimicked using savepoints, which became available in 8.0. I see that there are in fact no mention of version numbers of any of the db products on the installation page. IMO, this should be fixed as well. I guess I should log an issue ... >> I will post some test cases with suggested behavior later (in a ticket). >> If someone could give me a clue to how I can easily run the django test >> suite, I would be glad. >> > > Most certainly log this issue; test cases are most welcome; fixes even > more welcome. > > I suspect the best approach will be to extend the django TestCase, > overriding one of the test run methods to provide transaction > checking. It may be helpful to define this behaviour as a decorator; > this would also allow users with tests based on unittest.TestCase, > rather than django.test.TestCase. > Thanks for the comments. I will log two issues: 1. Different backends have differen transaction semantics (and one of them makes error handling distinctly hard to use, ie pg). 2. Testcases give problems because of this. I am separating them since the second one is relatively easier to fix.. Nis --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---