##// END OF EJS Templates
Moving trap rule example.
Moving trap rule example.

File last commit:

r15469:f7bf2480
r16075:065b2492
Show More
tools.py
458 lines | 13.6 KiB | text/x-python | PythonLexer
MinRK
remove a few more obsolete twisted notes
r6421 """Generic testing tools.
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
Authors
-------
- Fernando Perez <Fernando.Perez@berkeley.edu>
"""
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 from __future__ import absolute_import
#-----------------------------------------------------------------------------
MinRK
test that `-h` and `--help-all` work for various IPython entry points...
r12354 # Copyright (C) 2009 The IPython Development Team
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 #-----------------------------------------------------------------------------
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
#-----------------------------------------------------------------------------
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 # Imports
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 #-----------------------------------------------------------------------------
import os
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 import re
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 import sys
MinRK
put test_hist.sqlite in tempdir, to prevent polluting filesystem
r4486 import tempfile
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 from contextlib import contextmanager
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 from io import StringIO
MinRK
use Popen command list for ipexec...
r11475 from subprocess import Popen, PIPE
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214
Fernando Perez
Remove accidentally introduced runtime nose dependencies.
r2442 try:
# These tools are used by parts of the runtime, so we make the nose
# dependency optional at this point. Nose is a hard dependency to run the
# test suite, but NOT to use ipython itself.
import nose.tools as nt
has_nose = True
except ImportError:
has_nose = False
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 from IPython.config.loader import Config
MinRK
test that `-h` and `--help-all` work for various IPython entry points...
r12354 from IPython.utils.process import get_output_error_code
Brandon Parsons
moved getdefaultencoding from text to py3compat
r6653 from IPython.utils.text import list_strings
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 from IPython.utils.io import temp_pyfile, Tee
from IPython.utils import py3compat
Brandon Parsons
saner default encoding mechanism
r6716 from IPython.utils.encoding import DEFAULT_ENCODING
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461 from . import decorators as dec
MinRK
fix skip_doctest import in testing.tools
r3905 from . import skipdoctest
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 #-----------------------------------------------------------------------------
# Functions and classes
#-----------------------------------------------------------------------------
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461 # The docstring for full_path doctests differently on win32 (different path
# separator) so just skip the doctest there. The example remains informative.
MinRK
fix skip_doctest import in testing.tools
r3905 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
Brian Granger
Fixing tests in IPython.testing.
r1982
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461 @doctest_deco
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 def full_path(startPath,files):
"""Make full paths for all the listed files, based on startPath.
Only the base part of startPath is kept, since this routine is typically
Thomas Kluyver
Various minor docs fixes
r13592 used with a script's ``__file__`` variable as startPath. The base of startPath
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 is then prepended to all the listed files, forming the output list.
Brian Granger
Merging Fernando's fixes from his trunk-dev and fixing testing things....
r1973 Parameters
----------
Thomas Kluyver
Various minor docs fixes
r13592 startPath : string
Initial path to use as the base for the results. This path is split
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 using os.path.split() and only its first component is kept.
Thomas Kluyver
Various minor docs fixes
r13592 files : string or list
One or more files.
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
Brian Granger
Merging Fernando's fixes from his trunk-dev and fixing testing things....
r1973 Examples
--------
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
>>> full_path('/foo/bar.py',['a.txt','b.txt'])
['/foo/a.txt', '/foo/b.txt']
>>> full_path('/foo',['a.txt','b.txt'])
['/a.txt', '/b.txt']
Thomas Kluyver
Various minor docs fixes
r13592 If a single file is given, the output is still a list::
>>> full_path('/foo','a.txt')
['/a.txt']
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 """
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 files = list_strings(files)
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 base = os.path.split(startPath)[0]
return [ os.path.join(base,f) for f in files ]
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353
def parse_test_output(txt):
"""Parse the output of a test run and return errors, failures.
Parameters
----------
txt : str
Text output of a test run, assumed to contain a line of one of the
following forms::
Thomas Kluyver
Miscellaneous docs fixes
r9244
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 'FAILED (errors=1)'
'FAILED (failures=1)'
'FAILED (errors=1, failures=1)'
Returns
-------
Thomas Kluyver
Various minor docs fixes
r13592 nerr, nfail
number of errors and failures.
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 """
err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
if err_m:
nerr = int(err_m.group(1))
nfail = 0
return nerr, nfail
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
if fail_m:
nerr = 0
nfail = int(fail_m.group(1))
return nerr, nfail
both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
re.MULTILINE)
if both_m:
nerr = int(both_m.group(1))
nfail = int(both_m.group(2))
return nerr, nfail
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 # If the input didn't match any of these forms, assume no error/failures
return 0, 0
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 # So nose doesn't think this is a test
parse_test_output.__test__ = False
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
def default_argv():
"""Return a valid default argv for creating testing instances of ipython"""
Fernando Perez
Minimize stdout side effects in testing instances.
r2477 return ['--quick', # so no config file is loaded
# Other defaults to minimize side effects on stdout
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 '--colors=NoColor', '--no-term-title','--no-banner',
'--autocall=0']
Brian Granger
More work addressing review comments for Fernando's branch....
r2499
def default_config():
"""Return a config object with good defaults for testing."""
config = Config()
Brian Granger
Complete reorganization of InteractiveShell....
r2761 config.TerminalInteractiveShell.colors = 'NoColor'
config.TerminalTerminalInteractiveShell.term_title = False,
config.TerminalInteractiveShell.autocall = 0
Julian Taylor
remove mktemp usage...
r15372 f = tempfile.NamedTemporaryFile(suffix=u'test_hist.sqlite', delete=False)
config.HistoryManager.hist_file = f.name
f.close()
Thomas Kluyver
Tests can no longer use db in memory: doesn't work with multiple threads.
r3712 config.HistoryManager.db_cache_size = 10000
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 return config
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
Paul Ivanov
moved get_ipython_cmd into separate function
r11861 def get_ipython_cmd(as_string=False):
"""
Return appropriate IPython command line name. By default, this will return
a list that can be used with subprocess.Popen, for example, but passing
`as_string=True` allows for returning the IPython command as a string.
Parameters
----------
as_string: bool
Flag to allow to return the command as a string.
"""
Thomas Kluyver
remove workaround for 2.6 support
r12151 ipython_cmd = [sys.executable, "-m", "IPython"]
Paul Ivanov
moved get_ipython_cmd into separate function
r11861
if as_string:
ipython_cmd = " ".join(ipython_cmd)
return ipython_cmd
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 def ipexec(fname, options=None):
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 """Utility to call 'ipython filename'.
MinRK
getoutput wants a string, not a command list
r11353 Starts IPython with a minimal and safe configuration to make startup as fast
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 as possible.
Note that this starts IPython in a subprocess!
Parameters
----------
fname : str
Name of file to be executed (should have .py or .ipy extension).
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 options : optional, list
Extra command-line flags to be passed to IPython.
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 Returns
-------
(stdout, stderr) of ipython subprocess.
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 """
if options is None: options = []
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Minimize stdout side effects in testing instances.
r2477 # For these subprocess calls, eliminate all prompt printing so we only see
# output from script execution
MinRK
PromptManager fixes...
r5548 prompt_opts = [ '--PromptManager.in_template=""',
'--PromptManager.in2_template=""',
'--PromptManager.out_template=""'
MinRK
catch up tests to recent changes...
r4029 ]
MinRK
use Popen command list for ipexec...
r11475 cmdargs = default_argv() + prompt_opts + options
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 test_dir = os.path.dirname(__file__)
Paul Ivanov
moved get_ipython_cmd into separate function
r11861
ipython_cmd = get_ipython_cmd()
Fernando Perez
Various fixes for IPython.core tests to pass under win32.
r2446 # Absolute path for filename
Brian Granger
Removed the top-level iptest.py and INSTALLED logic....
r2507 full_fname = os.path.join(test_dir, fname)
MinRK
use Popen command list for ipexec...
r11475 full_cmd = ipython_cmd + cmdargs + [full_fname]
Thomas Kluyver
Unset PYTHONWARNINGS envvar before running subprocess tests....
r15466 env = os.environ.copy()
Thomas Kluyver
Only pop PYTHONWARNINGS if its there.
r15469 env.pop('PYTHONWARNINGS', None) # Avoid extraneous warnings appearing on stderr
Thomas Kluyver
Unset PYTHONWARNINGS envvar before running subprocess tests....
r15466 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE, env=env)
MinRK
use Popen command list for ipexec...
r11475 out, err = p.communicate()
out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
MinRK
more general fix for #662...
r6190 # `import readline` causes 'ESC[?1034h' to be output sometimes,
# so strip that out before doing comparisons
MinRK
strip leading 'ESC[?1034h' in tests caused by `import readline`...
r4470 if out:
MinRK
more general fix for #662...
r6190 out = re.sub(r'\x1b\[[^h]+h', '', out)
MinRK
unpack out,err in ipexec...
r6221 return out, err
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
Fernando Perez
Robustness fixes in test suite machinery....
r2494 def ipexec_validate(fname, expected_out, expected_err='',
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 options=None):
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 """Utility to call 'ipython filename' and validate output/error.
This function raises an AssertionError if the validation fails.
Note that this starts IPython in a subprocess!
Parameters
----------
fname : str
Name of the file to be executed (should have .py or .ipy extension).
expected_out : str
Expected stdout of the process.
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 expected_err : optional, str
Expected stderr of the process.
options : optional, list
Extra command-line flags to be passed to IPython.
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 Returns
-------
None
"""
Fernando Perez
Remove accidentally introduced runtime nose dependencies.
r2442 import nose.tools as nt
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
fix missing options arg to ipexec in ipexec_validate
r5249 out, err = ipexec(fname, options)
Fernando Perez
Robustness fixes in test suite machinery....
r2494 #print 'OUT', out # dbg
#print 'ERR', err # dbg
# If there are any errors, we must check those befor stdout, as they may be
# more informative than simply having an empty stdout.
if err:
if expected_err:
Jörgen Stenarson
Adding tests and another line normalization for stderr.
r8291 nt.assert_equal("\n".join(err.strip().splitlines()), "\n".join(expected_err.strip().splitlines()))
Fernando Perez
Robustness fixes in test suite machinery....
r2494 else:
raise ValueError('Running file %r produced error: %r' %
(fname, err))
# If no errors or output on stderr was expected, match stdout
Jörgen Stenarson
Normalize line endings for ipexec_validate, fix for #2315....
r8288 nt.assert_equal("\n".join(out.strip().splitlines()), "\n".join(expected_out.strip().splitlines()))
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415
class TempFileMixin(object):
"""Utility class to create temporary Python/IPython files.
Meant as a mixin class for test cases."""
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 def mktmp(self, src, ext='.py'):
"""Make a valid python temp file."""
fname, f = temp_pyfile(src, ext)
self.tmpfile = f
self.fname = fname
Fernando Perez
Make our temp file mixin unittest-friendly....
r2907 def tearDown(self):
Fernando Perez
Various fixes for IPython.core tests to pass under win32.
r2446 if hasattr(self, 'tmpfile'):
# If the tmpfile wasn't made because of skipped tests, like in
# win32, there's nothing to cleanup.
self.tmpfile.close()
try:
os.unlink(self.fname)
except:
# On Windows, even though we close the file, we still can't
# delete it. I have no clue why
pass
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 pair_fail_msg = ("Testing {0}\n\n"
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 "In:\n"
" {1!r}\n"
"Expected:\n"
" {2!r}\n"
"Got:\n"
" {3!r}\n")
def check_pairs(func, pairs):
Bernardo B. Marques
remove all trailling spaces
r4872 """Utility function for the common case of checking a function with a
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 sequence of input/output pairs.
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 Parameters
----------
func : callable
The function to be tested. Should accept a single argument.
pairs : iterable
A list of (input, expected_output) tuples.
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 Returns
-------
None. Raises an AssertionError if any output does not match the expected
value.
"""
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 for inp, expected in pairs:
out = func(inp)
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214
Thomas Kluyver
Follow Fernando's suggestions.
r4920
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 if py3compat.PY3:
MyStringIO = StringIO
else:
# In Python 2, stdout/stderr can have either bytes or unicode written to them,
# so we need a class that can handle both.
class MyStringIO(StringIO):
def write(self, s):
Brandon Parsons
saner default encoding mechanism
r6716 s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 super(MyStringIO, self).write(s)
MinRK
add regex support to AssertPrints
r15219 _re_type = type(re.compile(r''))
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
Thomas Kluyver
Add failing test for issue gh-1456
r8099 -------
{2!s}
-------
"""
Thomas Kluyver
Follow Fernando's suggestions.
r4920
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 class AssertPrints(object):
"""Context manager for testing that code prints certain text.
Examples
--------
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 >>> with AssertPrints("abc", suppress=False):
Thomas Kluyver
Fix doctests in IPython.testing
r13393 ... print("abcd")
... print("def")
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 ...
abcd
def
"""
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 def __init__(self, s, channel='stdout', suppress=True):
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 self.s = s
MinRK
add regex support to AssertPrints
r15219 if isinstance(self.s, (py3compat.string_types, _re_type)):
Thomas Kluyver
Add failing test for SyntaxError display
r12543 self.s = [self.s]
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 self.channel = channel
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 self.suppress = suppress
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901
def __enter__(self):
self.orig_stream = getattr(sys, self.channel)
self.buffer = MyStringIO()
self.tee = Tee(self.buffer, channel=self.channel)
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 setattr(sys, self.channel, self.buffer if self.suppress else self.tee)
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901
def __exit__(self, etype, value, traceback):
Thomas Kluyver
Add failing test for gh-4361
r12950 if value is not None:
# If an error was raised, don't check anything else
return False
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 self.tee.flush()
setattr(sys, self.channel, self.orig_stream)
printed = self.buffer.getvalue()
Thomas Kluyver
Add failing test for SyntaxError display
r12543 for s in self.s:
MinRK
add regex support to AssertPrints
r15219 if isinstance(s, _re_type):
assert s.search(printed), notprinted_msg.format(s.pattern, self.channel, printed)
else:
assert s in printed, notprinted_msg.format(s, self.channel, printed)
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901 return False
Thomas Kluyver
Add failing test for issue gh-1456
r8099
printed_msg = """Found {0!r} in printed output (on {1}):
-------
{2!s}
-------
"""
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 class AssertNotPrints(AssertPrints):
"""Context manager for checking that certain output *isn't* produced.
Counterpart of AssertPrints"""
def __exit__(self, etype, value, traceback):
Thomas Kluyver
Add failing test for gh-4361
r12950 if value is not None:
# If an error was raised, don't check anything else
return False
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 self.tee.flush()
setattr(sys, self.channel, self.orig_stream)
printed = self.buffer.getvalue()
Thomas Kluyver
Add failing test for SyntaxError display
r12543 for s in self.s:
MinRK
add regex support to AssertPrints
r15219 if isinstance(s, _re_type):
assert not s.search(printed), printed_msg.format(s.pattern, self.channel, printed)
else:
assert s not in printed, printed_msg.format(s, self.channel, printed)
Thomas Kluyver
Use AssertPrints in tests for autoreload extension.
r4904 return False
Thomas Kluyver
Add AssertPrints context manager to check output from tests.
r4901
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 @contextmanager
def mute_warn():
from IPython.utils import warn
save_warn = warn.warn
warn.warn = lambda *a, **kw: None
try:
yield
finally:
Robert Kern
BUG: Allow %magic argument filenames with spaces to be specified with quotes under win32.
r4688 warn.warn = save_warn
@contextmanager
def make_tempfile(name):
""" Create an empty, named, temporary file for the duration of the context.
"""
f = open(name, 'w')
f.close()
try:
yield
finally:
os.unlink(name)
Takafumi Arakaki
Add tests for IPython.lib.latextools
r7858
@contextmanager
def monkeypatch(obj, name, attr):
"""
Context manager to replace attribute named `name` in `obj` with `attr`.
"""
orig = getattr(obj, name)
setattr(obj, name, attr)
yield
setattr(obj, name, orig)
MinRK
test that `-h` and `--help-all` work for various IPython entry points...
r12354
def help_output_test(subcommand=''):
"""test that `ipython [subcommand] -h` works"""
Thomas Kluyver
Use argument lists for testing command help output....
r13739 cmd = get_ipython_cmd() + [subcommand, '-h']
MinRK
test that `-h` and `--help-all` work for various IPython entry points...
r12354 out, err, rc = get_output_error_code(cmd)
nt.assert_equal(rc, 0, err)
nt.assert_not_in("Traceback", err)
nt.assert_in("Options", out)
nt.assert_in("--help-all", out)
return out, err
def help_all_output_test(subcommand=''):
"""test that `ipython [subcommand] --help-all` works"""
Thomas Kluyver
Use argument lists for testing command help output....
r13739 cmd = get_ipython_cmd() + [subcommand, '--help-all']
MinRK
test that `-h` and `--help-all` work for various IPython entry points...
r12354 out, err, rc = get_output_error_code(cmd)
nt.assert_equal(rc, 0, err)
nt.assert_not_in("Traceback", err)
nt.assert_in("Options", out)
nt.assert_in("Class parameters", out)
return out, err