Commit 9d74b4d2 by John Eskew

Merge pull request #11700 from edx/jeskew/my_unittest_speedups

Unit test speedups - Add context manager to SharedModuleStoreTestCase.
parents 9de6b912 b777530d
...@@ -4,6 +4,7 @@ Modulestore configuration for test cases. ...@@ -4,6 +4,7 @@ Modulestore configuration for test cases.
""" """
import functools import functools
from uuid import uuid4 from uuid import uuid4
from contextlib import contextmanager
from mock import patch from mock import patch
...@@ -267,9 +268,10 @@ class SharedModuleStoreTestCase(TestCase): ...@@ -267,9 +268,10 @@ class SharedModuleStoreTestCase(TestCase):
MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False) MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False)
@classmethod @classmethod
def setUpClass(cls): def _setUpModuleStore(cls): # pylint: disable=invalid-name
super(SharedModuleStoreTestCase, cls).setUpClass() """
Set up the modulestore for an entire test class.
"""
cls._settings_override = override_settings(MODULESTORE=cls.MODULESTORE) cls._settings_override = override_settings(MODULESTORE=cls.MODULESTORE)
cls._settings_override.__enter__() cls._settings_override.__enter__()
XMODULE_FACTORY_LOCK.enable() XMODULE_FACTORY_LOCK.enable()
...@@ -277,6 +279,40 @@ class SharedModuleStoreTestCase(TestCase): ...@@ -277,6 +279,40 @@ class SharedModuleStoreTestCase(TestCase):
cls.store = modulestore() cls.store = modulestore()
@classmethod @classmethod
@contextmanager
def setUpClassAndTestData(cls): # pylint: disable=invalid-name
"""
For use when the test class has a setUpTestData() method that uses variables
that are setup during setUpClass() of the same test class.
Use it like so:
@classmethod
def setUpClass(cls):
with super(MyTestClass, cls).setUpClassAndTestData():
<all the cls.setUpClass() setup code that performs modulestore setup...>
@classmethod
def setUpTestData(cls):
<all the setup code that creates Django models per test class...>
<these models can use variables (courses) setup in setUpClass() above>
"""
cls._setUpModuleStore()
# Now yield to allow the test class to run its setUpClass() setup code.
yield
# Now call the base class, which calls back into the test class's setUpTestData().
super(SharedModuleStoreTestCase, cls).setUpClass()
@classmethod
def setUpClass(cls):
"""
For use when the test class has no setUpTestData() method -or-
when that method does not use variable set up in setUpClass().
"""
super(SharedModuleStoreTestCase, cls).setUpClass()
cls._setUpModuleStore()
@classmethod
def tearDownClass(cls): def tearDownClass(cls):
drop_mongo_collections() # pylint: disable=no-value-for-parameter drop_mongo_collections() # pylint: disable=no-value-for-parameter
clear_all_caches() clear_all_caches()
......
...@@ -25,16 +25,12 @@ class TestCCXModulestoreWrapper(SharedModuleStoreTestCase): ...@@ -25,16 +25,12 @@ class TestCCXModulestoreWrapper(SharedModuleStoreTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super(TestCCXModulestoreWrapper, cls).setUpClass() super(TestCCXModulestoreWrapper, cls).setUpClass()
cls.course = course = CourseFactory.create() cls.course = CourseFactory.create()
cls.mooc_start = start = datetime.datetime( start = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=pytz.UTC)
2010, 5, 12, 2, 42, tzinfo=pytz.UTC due = datetime.datetime(2010, 7, 7, 0, 0, tzinfo=pytz.UTC)
)
cls.mooc_due = due = datetime.datetime(
2010, 7, 7, 0, 0, tzinfo=pytz.UTC
)
# Create a course outline # Create a course outline
cls.chapters = chapters = [ cls.chapters = chapters = [
ItemFactory.create(start=start, parent=course) for _ in xrange(2) ItemFactory.create(start=start, parent=cls.course) for _ in xrange(2)
] ]
cls.sequentials = sequentials = [ cls.sequentials = sequentials = [
ItemFactory.create(parent=c) for _ in xrange(2) for c in chapters ItemFactory.create(parent=c) for _ in xrange(2) for c in chapters
...@@ -48,20 +44,24 @@ class TestCCXModulestoreWrapper(SharedModuleStoreTestCase): ...@@ -48,20 +44,24 @@ class TestCCXModulestoreWrapper(SharedModuleStoreTestCase):
ItemFactory.create(parent=v, category='html') for _ in xrange(2) for v in verticals ItemFactory.create(parent=v, category='html') for _ in xrange(2) for v in verticals
] ]
@classmethod
def setUpTestData(cls):
"""
Set up models for the whole TestCase.
"""
cls.user = UserFactory.create()
# Create instructor account
cls.coach = AdminFactory.create()
def setUp(self): def setUp(self):
""" """
Set up tests Set up tests
""" """
super(TestCCXModulestoreWrapper, self).setUp() super(TestCCXModulestoreWrapper, self).setUp()
self.user = UserFactory.create()
# Create instructor account
coach = AdminFactory.create()
self.ccx = ccx = CustomCourseForEdX( self.ccx = ccx = CustomCourseForEdX(
course_id=self.course.id, course_id=self.course.id,
display_name='Test CCX', display_name='Test CCX',
coach=coach coach=self.coach
) )
ccx.save() ccx.save()
...@@ -132,12 +132,13 @@ class TestCCXModulestoreWrapper(SharedModuleStoreTestCase): ...@@ -132,12 +132,13 @@ class TestCCXModulestoreWrapper(SharedModuleStoreTestCase):
def test_publication_api(self): def test_publication_api(self):
"""verify that we can correctly discern a published item by ccx key""" """verify that we can correctly discern a published item by ccx key"""
for expected in self.blocks: with self.store.bulk_operations(self.ccx_locator):
block_key = self.ccx_locator.make_usage_key( for expected in self.blocks:
expected.location.block_type, expected.location.block_id block_key = self.ccx_locator.make_usage_key(
) expected.location.block_type, expected.location.block_id
self.assertTrue(self.store.has_published_version(expected)) )
self.store.unpublish(block_key, self.user.id) self.assertTrue(self.store.has_published_version(expected))
self.assertFalse(self.store.has_published_version(expected)) self.store.unpublish(block_key, self.user.id)
self.store.publish(block_key, self.user.id) self.assertFalse(self.store.has_published_version(expected))
self.assertTrue(self.store.has_published_version(expected)) self.store.publish(block_key, self.user.id)
self.assertTrue(self.store.has_published_version(expected))
...@@ -7,7 +7,7 @@ from nose.plugins.attrib import attr ...@@ -7,7 +7,7 @@ from nose.plugins.attrib import attr
from django.test.utils import override_settings from django.test.utils import override_settings
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from ..field_overrides import ( from ..field_overrides import (
disable_overrides, disable_overrides,
...@@ -23,14 +23,21 @@ TESTUSER = "testuser" ...@@ -23,14 +23,21 @@ TESTUSER = "testuser"
@attr('shard_1') @attr('shard_1')
@override_settings(FIELD_OVERRIDE_PROVIDERS=( @override_settings(FIELD_OVERRIDE_PROVIDERS=(
'courseware.tests.test_field_overrides.TestOverrideProvider',)) 'courseware.tests.test_field_overrides.TestOverrideProvider',))
class OverrideFieldDataTests(ModuleStoreTestCase): class OverrideFieldDataTests(SharedModuleStoreTestCase):
""" """
Tests for `OverrideFieldData`. Tests for `OverrideFieldData`.
""" """
@classmethod
def setUpClass(cls):
"""
Course is created here and shared by all the class's tests.
"""
super(OverrideFieldDataTests, cls).setUpClass()
cls.course = CourseFactory.create(enable_ccx=True)
def setUp(self): def setUp(self):
super(OverrideFieldDataTests, self).setUp() super(OverrideFieldDataTests, self).setUp()
self.course = CourseFactory.create(enable_ccx=True)
OverrideFieldData.provider_classes = None OverrideFieldData.provider_classes = None
def tearDown(self): def tearDown(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment