Skip to content

Instantly share code, notes, and snippets.

@bplower

bplower/rst_parse.py

Created Feb 15, 2017
Embed
What would you like to do?
Automatic TestCase creation for rst literal_block shell examples in python class docstrings
import sys
import unittest
from docutils.core import publish_doctree
import subprocess
import opendir_dl
class ShellTestCase(unittest.TestCase):
def assert_shell_yields(self, command, expected_result):
result = subprocess.check_output(command, shell=True)[:-1]
if result != expected_result:
raise ValueError
def test_case_factory(command, result):
def test_shell_result(self):
self.assert_shell_yields(command, result)
return test_shell_result
def shell_factory(cls, name):
shell_test_case = type(cls.__name__, (ShellTestCase,), dict(ShellTestCase.__dict__))
method_counter = 0
for i in get_code_blocks(cls.__doc__):
func = test_case_factory(i['command'], i['result'])
setattr(shell_test_case, "test_{}".format(method_counter), func)
method_counter += 1
return shell_test_case
def get_code_blocks(source_text):
return_list = []
if not source_text:
return return_list
doctree = publish_doctree(source_text)
for child in doctree.children:
if child.tagname == "literal_block":
code_block = {}
code_lines = child.astext().split("\n")
# Parse execution line
code_block['command'] = code_lines[0][1:].strip()
# Parse execution result
code_block['result'] = str("\n".join(code_lines[1:]))
# Append to return list
return_list.append(code_block)
return return_list
class_list = [
opendir_dl.commands.tag_list_command,
opendir_dl.commands.TagCreateCommand,
opendir_dl.commands.TagDeleteCommand
]
thismodule = sys.modules[__name__]
for i in class_list:
shell_test_case = shell_factory(i, i.__name__)
setattr(thismodule, shell_test_case.__name__, shell_test_case)
# Example usage (note the names of classes from opendir_dl.commands are a little messy at the moment)
#
#>>> import unittest
#>>> import rst_parse
#>>> suite1 = unittest.TestLoader().loadTestsFromTestCase(rst_parse.tag_list_command)
#>>> suite2 = unittest.TestLoader().loadTestsFromTestCase(rst_parse.TagCreateCommand)
#>>> test_suite = unittest.TestSuite([suite, suite2])
#>>> unittest.TextTestRunner(verbosity=2).run(test_suite)
#test_0 (rst_parse.tag_list_command) ... ok
#test_0 (rst_parse.TagCreateCommand) ... Usage:
#test_0 (rst_parse.TagCreateCommand) ... Usage:
# opendir-dl help [options]
# <LONG OUTPUT REMOVED>
# opendir-dl database delete [options] <name>...
#ERROR
#
#======================================================================
#ERROR: test_0 (rst_parse.TagCreateCommand)
#----------------------------------------------------------------------
#Traceback (most recent call last):
# File "rst_parse.py", line 17, in test_shell_result
# self.assert_shell_yields(command, result)
# File "rst_parse.py", line 11, in assert_shell_yields
# result = subprocess.check_output(command, shell=True)[:-1]
# File "/usr/lib/python2.7/subprocess.py", line 574, in check_output
# raise CalledProcessError(retcode, cmd, output=output)
#CalledProcessError: Command 'opendir-dl create testing_command' returned non-zero exit status 1
#
#----------------------------------------------------------------------
#Ran 2 tests in 0.463s
#
#FAILED (errors=1)
#<unittest.runner.TextTestResult run=2 errors=1 failures=0>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment