Re: Test fixtures loaded ~100 times faster by overwriting BaseDatabaseCreation.create_test_db + question
On Jan 14, 11:07 pm, Russell Keith-Magee wrote: > On Thu, Jan 14, 2010 at 4:43 PM, Piotr Czachur wrote: > > Guys, > > I was really unhappy to see how slow fixtures are loaded before every > > test. I'm not talking about initial_data stuff that is loaded just in > > beginning, and then reset by rollback. Fixtures used for unit tests > > are loaded on demand (fixtures = [f1, f2]), and this is really slow, > > because thousands of SQL queries going to database (SELECTs, SELECTs, > > INSERTs). > > For my small test suite (130 tests) and small fixtures (15 items) I've > > recorded ~16000 queries to database - I was really blown away by this > > number. 99% of this queries was related to fixtures loading. > > We are well aware of the speed problems associated with fixture setup > and teardown during testing. We're open to any practical suggestions > on how to speed them up. > I came across some similar issues with an Event/Occurrence pair of models (each Event has one or more occurrences, representing the potentially repeating nature of the event). Because an Event could have many thousand Occurrences, and modifying the Event may require modifying, or even recreating all of the Occurrences, I looked at some ways to improve performance. Because we have a series of homogenous object types, we can combine all of the SQL queries into one. I wonder if something similar could be done with fixtures: create all of the objects, but instead of saving them one at a time, save them in one batch. I hand coded the query, as this was a development exercise, and wasn't for production. This would probably require significant thought as to the best way to do this: perhaps a create_many() method on the Manager might be a better solution? I think I'll have another look at this - I'm about to revisit that code anyway. Any other suggestions are welcome, too :) > > As I said, we're more than happy to look at any proposal to improve > the speed of testing in Django, but those changes can't come at the > cost of fundamentally changing what it means to write a test. Agreed. I use the different fixtures in test classes to have a known state at the beginning of each test, that varies across test cases. Matt. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Test fixtures loaded ~100 times faster by overwriting BaseDatabaseCreation.create_test_db + question
On Thu, Jan 14, 2010 at 4:43 PM, Piotr Czachur wrote: > Guys, > I was really unhappy to see how slow fixtures are loaded before every > test. I'm not talking about initial_data stuff that is loaded just in > beginning, and then reset by rollback. Fixtures used for unit tests > are loaded on demand (fixtures = [f1, f2]), and this is really slow, > because thousands of SQL queries going to database (SELECTs, SELECTs, > INSERTs). > For my small test suite (130 tests) and small fixtures (15 items) I've > recorded ~16000 queries to database - I was really blown away by this > number. 99% of this queries was related to fixtures loading. We are well aware of the speed problems associated with fixture setup and teardown during testing. We're open to any practical suggestions on how to speed them up. > So I came to conclusion that I can load my all fixtures just after > initial_data fixtures are loaded at beginning, so database rollback > can be used by Django test infrastructure to reset database state in a > fraction of second. This might work for your particular test suite, but it isn't that simple in the general case. More details in a moment. > Question: > Like you see I decorated and overwrote create_test_db, but what I > don't like here is that I had to add "setup_environ(settings)" to > prevent getting exception, because Django was not initialized at this > moment. > execute_manager(settings) also runs setup_environ(settings) so it is > run twice. > Is there a better place/time to execute such overwriting? ...because I > see this little tricky. Yes - rather than dynamically monkeypatching, write a custom test runner [1] that calls into your customized create/destroy routines. [1] http://docs.djangoproject.com/en/dev/topics/testing/#defining-a-test-runner > P.S. > The side effect was that I have to remove all "fixture = [a,b,c]" from > my tests, because I have all fixtures loaded at beginning before tests > are run - but I cannot see this as a problem. This is a little more than a 'side effect' - it's a fundamental change to the expectations of test cases. The major reason to use fixture=[] notation is to allow every test case to have it's own test fixtures. This isn't just a good idea - it's a fundamental requirement for certain types of tests. For example, consider a simple suite with two tests that validate that an article list displays correctly. The first test validates that the list displays when articles are defined; the second test validates that error text is displayed when no articles are defined. The test fixture requirements for the two tests cannot be accommodated in a single set of suite-wide test fixtures. As I said, we're more than happy to look at any proposal to improve the speed of testing in Django, but those changes can't come at the cost of fundamentally changing what it means to write a test. Yours, Russ Magee %-) -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.