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

« back to all changes in this revision

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

  • Committer: dilshan_a
  • Date: 2008-01-25 01:03:06 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:299
Test framework now handles exceptions as valid outputs for scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
import sys, StringIO, copy
26
26
 
27
 
# student error
28
 
class FunctionNotFoundError(Exception):
29
 
    """This error is returned when a function was expected in student
30
 
    code but was not found"""
31
 
    def __init__(self, function_name):
32
 
        self.function_name = function_name
33
 
 
34
 
    def __str__(self):
35
 
        return "Function " + self.function_name + " not found"
36
 
 
37
27
# author error
38
28
class TestCreationError(Exception):
39
29
    """An error occured while creating the test suite or one of its components"""
50
40
        cla, exc, trbk = exc_info
51
41
        self.name = cla.__name__
52
42
        self._detail = str(exc)
 
43
        self._exc_info = exc_info
 
44
 
 
45
    def to_dict(self):
 
46
        return {'name': self._name,
 
47
                'detail': self._detail
 
48
                }
 
49
 
 
50
    def exc_info(self):
 
51
        return self._exc_info
53
52
 
54
53
    def __str__(self):
55
54
        return "Error running solution: %s" %str(self._detail)
61
60
        cla, exc, trbk = exc_info
62
61
        self.name = cla.__name__
63
62
        self._detail = str(exc)
 
63
        self._exc_info = exc_info
 
64
 
 
65
    def exc_info(self):
 
66
        return self._exc_info
64
67
 
65
68
    def __str__(self):
66
69
        return "Error testing solution against attempt: %s" %str(self._detail)
90
93
    def __str__(self):
91
94
        return self._name + " - " + str(self._detail)
92
95
 
 
96
# student error
 
97
class FunctionNotFoundError(Exception):
 
98
    """This error is returned when a function was expected in a
 
99
    test case but was not found"""
 
100
    def __init__(self, function_name):
 
101
        self.function_name = function_name
 
102
 
 
103
    def __str__(self):
 
104
        return "Function " + self.function_name + " not found"
 
105
 
93
106
class TestCasePart:
94
107
    """
95
108
    A part of a test case which compares a subset of the input files or file streams.
120
133
        self._file_tests = {}
121
134
        self._stdout_test = ('check', self._default_func)
122
135
        self._stderr_test = ('check', self._default_func)
 
136
        self._exception_test = ('check', self._default_func)
123
137
        self._result_test = ('check', self._default_func)
124
138
 
125
139
    def get_description(self):
189
203
        function = self._set_default_function(function, test_type)
190
204
        self._stderr_test = (test_type, function)
191
205
 
 
206
    def add_exception_test(self, function, test_type='norm'):
 
207
        "Test part that compares stderr"
 
208
        function = self._set_default_function(function, test_type)
 
209
        self._exception_test = (test_type, function)
 
210
 
192
211
    def add_file_test(self, filename, function, test_type='norm'):
193
212
        "Test part that compares the contents of a specified file"
194
213
        function = self._set_default_function(function, test_type)
201
220
        # converts unicode to string
202
221
        if type(solution_output) == unicode:    
203
222
            solution_output = str(solution_output)
 
223
            
204
224
        if type(attempt_output) == unicode:
205
225
            attempt_output = str(attempt_output)
206
226
            
229
249
        if not self._check_output(solution_data['stderr'], attempt_data['stderr'], test_type, f):        
230
250
            return 'stderr does not match'
231
251
 
 
252
        #check exception
 
253
        (test_type, f) = self._exception_test
 
254
        if not self._check_output(solution_data['exception'], attempt_data['exception'], test_type, f):        
 
255
            return 'exception does not match'
 
256
 
232
257
 
233
258
        solution_files = solution_data['modified_files']
234
259
        attempt_files = attempt_data['modified_files']
287
312
        self._filespace = TestFilespace(filespace)
288
313
        self._global_space = global_space
289
314
        self._parts = []
 
315
        self._allowed_exceptions = set()
290
316
 
291
317
    def set_stdin(self, stdin):
292
318
        """ Set the given string as the stdin for this test case"""
318
344
                self._keyword_args[name] = value
319
345
        except:
320
346
            raise TestCreationError("Invalid value for function argument: %s" %value)
 
347
 
 
348
    def add_exception(self, exception_name):
 
349
        self._allowed_exceptions.add(exception_name)
321
350
        
322
351
    def add_part(self, test_part):
323
352
        """ Add a TestPart to this test case"""
420
449
        output_stream, input_stream, error_stream = StringIO.StringIO(), StringIO.StringIO(self._stdin), StringIO.StringIO()
421
450
        sys.stdout, sys.stdin, sys.stderr = output_stream, input_stream, error_stream
422
451
 
 
452
        result = None
 
453
        exception_name = None
 
454
        
423
455
        try:
424
456
            if type(function) == tuple:
425
457
                # very hackish... exec can't be put into a lambda function!
426
458
                # or even with eval
427
459
                exec(function[0], function[1])
428
 
                result = None
429
460
            else:
430
461
                result = function()
431
462
        except:
432
463
            sys.stdout, sys.stdin, sys.stderr = sys_stdout, sys_stdin, sys_stderr
433
 
            raise
 
464
            exception_name = sys.exc_info()[0].__name__
 
465
            if exception_name not in self._allowed_exceptions:
 
466
                raise
434
467
        
435
468
        sys.stdout, sys.stdin, sys.stderr = sys_stdout, sys_stdin, sys_stderr
436
469
 
437
470
        self._current_filespace_copy.flush_all()
438
471
            
439
472
        return {'result': result,
 
473
                'exception': exception_name,
440
474
                'stdout': output_stream.getvalue(),
441
475
                'stderr': output_stream.getvalue(),
442
476
                'modified_files': self._current_filespace_copy.get_modified_files()}