Skip to content

Instantly share code, notes, and snippets.

Last active September 29, 2023 08:13
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
A python wrapper to show differences using custom tools
import unittest
import tempfile
import subprocess
# One could use vimdiff, meld, or even diff
def diff_with(test_func=None, tool='vimdiff'):
# The decorator was used with parentheses
# thus the test_func is not set, we need to call it ourself
if test_func is None:
return functools.partial(diff_with, tool=tool)
def diff_to_files(diff_str):
lines = diff_str.splitlines()
expected_lines = []
actual_lines = []
for line in lines:
if line.startswith('+ '):
elif line.startswith('- '):
elif line.startswith(' '): # Two spaces for common lines
return expected_lines, actual_lines
def wrapper(test_case, *args, **kwargs):
# Call the original test function
result = test_func(test_case, *args, **kwargs)
except AssertionError as e:
expected_lines, actual_lines = diff_to_files(str(e))
expected = '\n'.join(expected_lines)
actual = '\n'.join(actual_lines)
with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt', prefix='expected_') as f1, \
tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt', prefix='actual_') as f2:
# Call the tool to show differences[tool,,])
raise # re-raise the original exception
return result
return wrapper
class TestUtilityFunctions(unittest.TestCase):
@diff_with # use the default tool defined above
def test_failed_default(self):
expected = "Hello\nWorld\n"
actual = "Hello\nUniverse\n"
self.assertEqual(expected, actual)
def test_failed_custom(self):
expected = "Hello\nAll\n"
actual = "Hello\nEveryone\n"
self.assertEqual(expected, actual)
@diff_with # Should not trigger the diff tool if matched
def test_passed(self):
expected = "Hello\nWorld\n"
actual = "Hello\nWorld\n"
self.assertEqual(expected, actual)
if __name__ == "__main__":
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment