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