From e67f3240f12ca3a93a0a814cd2e1a5b81e112d6b Mon Sep 17 00:00:00 2001 From: Dannnno Date: Tue, 7 Oct 2014 16:12:49 -0700 Subject: [PATCH] Resolved Issue 1 Now correctly gets imported functions, classes. Now properly catches printed output --- Example_assignments/ps3alice.py | 4 +-- Example_assignments/ps3alice.txt | 8 ++--- Example_assignments/ps3bob.py | 2 +- Example_assignments/ps3bob.txt | 19 +++-------- Example_assignments/ps3dan.txt | 15 ++------- auto_grader.py | 58 +++++++++++++++++++------------- example.py | 36 ++++++-------------- 7 files changed, 60 insertions(+), 82 deletions(-) diff --git a/Example_assignments/ps3alice.py b/Example_assignments/ps3alice.py index 5f5810e..7f60d9a 100644 --- a/Example_assignments/ps3alice.py +++ b/Example_assignments/ps3alice.py @@ -1,4 +1,4 @@ -## Alice, a CS student +## Alice, an average CS student def func1(a): return a+1 @@ -7,4 +7,4 @@ def func2(a): return a[::-1] def printer(a): - print a \ No newline at end of file + return a \ No newline at end of file diff --git a/Example_assignments/ps3alice.txt b/Example_assignments/ps3alice.txt index 0649218..1f9ce1c 100644 --- a/Example_assignments/ps3alice.txt +++ b/Example_assignments/ps3alice.txt @@ -11,12 +11,12 @@ FAIL: Base class for autograding Python homework Tests func3 ---------------------------------------------------------------------- Traceback (most recent call last): - File "example.py", line 80, in test_printing - ["Hi", "My", "Name", "Is"]) -AssertionError: None != 'Hi' + File "example.py", line 69, in test_printing + out) +AssertionError: 'Hi' != None ---------------------------------------------------------------------- -Ran 3 tests in 0.016s +Ran 3 tests in 0.003s FAILED (failures=1) diff --git a/Example_assignments/ps3bob.py b/Example_assignments/ps3bob.py index d42510d..ef8f120 100644 --- a/Example_assignments/ps3bob.py +++ b/Example_assignments/ps3bob.py @@ -1,4 +1,4 @@ -## Bob, a CS student +## Bob, a bad CS student def func1(a): print a+1 diff --git a/Example_assignments/ps3bob.txt b/Example_assignments/ps3bob.txt index de01499..f7353bf 100644 --- a/Example_assignments/ps3bob.txt +++ b/Example_assignments/ps3bob.txt @@ -4,14 +4,14 @@ Tests func1 ... FAIL Base class for autograding Python homework Tests func2 ... FAIL Base class for autograding Python homework -Tests func3 ... FAIL +Tests func3 ... ok ====================================================================== FAIL: Base class for autograding Python homework Tests func1 ---------------------------------------------------------------------- Traceback (most recent call last): - File "example.py", line 55, in test_func1 + File "example.py", line 51, in test_func1 [1, 2, 3, 4, 5]) AssertionError: None != 1 @@ -20,21 +20,12 @@ FAIL: Base class for autograding Python homework Tests func2 ---------------------------------------------------------------------- Traceback (most recent call last): - File "example.py", line 63, in test_func2 + File "example.py", line 59, in test_func2 ["iH", "yM", "emaN", "sI"]) AssertionError: '' != 'iH' -====================================================================== -FAIL: Base class for autograding Python homework -Tests func3 ----------------------------------------------------------------------- -Traceback (most recent call last): - File "example.py", line 80, in test_printing - ["Hi", "My", "Name", "Is"]) -AssertionError: None != 'Hi' - ---------------------------------------------------------------------- -Ran 3 tests in 0.012s +Ran 3 tests in 0.021s -FAILED (failures=3) +FAILED (failures=2) diff --git a/Example_assignments/ps3dan.txt b/Example_assignments/ps3dan.txt index 6cc56cf..e2a9825 100644 --- a/Example_assignments/ps3dan.txt +++ b/Example_assignments/ps3dan.txt @@ -4,19 +4,10 @@ Tests func1 ... ok Base class for autograding Python homework Tests func2 ... ok Base class for autograding Python homework -Tests func3 ... FAIL +Tests func3 ... ok -====================================================================== -FAIL: Base class for autograding Python homework -Tests func3 ---------------------------------------------------------------------- -Traceback (most recent call last): - File "example.py", line 80, in test_printing - ["Hi", "My", "Name", "Is"]) -AssertionError: None != 'Hi' +Ran 3 tests in 0.001s ----------------------------------------------------------------------- -Ran 3 tests in 0.010s - -FAILED (failures=1) +OK diff --git a/auto_grader.py b/auto_grader.py index 615b5d4..828e8ca 100644 --- a/auto_grader.py +++ b/auto_grader.py @@ -23,26 +23,19 @@ If not, see """ +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO from difflib import get_close_matches as gcm import abc +import contextlib import sys import types import unittest sys.path.insert(0, "") - -class test_std_out(object): - """Implements a stdout for use in testing""" - - def __init__(self): - self.written = [] - self.saved = sys.stdout - - def write(self, string): - string = string.split() - if string: - self.written.append(string[0]) class auto_grader(unittest.TestCase): @@ -52,15 +45,20 @@ class auto_grader(unittest.TestCase): class. Grader is asked to subclass this with their own desired functionality. If - capturing printed statements is desired then make sure you import - auto_grader.my_std_out and make that your new stdout - - import sys - saved = sys.stdout - sys.stdout = auto_grader.test_std_out() - - If you have specific functionality you want then just implement your own - stdout, or inherit from auto_grader.test_std_out and implement as needed. + capturing printed statements is desired then just use the context manager + autograder.capture() like so + + def test_my_func(self): + my_func = my_subclass.black_magic(func_name) + + with self.capture() as (out, err): + map(self.assertEqual, + map(my_func, + arglist), + out) + + If if this doesn't do exactly you want then just override capture with the + desired functionality. When implementing your test functions you can just do @@ -76,7 +74,7 @@ def test_some_func(self, args): Just call test_assignment(subclass, good_names, student_name, - module_name, mod_path, grade_path [, stdout]) + module_name, mod_path, grade_path) With all of the appropriate arguments. Loops are ideal. For example: @@ -84,7 +82,7 @@ def test_some_func(self, args): test_assignment(subclass, my_names, submission[0], submission[1], submission[2], submission[3]) - Where submission has all of the appropriate data you want. + Where submission has all of the data you need. """ good_functions = [] student_functions = {} @@ -163,6 +161,20 @@ def test_my_function(self): print "Black magic error:" print "\t", e return + + @contextlib.contextmanager + def capture(self): + oldout, olderr = sys.stdout, sys.stderr + + try: + out=[StringIO(), StringIO()] + sys.stdout, sys.stderr = out + yield out + + finally: + sys.stdout, sys.stderr = oldout, olderr + out[0] = out[0].getvalue() + out[1] = out[1].getvalue() def test_assignment(subclass, good_names, stud_name, diff --git a/example.py b/example.py index 3ca03f1..e0112a2 100644 --- a/example.py +++ b/example.py @@ -31,20 +31,16 @@ saved = sys.stdout - class example_test_class(auto_grader.auto_grader): """An example grader for a certain homework""" def setUp(self): """Not implemented - Sets up the program""" - self.test_out = auto_grader.test_std_out() - sys.stdout = self.test_out - #pass + pass def tearDown(self): """Not implemented - 'tears down' the program""" - sys.stdout = saved - #pass + pass def test_func1(self): """Tests func1""" @@ -66,25 +62,13 @@ def test_printing(self): """Tests func3""" printing_function = example_test_class.black_magic("printer") - #self.test_out.write(self.test_out.written) - #self.test_out.write(self.test_out.written[-1:-4]) - sys.stdout = saved - print self.test_out - print self.test_out.written - print self.test_out.written[len(self.test_out.written)-4:] - sys.stdout = self.test_out - map(self.assertEqual, - map(printing_function, - ["Hi", "My", "Name", "Is"]), - #self.test_out.written[len(self.test_out.written)-4:]) - ["Hi", "My", "Name", "Is"]) - sys.stdout = saved - print self.test_out - print self.test_out.written - print self.test_out.written[len(self.test_out.written)-4:] - sys.stdout = self.test_out - - + with self.capture() as (out, errout): + map(self.assertEqual, + map(printing_function, + ["Hi", "My", "Name", "Is"]), + out) + + if __name__ == "__main__": os.chdir(os.getcwd() + "\\example_assignments" ) student_names = ["Alice", "Bob", "Dan"] @@ -101,4 +85,4 @@ def test_printing(self): submission[1], submission[2], submission[3]) - \ No newline at end of file + \ No newline at end of file