##// END OF EJS Templates
Add test utility for parsing test output from stdout/stderr
Fernando Perez -
Show More
@@ -1,52 +1,61 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Tests for testing.tools
5 5 """
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (C) 2008-2009 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 import os
19 19 import sys
20 20
21 21 import nose.tools as nt
22 22
23 23 from IPython.testing import decorators as dec
24 from IPython.testing.tools import full_path
24 from IPython.testing.tools import full_path, parse_test_output
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Tests
28 28 #-----------------------------------------------------------------------------
29 29
30
31 30 @dec.skip_win32
32 31 def test_full_path_posix():
33 32 spath = '/foo/bar.py'
34 33 result = full_path(spath,['a.txt','b.txt'])
35 34 nt.assert_equal(result, ['/foo/a.txt', '/foo/b.txt'])
36 35 spath = '/foo'
37 36 result = full_path(spath,['a.txt','b.txt'])
38 37 nt.assert_equal(result, ['/a.txt', '/b.txt'])
39 38 result = full_path(spath,'a.txt')
40 39 nt.assert_equal(result, ['/a.txt'])
41 40
42 41
43 42 @dec.skip_if_not_win32
44 43 def test_full_path_win32():
45 44 spath = 'c:\\foo\\bar.py'
46 45 result = full_path(spath,['a.txt','b.txt'])
47 46 nt.assert_equal(result, ['c:\\foo\\a.txt', 'c:\\foo\\b.txt'])
48 47 spath = 'c:\\foo'
49 48 result = full_path(spath,['a.txt','b.txt'])
50 49 nt.assert_equal(result, ['c:\\a.txt', 'c:\\b.txt'])
51 50 result = full_path(spath,'a.txt')
52 nt.assert_equal(result, ['c:\\a.txt']) No newline at end of file
51 nt.assert_equal(result, ['c:\\a.txt'])
52
53
54 def test_parser():
55 err = ("FAILED (errors=1)", 1, 0)
56 fail = ("FAILED (failures=1)", 0, 1)
57 both = ("FAILED (errors=1, failures=1)", 1, 1)
58 for txt, nerr, nfail in [err, fail, both]:
59 nerr1, nfail1 = parse_test_output(txt)
60 yield (nt.assert_equal, nerr, nerr1)
61 yield (nt.assert_equal, nfail, nfail1)
@@ -1,89 +1,133 b''
1 1 """Generic testing tools that do NOT depend on Twisted.
2 2
3 3 In particular, this module exposes a set of top-level assert* functions that
4 4 can be used in place of nose.tools.assert* in method generators (the ones in
5 5 nose can not, at least as of nose 0.10.4).
6 6
7 7 Note: our testing package contains testing.util, which does depend on Twisted
8 8 and provides utilities for tests that manage Deferreds. All testing support
9 9 tools that only depend on nose, IPython or the standard library should go here
10 10 instead.
11 11
12 12
13 13 Authors
14 14 -------
15 15 - Fernando Perez <Fernando.Perez@berkeley.edu>
16 16 """
17 17
18 18 #*****************************************************************************
19 19 # Copyright (C) 2009 The IPython Development Team
20 20 #
21 21 # Distributed under the terms of the BSD License. The full license is in
22 22 # the file COPYING, distributed as part of this software.
23 23 #*****************************************************************************
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Required modules and packages
27 27 #-----------------------------------------------------------------------------
28 28
29 29 import os
30 import re
30 31 import sys
31 32
32 33 import nose.tools as nt
33 34
34 35 from IPython.tools import utils
35 36 from IPython.testing import decorators as dec
36 37
37 38 #-----------------------------------------------------------------------------
38 39 # Globals
39 40 #-----------------------------------------------------------------------------
40 41
41 42 # Make a bunch of nose.tools assert wrappers that can be used in test
42 43 # generators. This will expose an assert* function for each one in nose.tools.
43 44
44 45 _tpl = """
45 46 def %(name)s(*a,**kw):
46 47 return nt.%(name)s(*a,**kw)
47 48 """
48 49
49 50 for _x in [a for a in dir(nt) if a.startswith('assert')]:
50 51 exec _tpl % dict(name=_x)
51 52
52 53 #-----------------------------------------------------------------------------
53 54 # Functions and classes
54 55 #-----------------------------------------------------------------------------
55 56
56 57
57 58 def full_path(startPath,files):
58 59 """Make full paths for all the listed files, based on startPath.
59 60
60 61 Only the base part of startPath is kept, since this routine is typically
61 62 used with a script's __file__ variable as startPath. The base of startPath
62 63 is then prepended to all the listed files, forming the output list.
63 64
64 65 Parameters
65 66 ----------
66 67 startPath : string
67 68 Initial path to use as the base for the results. This path is split
68 69 using os.path.split() and only its first component is kept.
69 70
70 71 files : string or list
71 72 One or more files.
72 73
73 74 Examples
74 75 --------
75 76
76 77 >>> full_path('/foo/bar.py',['a.txt','b.txt'])
77 78 ['/foo/a.txt', '/foo/b.txt']
78 79
79 80 >>> full_path('/foo',['a.txt','b.txt'])
80 81 ['/a.txt', '/b.txt']
81 82
82 83 If a single file is given, the output is still a list:
83 84 >>> full_path('/foo','a.txt')
84 85 ['/a.txt']
85 86 """
86 87
87 88 files = utils.list_strings(files)
88 89 base = os.path.split(startPath)[0]
89 90 return [ os.path.join(base,f) for f in files ]
91
92
93 def parse_test_output(txt):
94 """Parse the output of a test run and return errors, failures.
95
96 Parameters
97 ----------
98 txt : str
99 Text output of a test run, assumed to contain a line of one of the
100 following forms::
101 'FAILED (errors=1)'
102 'FAILED (failures=1)'
103 'FAILED (errors=1, failures=1)'
104
105 Returns
106 -------
107 nerr, nfail: number of errors and failures.
108 """
109
110 err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
111 if err_m:
112 nerr = int(err_m.group(1))
113 nfail = 0
114 return nerr, nfail
115
116 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
117 if fail_m:
118 nerr = 0
119 nfail = int(fail_m.group(1))
120 return nerr, nfail
121
122 both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
123 re.MULTILINE)
124 if both_m:
125 nerr = int(both_m.group(1))
126 nfail = int(both_m.group(2))
127 return nerr, nfail
128
129 # If the input didn't match any of these forms, assume no error/failures
130 return 0, 0
131
132 # So nose doesn't think this is a test
133 parse_test_output.__test__ = False
General Comments 0
You need to be logged in to leave comments. Login now