Skip to content

Instantly share code, notes, and snippets.

@inklesspen
inklesspen / README.md
Last active May 5, 2023 20:06
py.test session fixtures

Pytest's session fixture scope is really handy, but there are some things which need to execute only once per actual test session. For example, one of my session fixtures sets up DB tables at the start of the test session and tears them down at the end. (I use PostgreSQL's nested transactions to keep from having to drop and recreate tables between each individual test.)

@pytest.fixture(scope='session')
def dbtables(request, sqlengine):
    Base.metadata.create_all(sqlengine)

    def teardown():
        Base.metadata.drop_all(sqlengine)
@inklesspen
inklesspen / gist:4527085
Created January 14, 2013 01:05
barebones user model
import bcrypt # http://pypi.python.org/pypi/py-bcrypt
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
query = DBSession.query_property()
username = Column(Unicode(50), unique=True, nullable=False)
password_hash = Column(String(60), nullable=False)
@inklesspen
inklesspen / README.md
Last active April 27, 2026 12:55
Fast and flexible unit tests with live Postgres databases and fixtures

(This gist is pretty old; I've written up my current approach to the Pyramid integration on this blog post, but that blog post doesn't go into the transactional management, so you may still find this useful.)

Fast and flexible unit tests with live Postgres databases and fixtures

I've created a Pyramid scaffold which integrates Alembic, a migration tool, with the standard SQLAlchemy scaffold. (It also configures the Mako template system, because I prefer Mako.)

I am also using PostgreSQL for my database. PostgreSQL supports nested transactions. This means I can setup the tables at the beginning of the test session, then start a transaction before each test happens and roll it back after the test; in turn, this means my tests operate in the same environment I expect to use in production, but they are also fast.

I based my approach on [sontek's blog post](http://sontek.net/blog/

@pytest.fixture(scope='session', autouse=True)
def set_bcrypt_difficulty():
# The default difficulty is good for regular use, but slows down the tests too much.
Login.set_bcrypt_difficulty(2)
@pytest.fixture(scope='session')
def appsettings(request):
config_uri = os.path.abspath(request.config.option.ini)
setup_logging(config_uri)
settings = get_appsettings(config_uri)
@inklesspen
inklesspen / gist:4222841
Created December 6, 2012 08:39
ACLs, context objects, and URL Dispatch in Pyramid
# A worked example based on http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/urldispatch.html#using-pyramid-security-with-url-dispatch
# in your configuration section (typically in myapp/__init__.py)
config.add_route('articles.edit', 'article/{id}/edit', factory='myapp.acl.ArticleACL')
# in myapp/acl.py
class ArticleACL(object):
def __init__(self, request):
# First, we assume this ACL object is used only in routes that provide an article id; if need be, you can add some sanity checking here, or some if/else branching
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379')
settings['redis_conn'] = redis.from_url(redis_url)
======================================================================
ERROR: test_reentrant_dogpile (tests.cache.test_dbm_backend.DBMMutexTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jon/code/forks/dogpile.cache-fork/tests/cache/_fixtures.py", line 199, in test_reentrant_dogpile
reg.get_or_create("foo", create_foo),
File "/Users/jon/code/forks/dogpile.cache-fork/dogpile/cache/region.py", line 365, in get_or_create
expiration_time) as value:
File "/Users/jon/code/forks/dogpile.cache-fork/localpy/lib/python2.7/site-packages/dogpile/core/dogpile.py", line 142, in __enter__
return self._enter()
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/jon/code/forks/dogpile.cache-fork/tests/cache/_fixtures.py", line 104, in f
reg.get_or_create("some key", creator)
File "/Users/jon/code/forks/dogpile.cache-fork/dogpile/cache/region.py", line 365, in get_or_create
expiration_time) as value:
@inklesspen
inklesspen / gist:4089708
Created November 16, 2012 18:35
velruse/tweepy
# in your ini file:
velruse.twitter.consumer_key = yourkey
velruse.twitter.consumer_secret = yoursecret
# in __init__.py's main()
config.add_twitter_login_from_settings(prefix='velruse.twitter.')
config.add_view(views.login_complete_view, context='velruse.AuthenticationComplete')
import os
import pytest
from sqlalchemy import engine_from_config
from pyramid.paster import (
get_appsettings,
setup_logging,
)