Created
February 15, 2017 08:48
-
-
Save brahmlower/87b02cfb478ce77765deb32dcabbefce to your computer and use it in GitHub Desktop.
Automatic TestCase creation for rst literal_block shell examples in python class docstrings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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