~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/apps/tutorialservice/test/TestFramework.py

  • Committer: stevenbird
  • Date: 2008-02-19 07:59:12 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:507
Extended code test framework to support tests on the code string, rather
than just its outputs.  This makes it possible to check the method being
used by the code to do its work.  For example, if the exercise is to
write code that computes 10! using multiplication, a response that
simply prints 3628800 produces the correct output, but using the
incorrect method.  A regular expression that tests the code could check
for the presence of a multiplication operation.  The XML format is:
<code type="check"> lambda x,y: '*' in y </code>

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
# Module: TestFramework
19
19
# Author: Dilshan Angampitiya
 
20
#         Steven Bird (revisions)
20
21
# Date:   24/1/2008
21
22
 
22
23
# Brief description of the Module# define custom exceptions
23
24
# use exceptions for all errors found in testing
24
25
 
25
26
import sys, StringIO, copy
 
27
import types
26
28
 
27
29
# student error or author error
28
30
# errors in student code get handled internally
156
158
            try:
157
159
                exec "__f__ = %s" %function in included_code
158
160
            except:
159
 
                raise TestCreationError("Invalid function %s" %function)
 
161
                raise TestCreationError("Invalid function %s" % function)
160
162
 
161
163
            f = included_code['__f__']
162
164
 
163
165
            if not callable(f):
164
 
                raise TestCreationError("Invalid function %s" %function)    
 
166
                raise TestCreationError("Invalid function %s" % function)
165
167
        else:
166
168
            f = function
167
169
 
169
171
 
170
172
    def validate_functions(self, included_code):
171
173
        """Ensure all functions used by the test cases exist and are callable.
172
 
        Also covert their string representations to function objects.
 
174
        Also convert their string representations to function objects.
173
175
        This can only be done once all the include code has been specified.
174
176
        """
175
177
        (test_type, function) = self._stdout_test
215
217
        """Compare solution output and attempt output using the
216
218
        specified comparison function.
217
219
        """
218
 
        # converts unicode to string
219
 
        if type(solution_output) == unicode:    
220
 
            solution_output = str(solution_output)
221
 
            
222
 
        if type(attempt_output) == unicode:
223
 
            attempt_output = str(attempt_output)
 
220
        solution_output = str(solution_output)
 
221
        attempt_output = str(attempt_output)
224
222
            
225
223
        if test_type == 'norm':
226
224
            return f(solution_output) == f(attempt_output)
231
229
        """Compare solution code and attempt code using the
232
230
        specified comparison function.
233
231
        """
234
 
        if not callable(f):
235
 
            raise TestCreationError("Invalid function %s" %f)
 
232
        if type(f) in types.StringTypes:  # kludge
 
233
            f = eval(str(f))
236
234
        if test_type == 'norm':
237
235
            return f(solution) == f(attempt)
238
236
        else:
250
248
 
251
249
        # check function return value (None for scripts)
252
250
        (test_type, f) = self._result_test
253
 
        if not self._check_output(solution_data['result'], attempt_data['result'], test_type, f):       
 
251
        if not self._check_output(solution_data['result'], attempt_data['result'], test_type, f):
254
252
            return 'Unexpected function return value'
255
253
 
256
254
        # check stdout
257
255
        (test_type, f) = self._stdout_test
258
 
        if not self._check_output(solution_data['stdout'], attempt_data['stdout'], test_type, f):       
 
256
        if not self._check_output(solution_data['stdout'], attempt_data['stdout'], test_type, f):
259
257
            return 'Unexpected output'
260
258
 
261
259
        #check stderr
262
260
        (test_type, f) = self._stderr_test
263
 
        if not self._check_output(solution_data['stderr'], attempt_data['stderr'], test_type, f):        
 
261
        if not self._check_output(solution_data['stderr'], attempt_data['stderr'], test_type, f):
264
262
            return 'Unexpected error output'
265
263
 
266
264
        #check exception
267
265
        (test_type, f) = self._exception_test
268
 
        if not self._check_output(solution_data['exception'], attempt_data['exception'], test_type, f):        
 
266
        if not self._check_output(solution_data['exception'], attempt_data['exception'], test_type, f):
269
267
            return 'Unexpected exception'
270
268
 
271
269
        solution_files = solution_data['modified_files']
338
336
    def add_variable(self, variable, value):
339
337
        """ Add the given varibale-value pair to the initial global environment
340
338
        for this test case.
341
 
        Throw and exception if thevalue cannot be paresed.
 
339
        Throw and exception if the value cannot be paresed.
342
340
        """
343
341
        
344
342
        try: