Last active
December 30, 2015 15:38
-
-
Save eliasdorneles/a9d5e7ff9a0c00f5bf29 to your computer and use it in GitHub Desktop.
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