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
#!/usr/bin/env python | |
# A toy Python BDD framework | |
# Decorator for test classes | |
def _context(): | |
def add_test_method(cls, method, name): | |
def test(self, *args, **kwargs): | |
return method(self, self.subject(), *args, **kwargs) | |
test.func_name = 'test_' + name | |
setattr(cls, test.func_name, test) | |
def decorator(cls): | |
import inspect | |
class NewClassTest(cls): | |
pass | |
for name, method in inspect.getmembers(cls, inspect.ismethod): | |
if name.startswith('should_') or name.startswith('when_'): | |
add_test_method(NewClassTest, method, name) | |
NewClassTest.__name__ = cls.__name__ | |
return NewClassTest | |
return decorator | |
context = _context() | |
# Some test code: | |
import unittest | |
@context | |
class Defaultdict(unittest.TestCase): | |
def subject(self): | |
from collections import defaultdict | |
return defaultdict(int) | |
def should_support_dict_set_key(self, it): | |
it[2] = 4 | |
self.assertEquals(4, it[2]) | |
def when_new_key_should_return_0(self, it): | |
self.assertNotIn(0, it) | |
self.assertEquals(0, it[0]) | |
self.assertIn(0, it) | |
@context | |
class Deque(unittest.TestCase): | |
def subject(self): | |
import collections | |
return collections.deque() | |
def should_append(self, it): | |
it.append(3) | |
it.append(5) | |
it.append(7) | |
self.assertEquals(it[0], 3) | |
self.assertEquals(it[2], 7) | |
def when_append_left_should_insert_at_beginning(self, it): | |
it.append(3) | |
it.append(5) | |
it.append(7) | |
it.appendleft(1) | |
self.assertEquals(it[0], 1) | |
@unittest.skip('test skipping') | |
def should_skip(self, _): | |
raise AssertionError("Wasn't skipped :(") | |
# And yes, @mock.patch decorator works normally: | |
import shutil | |
def copy_file(src, dest): | |
shutil.copy(src, dest) | |
import mock | |
@context | |
class Shutil(unittest.TestCase): | |
def subject(self): | |
return copy_file | |
@mock.patch('shutil.copy', autospec=True) | |
def should_call_shutil_copy(self, it, mock_copy): | |
it(mock.sentinel.a, mock.sentinel.b) | |
mock_copy.assert_called_once_with(mock.sentinel.a, mock.sentinel.b) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment