Start to add peer grading tests, make dummy system a separate thing
This commit is contained in:
@@ -100,29 +100,29 @@ without making actual service calls to the grading controller
|
||||
|
||||
class MockPeerGradingService(object):
|
||||
def get_next_submission(self, problem_location, grader_id):
|
||||
return json.dumps({'success': True,
|
||||
return {'success': True,
|
||||
'submission_id': 1,
|
||||
'submission_key': "",
|
||||
'student_response': 'fake student response',
|
||||
'prompt': 'fake submission prompt',
|
||||
'rubric': 'fake rubric',
|
||||
'max_score': 4})
|
||||
'max_score': 4}
|
||||
|
||||
def save_grade(self, location, grader_id, submission_id,
|
||||
score, feedback, submission_key, rubric_scores, submission_flagged):
|
||||
return json.dumps({'success': True})
|
||||
return {'success': True}
|
||||
|
||||
def is_student_calibrated(self, problem_location, grader_id):
|
||||
return json.dumps({'success': True, 'calibrated': True})
|
||||
return {'success': True, 'calibrated': True}
|
||||
|
||||
def show_calibration_essay(self, problem_location, grader_id):
|
||||
return json.dumps({'success': True,
|
||||
return {'success': True,
|
||||
'submission_id': 1,
|
||||
'submission_key': '',
|
||||
'student_response': 'fake student response',
|
||||
'prompt': 'fake submission prompt',
|
||||
'rubric': 'fake rubric',
|
||||
'max_score': 4})
|
||||
'max_score': 4}
|
||||
|
||||
def save_calibration_essay(self, problem_location, grader_id,
|
||||
calibration_essay_id, submission_key, score,
|
||||
@@ -130,10 +130,13 @@ class MockPeerGradingService(object):
|
||||
return {'success': True, 'actual_score': 2}
|
||||
|
||||
def get_problem_list(self, course_id, grader_id):
|
||||
return json.dumps({'success': True,
|
||||
return {'success': True,
|
||||
'problem_list': [
|
||||
json.dumps({'location': 'i4x://MITx/3.091x/problem/open_ended_demo1',
|
||||
'problem_name': "Problem 1", 'num_graded': 3, 'num_pending': 5}),
|
||||
json.dumps({'location': 'i4x://MITx/3.091x/problem/open_ended_demo2',
|
||||
'problem_name': "Problem 2", 'num_graded': 1, 'num_pending': 5})
|
||||
]})
|
||||
{'location': 'i4x://MITx/3.091x/problem/open_ended_demo1',
|
||||
'problem_name': "Problem 1", 'num_graded': 3, 'num_pending': 5},
|
||||
{'location': 'i4x://MITx/3.091x/problem/open_ended_demo2',
|
||||
'problem_name': "Problem 2", 'num_graded': 1, 'num_pending': 5}
|
||||
]}
|
||||
|
||||
def get_data_for_location(self, problem_location, student_id):
|
||||
return {"version": 1, "count_graded": 3, "count_required": 3, "success": True, "student_sub_count": 1}
|
||||
|
||||
55
common/lib/xmodule/xmodule/tests/dummy_system.py
Normal file
55
common/lib/xmodule/xmodule/tests/dummy_system.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from . import test_system
|
||||
import unittest
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.xml import ImportSystem, XMLModuleStore
|
||||
from xmodule.tests.test_export import DATA_DIR
|
||||
from fs.memoryfs import MemoryFS
|
||||
from mock import patch, Mock
|
||||
|
||||
class DummySystem(ImportSystem):
|
||||
|
||||
@patch('xmodule.modulestore.xml.OSFS', lambda dir: MemoryFS())
|
||||
def __init__(self, load_error_modules, org, course):
|
||||
|
||||
xmlstore = XMLModuleStore("data_dir", course_dirs=[], load_error_modules=load_error_modules)
|
||||
course_id = "/".join([org, course, 'test_run'])
|
||||
course_dir = "test_dir"
|
||||
policy = {}
|
||||
error_tracker = Mock()
|
||||
parent_tracker = Mock()
|
||||
|
||||
super(DummySystem, self).__init__(
|
||||
xmlstore,
|
||||
course_id,
|
||||
course_dir,
|
||||
policy,
|
||||
error_tracker,
|
||||
parent_tracker,
|
||||
load_error_modules=load_error_modules,
|
||||
)
|
||||
|
||||
def render_template(self, template, context):
|
||||
raise Exception("Shouldn't be called")
|
||||
|
||||
class DummySystemUser(object):
|
||||
test_system = test_system()
|
||||
@staticmethod
|
||||
def get_import_system(org, course, load_error_modules=True):
|
||||
'''Get a dummy system'''
|
||||
return DummySystem(load_error_modules, org, course)
|
||||
|
||||
def get_course(self, name):
|
||||
"""Get a test course by directory name. If there's more than one, error."""
|
||||
|
||||
modulestore = XMLModuleStore(DATA_DIR, course_dirs=[name])
|
||||
courses = modulestore.get_courses()
|
||||
self.modulestore = modulestore
|
||||
self.assertEquals(len(courses), 1)
|
||||
return courses[0]
|
||||
|
||||
def get_module_from_location(self, location, course):
|
||||
course = self.get_course(course)
|
||||
if not isinstance(location, Location):
|
||||
location = Location(location)
|
||||
descriptor = self.modulestore.get_instance(course.id, location, depth=None)
|
||||
return descriptor.xmodule(self.test_system)
|
||||
@@ -5,6 +5,8 @@ import unittest
|
||||
from fs.memoryfs import MemoryFS
|
||||
from mock import patch
|
||||
|
||||
from dummy_system import DummySystemUser
|
||||
|
||||
from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild
|
||||
from xmodule.open_ended_grading_classes.open_ended_module import OpenEndedModule
|
||||
from xmodule.open_ended_grading_classes.combined_open_ended_modulev1 import CombinedOpenEndedV1Module
|
||||
@@ -42,31 +44,6 @@ class MockQueryDict(dict):
|
||||
return []
|
||||
return default
|
||||
|
||||
class DummySystem(ImportSystem):
|
||||
|
||||
@patch('xmodule.modulestore.xml.OSFS', lambda dir: MemoryFS())
|
||||
def __init__(self, load_error_modules):
|
||||
|
||||
xmlstore = XMLModuleStore("data_dir", course_dirs=[], load_error_modules=load_error_modules)
|
||||
course_id = "/".join([ORG, COURSE, 'test_run'])
|
||||
course_dir = "test_dir"
|
||||
policy = {}
|
||||
error_tracker = Mock()
|
||||
parent_tracker = Mock()
|
||||
|
||||
super(DummySystem, self).__init__(
|
||||
xmlstore,
|
||||
course_id,
|
||||
course_dir,
|
||||
policy,
|
||||
error_tracker,
|
||||
parent_tracker,
|
||||
load_error_modules=load_error_modules,
|
||||
)
|
||||
|
||||
def render_template(self, template, context):
|
||||
raise Exception("Shouldn't be called")
|
||||
|
||||
"""
|
||||
Tests for the various pieces of the CombinedOpenEndedGrading system
|
||||
|
||||
@@ -514,7 +491,7 @@ class CombinedOpenEndedModuleTest(unittest.TestCase):
|
||||
self.assertEqual(score_dict['score'], 15.0)
|
||||
self.assertEqual(score_dict['total'], 15.0)
|
||||
|
||||
class OpenEndedModuleXmlTest(unittest.TestCase):
|
||||
class OpenEndedModuleXmlTest(unittest.TestCase, DummySystemUser):
|
||||
problem_location = Location(["i4x", "edX", "oe_test", "combinedopenended", "SampleQuestion"])
|
||||
answer = "blah blah"
|
||||
assessment = [0,1]
|
||||
@@ -525,37 +502,15 @@ class OpenEndedModuleXmlTest(unittest.TestCase):
|
||||
send_to_queue = Mock(side_effect=[1,"queued"])
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_import_system(load_error_modules=True):
|
||||
'''Get a dummy system'''
|
||||
return DummySystem(load_error_modules)
|
||||
|
||||
def get_course(self, name):
|
||||
"""Get a test course by directory name. If there's more than one, error."""
|
||||
print "Importing {0}".format(name)
|
||||
|
||||
modulestore = XMLModuleStore(DATA_DIR, course_dirs=[name])
|
||||
courses = modulestore.get_courses()
|
||||
self.modulestore = modulestore
|
||||
self.assertEquals(len(courses), 1)
|
||||
return courses[0]
|
||||
|
||||
def get_module_from_location(self, location):
|
||||
course = self.get_course('open_ended')
|
||||
if not isinstance(location, Location):
|
||||
location = Location(location)
|
||||
descriptor = self.modulestore.get_instance(course.id, location, depth=None)
|
||||
return descriptor.xmodule(self.test_system)
|
||||
|
||||
def test_open_ended_load_and_save(self):
|
||||
module = self.get_module_from_location(self.problem_location)
|
||||
module = self.get_module_from_location(self.problem_location, COURSE)
|
||||
module.handle_ajax("save_answer", {"student_answer" : self.answer})
|
||||
task_one_json = json.loads(module.task_states[0])
|
||||
self.assertEqual(task_one_json['child_history'][0]['answer'], self.answer)
|
||||
|
||||
def test_open_ended_flow_reset(self):
|
||||
assessment = [0,1]
|
||||
module = self.get_module_from_location(self.problem_location)
|
||||
module = self.get_module_from_location(self.problem_location, COURSE)
|
||||
|
||||
#Simulate a student saving an answer
|
||||
module.handle_ajax("save_answer", {"student_answer" : self.answer})
|
||||
@@ -578,7 +533,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase):
|
||||
|
||||
def test_open_ended_flow_correct(self):
|
||||
assessment = [1,1]
|
||||
module = self.get_module_from_location(self.problem_location)
|
||||
module = self.get_module_from_location(self.problem_location, COURSE)
|
||||
|
||||
#Simulate a student saving an answer
|
||||
module.handle_ajax("save_answer", {"student_answer" : self.answer})
|
||||
|
||||
49
common/lib/xmodule/xmodule/tests/test_peer_grading.py
Normal file
49
common/lib/xmodule/xmodule/tests/test_peer_grading.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import unittest
|
||||
from xmodule.modulestore import Location
|
||||
import json
|
||||
from lxml import etree
|
||||
from mock import Mock
|
||||
from . import test_system
|
||||
from dummy_system import DummySystem, DummySystemUser
|
||||
|
||||
from xmodule.peer_grading_module import PeerGradingModule, PeerGradingDescriptor
|
||||
from xmodule.open_ended_grading_classes.grading_service_module import GradingServiceError
|
||||
|
||||
ORG = "edX"
|
||||
COURSE="open_ended"
|
||||
|
||||
|
||||
class PeerGradingModuleTest(unittest.TestCase, DummySystemUser):
|
||||
location = Location(["i4x", "edX", "open_ended", "peergrading",
|
||||
"SampleQuestion"])
|
||||
max_score = 1
|
||||
|
||||
definition = "<peergrading/>"
|
||||
descriptor = Mock(data=definition)
|
||||
|
||||
def setUp(self):
|
||||
self.test_system = test_system()
|
||||
self.test_system.open_ended_grading_interface = None
|
||||
self.peer_grading = PeerGradingModule(self.test_system, self.location,self.descriptor, model_data={'data': self.definition})
|
||||
|
||||
def test_module_closed(self):
|
||||
closed = self.peer_grading.closed()
|
||||
self.assertEqual(closed, False)
|
||||
|
||||
def test_get_html(self):
|
||||
html = self.peer_grading.get_html()
|
||||
|
||||
def test_get_data(self):
|
||||
try:
|
||||
success, data = self.peer_grading.query_data_for_location()
|
||||
except GradingServiceError:
|
||||
pass
|
||||
|
||||
def test_get_score(self):
|
||||
score = self.peer_grading.get_score()
|
||||
|
||||
def test_get_max_score(self):
|
||||
max_score = self.peer_grading.max_score()
|
||||
|
||||
def get_next_submission(self):
|
||||
success, next_submission = self.peer_grading.get_next_submission({'location' : 'blah'})
|
||||
@@ -1,5 +1,6 @@
|
||||
<course>
|
||||
<chapter url_name="Overview">
|
||||
<combinedopenended url_name="SampleQuestion"/>
|
||||
<peergrading url_name="PeerGradingSample"/>
|
||||
</chapter>
|
||||
</course>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<peergrading/>
|
||||
@@ -9,6 +9,9 @@
|
||||
"display_name": "Overview"
|
||||
},
|
||||
"combinedopenended/SampleQuestion": {
|
||||
"display_name": "Sample Question",
|
||||
"display_name": "Sample Question"
|
||||
},
|
||||
"peergrading/PeerGradingSample": {
|
||||
"display_name": "Sample Question"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user