Шорин Александр / @kxepal
def test_fetch_doc_open_revs(self):
docid = 'docid'
docsatts = [({'_id': docid, '_rev': '1-ABC'}, None),
({'_id': docid, '_rev': '1-CDE'}, None),
({'_id': docid, '_rev': '1-EDC'}, None)]
revs = [doc['_rev'] for doc, _ in docsatts]
batch = yield from self.worker.fetch_doc_open_revs(...)
self.assertTrue(self.source.open_doc_revs.called)
args, kwargs = self.source.open_doc_revs.call_args
self.assertEqual((docid, revs), args[:2])
self.assertEqual({'atts_since': [], 'latest': True, 'revs': True},
kwargs)
self.assertEqual(batch, list(list(zip(*docsatts))[0])) # oh my...
def test_attfncontlz(self):
params = {'filename*0': 'foo', 'filename*01': 'bar'}
self.assertEqual('foo', content_disposition_filename(params))
def test_attfncontnc(self):
params = {'filename*0': 'foo', 'filename*2': 'bar'}
self.assertEqual('foo', content_disposition_filename(params))
def test_attfnconts1(self):
params = {'filename*1': 'foo', 'filename*2': 'bar'}
self.assertEqual(None, content_disposition_filename(params))
def test_attfnboth(self):
params = {'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'}
self.assertEqual('foo-ä.html',content_disposition_filename(params))
@pytest.mark.parametrize(('params', 'result'), [
({'filename*0': 'foo', 'filename*01': 'bar'}, 'foo'),
({'filename*0': 'foo', 'filename*2': 'bar'}, 'foo'),
({'filename*1': 'foo', 'filename*2': 'bar'}, None),
({'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'},
'foo-ä.html'),
])
def test_content_disposition_filename(params, result):
assert result == content_disposition_filename(params)
+----------------------------------------------------------------------+ | ВЕЛИКОЕ ВСЁ | | | | | | | | | | | | | | | | | | | | +---------------------+ | | Приемлемые данные | | | Х | +------------------------------------------------+-------------------^-+ | Наши тесты -------+
@asyncio.coroutine
def exists(self, rev=None, *, auth=None):
"""Checks if `document exists`_ in the database. Assumes success
on receiving response with `200 OK` status.
:param str rev: Document revision
:param :class:`aiocouchdb.authn.AuthProvider` auth:
:rtype: bool
"""
...
passed +-----------------------+ v | +-----------+ sample +------+ failed +----------+ +--------+ | Generator | --------> | Test | --------> | Shrinker | --> | Report | +-----------+ +------+ +----------+ +--------+ | ^ sample | ^ | +------------------+ | | | +-----------------------------------------------------------+ success
from pyqcheck import PyQCheck, Arbitrary
def eq(x,y):
return x * y == y * x and x + y == y + x
PyQCheck(verbose=True).add(
Arbitrary('boolean', 'boolean').property(
'!(x || y) == !x && !y',
lambda x, y: (not(x or y)) == ((not x) and (not y))
)
).add(
Arbitrary('integer', 'integer').property(
'x * y == y * x and x + y == y + x', eq
)
).run(10).result() # run(10) is test count == 10
Автор: David R. MacIver
https://github.com/DRMacIver/hypothesis
import math
from hypothesis import strategies as st
def nulls(): return st.none()
def booleans(): return st.booleans()
def numbers(): return st.integers() | st.floats()
def strings(): return st.text()
def arrays(elements): return st.lists(elements)
def objects(elements): return st.dictionaries(strings(), elements)
def values():
simple_values = nulls() | booleans() | numbers() | strings()
return (simple_values
| st.recursive(simple_values,
lambda children: arrays(children)
| objects(children)))
>>> doc = json_st.objects(json_st.values())
>>> doc.example()
{'G 〙G\u202fn〙G𝞠\u202f_n( n(nn_ n': 9.943339378805967e-309}
>>> doc.example()
{'': None, '\x85': '', '\U00014481': None,
'\u3000': -2.45410883359415e-309, '𒈏\x85': 1.5564453946197205e-308,
'I': '⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃',
'\u3000\u2029': -9.05230966734913e-309, '\U00014481\U00014481〯ⁱ': None,
'Nj': -1.80149788818e-311, '々〯_': -1.414261190585428e+202,
'\u2029ⁱNj': '⸃⸃⸃⸃⸃⸃⸃⸃⸃', '〯\u2029': inf, '々': '⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃',
'\u3000_': -1.0065151140507456e+206, 'Nj々': None, '々ⁱ': None,
'I\U00014481': -1.2296585975031088e+145, '\x80': '⸃⸃⸃⸃⸃',
'\x85ⁱ𒈏\x80\x80Nj': -6.438869672267061e+116, '𒈏〯': None,
'\u3000\x80': None, '\u2029\x80Nj': -698356955173.6532, '〯': '⸃⸃',
'々\x85': None, '\x85ⁱ\U00014481': None, '_〯': None, 'ⁱ': None,
'_\u3000_': '⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃⸃'}
>>> @given(json_st.objects(json_st.values()))
... def test_json(doc):
... assert json.loads(json.dumps(doc)) == doc
>>> test_json()
Falsifying example: test_json(doc={'': nan})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in test_json
File "./hypothesis/core.py", line 583, in wrapped_test
print_example=True, is_final=True
File "./hypothesis/executors/executors.py", line 25, in default_executor
return function()
File "./hypothesis/core.py", line 365, in run
return test(*args, **kwargs)
File "<stdin>", line 3, in test_json
AssertionError
>>> @given(json_st.objects(json_st.values()),
settings=Settings(verbosity=Verbosity.verbose))
... def test_json(doc):
... assert json.loads(json.dumps(doc)) == doc
...
>>> test_json()
Trying example: test_json(doc={})
Trying example: test_json(doc={'': True})
Trying example: test_json(doc={'': None})
Trying example: test_json(doc={'': False})
Trying example: test_json(doc={'': -43203256341979896423482879160843})
Trying example: test_json(doc={'': 24})
Trying example: test_json(doc={'': 9})
...
Trying example: test_json(doc={'': 397})
Trying example: test_json(doc={'': 100440})
Trying example: test_json(doc={'': 30323947834323202215971170911015})
Trying example: test_json(doc={'': 0.0})
Trying example: test_json(doc={'': inf})
Trying example: test_json(doc={'': -inf})
Successfully shrunk example 27 times
Falsifying example: test_json(doc={'': nan})
import math
from hypothesis import strategies as st
def nulls(): return st.none()
def booleans(): return st.booleans()
def numbers(): return st.integers() | st.floats().filter(math.isfinite)
def strings(): return st.text()
def arrays(elements): return st.lists(elements)
def objects(elements): return st.dictionaries(strings(), elements)
def values():
simple_values = nulls() | booleans() | numbers() | strings()
return (simple_values
| st.recursive(simple_values,
lambda children: arrays(children)
| objects(children)))
Hypothesis сохраняет найденные ошибки в SQLite базу для последующего воспроизведения.
+-------------+ replication +-------------+ store +-----------+ | CouchDB A | <-------------> | CouchDB B | <-------> | CI server | +-------------+ +-------------+ +-----------+ ^ ^ | store store | v v +-------------+ +-------------+ | Developer A | | Developer B | +-------------+ +-------------+
>>> from hypothesis import Settings
>>> Settings.register_profile("ci", Settings(max_examples=1000))
>>> Settings.register_profile("dev", Settings(max_examples=10))
>>> Settings.register_profile("debug", Settings(max_examples=10, verbosity=Verbosity.verbose))
>>> Settings.load_profile(os.getenv(u'HYPOTHESIS_PROFILE', 'default'))