- coverage was not working (and needs to be fixed in SQLAlchemy too),
go back to using a "bootstrap" system where we load in pytestplugin/ noseplugin via file importing, plugin/ is not used as a package. - identify the pytest_sessionstart hook as the best place to do plugin_base.post_begin() and actually begin importing main modules; this is where coverage has actually started. - we're now targeting 1.0.0 as this has to be ported to SQLAlchemy. - start using .coveragerc
This commit is contained in:
parent
58149cf4d0
commit
adc081312e
|
@ -0,0 +1,5 @@
|
|||
[run]
|
||||
include=alembic/*
|
||||
|
||||
[report]
|
||||
omit=alembic/testing/*
|
|
@ -1,2 +1,2 @@
|
|||
from . import postgresql, mysql, sqlite, mssql, oracle
|
||||
from .impl import DefaultImpl
|
||||
from . import postgresql, mysql, sqlite, mssql, oracle # pragma: no cover
|
||||
from .impl import DefaultImpl # pragma: no cover
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0
|
||||
"""
|
||||
|
||||
import collections
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
|
|
@ -8,12 +8,12 @@ from alembic.compat import u
|
|||
from alembic.script import Script, ScriptDirectory
|
||||
from alembic import util
|
||||
from . import engines
|
||||
from alembic.testing.plugin import plugin_base
|
||||
from . import provision
|
||||
|
||||
|
||||
def _get_staging_directory():
|
||||
if plugin_base.FOLLOWER_IDENT:
|
||||
return "scratch_%s" % plugin_base.FOLLOWER_IDENT
|
||||
if provision.FOLLOWER_IDENT:
|
||||
return "scratch_%s" % provision.FOLLOWER_IDENT
|
||||
else:
|
||||
return 'scratch'
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0
|
||||
"""
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"""Import stub for mock library.
|
||||
|
||||
NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0
|
||||
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
@ -18,7 +18,7 @@ if py33:
|
|||
from unittest.mock import MagicMock, Mock, call, patch
|
||||
else:
|
||||
try:
|
||||
from mock import MagicMock, Mock, call, patch
|
||||
from mock import MagicMock, Mock, call, patch # noqa
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"SQLAlchemy's test suite requires the "
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
"""
|
||||
Bootstrapper for nose/pytest plugins.
|
||||
|
||||
The entire rationale for this system is to get the modules in plugin/
|
||||
imported without importing all of the supporting library, so that we can
|
||||
set up things for testing before coverage starts.
|
||||
|
||||
The rationale for all of plugin/ being *in* the supporting library in the
|
||||
first place is so that the testing and plugin suite is available to other
|
||||
libraries, mainly external SQLAlchemy and Alembic dialects, to make use
|
||||
of the same test environment and standard suites available to
|
||||
SQLAlchemy/Alembic themselves without the need to ship/install a separate
|
||||
package outside of SQLAlchemy.
|
||||
|
||||
NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
bootstrap_file = locals()['bootstrap_file']
|
||||
to_bootstrap = locals()['to_bootstrap']
|
||||
|
||||
|
||||
def load_file_as_module(name):
|
||||
path = os.path.join(os.path.dirname(bootstrap_file), "%s.py" % name)
|
||||
if sys.version_info >= (3, 3):
|
||||
from importlib import machinery
|
||||
mod = machinery.SourceFileLoader(name, path).load_module()
|
||||
else:
|
||||
import imp
|
||||
mod = imp.load_source(name, path)
|
||||
return mod
|
||||
|
||||
if to_bootstrap == "pytest":
|
||||
sys.modules["alembic_plugin_base"] = load_file_as_module("plugin_base")
|
||||
sys.modules["alembic_pytestplugin"] = load_file_as_module("pytestplugin")
|
||||
elif to_bootstrap == "nose":
|
||||
sys.modules["alembic_plugin_base"] = load_file_as_module("plugin_base")
|
||||
sys.modules["alembic_noseplugin"] = load_file_as_module("noseplugin")
|
||||
else:
|
||||
raise Exception("unknown bootstrap: %s" % to_bootstrap) # noqa
|
|
@ -5,14 +5,21 @@
|
|||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
"""
|
||||
Enhance nose with extra options and behaviors for running SQLAlchemy tests.
|
||||
|
||||
|
||||
NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0.
|
||||
|
||||
"""
|
||||
|
||||
"""Enhance nose with extra options and behaviors for running SQLAlchemy tests.
|
||||
|
||||
|
||||
"""
|
||||
try:
|
||||
# installed by bootstrap.py
|
||||
import alembic_plugin_base as plugin_base
|
||||
except ImportError:
|
||||
# assume we're a package, use traditional import
|
||||
from . import plugin_base
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -21,16 +28,6 @@ from nose.plugins import Plugin
|
|||
fixtures = None
|
||||
|
||||
py3k = sys.version_info >= (3, 0)
|
||||
# no package imports yet! this prevents us from tripping coverage
|
||||
# too soon.
|
||||
path = os.path.join(os.path.dirname(__file__), "plugin_base.py")
|
||||
if sys.version_info >= (3, 3):
|
||||
from importlib import machinery
|
||||
plugin_base = machinery.SourceFileLoader(
|
||||
"plugin_base", path).load_module()
|
||||
else:
|
||||
import imp
|
||||
plugin_base = imp.load_source("plugin_base", path)
|
||||
|
||||
|
||||
class NoseSQLAlchemy(Plugin):
|
||||
|
@ -60,10 +57,10 @@ class NoseSQLAlchemy(Plugin):
|
|||
|
||||
plugin_base.set_coverage_flag(options.enable_plugin_coverage)
|
||||
|
||||
def begin(self):
|
||||
global fixtures
|
||||
from alembic.testing import fixtures # noqa
|
||||
|
||||
def begin(self):
|
||||
plugin_base.post_begin()
|
||||
|
||||
def describeTest(self, test):
|
||||
|
@ -77,7 +74,6 @@ class NoseSQLAlchemy(Plugin):
|
|||
cls = fn.__self__.cls
|
||||
else:
|
||||
cls = fn.im_class
|
||||
print "METH:", fn, "CLS:", cls
|
||||
return plugin_base.want_method(cls, fn)
|
||||
|
||||
def wantClass(self, cls):
|
||||
|
|
|
@ -11,7 +11,7 @@ so that we can continue to support nose and also begin adding new
|
|||
functionality via py.test.
|
||||
|
||||
NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0
|
||||
|
||||
|
||||
"""
|
||||
|
@ -34,11 +34,10 @@ if py3k:
|
|||
else:
|
||||
import ConfigParser as configparser
|
||||
|
||||
FOLLOWER_IDENT = None
|
||||
|
||||
# late imports
|
||||
fixtures = None
|
||||
engines = None
|
||||
provision = None
|
||||
exclusions = None
|
||||
warnings = None
|
||||
assertions = None
|
||||
|
@ -111,8 +110,8 @@ def configure_follower(follower_ident):
|
|||
database creation.
|
||||
|
||||
"""
|
||||
global FOLLOWER_IDENT
|
||||
FOLLOWER_IDENT = follower_ident
|
||||
from alembic.testing import provision
|
||||
provision.FOLLOWER_IDENT = follower_ident
|
||||
|
||||
|
||||
def memoize_important_follower_config(dict_):
|
||||
|
@ -164,6 +163,7 @@ def set_coverage_flag(value):
|
|||
|
||||
def post_begin():
|
||||
"""things to set up later, once we know coverage is running."""
|
||||
|
||||
# Lazy setup of other options (post coverage)
|
||||
for fn in post_configure:
|
||||
fn(options, file_config)
|
||||
|
@ -245,7 +245,7 @@ def _monkeypatch_cdecimal(options, file_config):
|
|||
@post
|
||||
def _engine_uri(options, file_config):
|
||||
from alembic.testing import config
|
||||
from alembic.testing.plugin import provision
|
||||
from alembic.testing import provision
|
||||
|
||||
if options.dburi:
|
||||
db_urls = list(options.dburi)
|
||||
|
@ -268,7 +268,7 @@ def _engine_uri(options, file_config):
|
|||
|
||||
for db_url in db_urls:
|
||||
cfg = provision.setup_config(
|
||||
db_url, db_opts, options, file_config, FOLLOWER_IDENT)
|
||||
db_url, db_opts, options, file_config, provision.FOLLOWER_IDENT)
|
||||
|
||||
if not config._current:
|
||||
cfg.set_as_current(cfg)
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0.
|
||||
"""
|
||||
|
||||
try:
|
||||
# installed by bootstrap.py
|
||||
import alembic_plugin_base as plugin_base
|
||||
except ImportError:
|
||||
# assume we're a package, use traditional import
|
||||
from . import plugin_base
|
||||
|
||||
import sys
|
||||
|
||||
py3k = sys.version_info >= (3, 0)
|
||||
|
||||
import pytest
|
||||
import argparse
|
||||
import inspect
|
||||
from . import plugin_base
|
||||
import collections
|
||||
import itertools
|
||||
|
||||
|
@ -42,9 +53,11 @@ def pytest_configure(config):
|
|||
|
||||
plugin_base.pre_begin(config.option)
|
||||
|
||||
plugin_base.set_coverage_flag(bool(getattr(config.option,
|
||||
"cov_source", False)))
|
||||
coverage = bool(getattr(config.option, "cov_source", False))
|
||||
plugin_base.set_coverage_flag(coverage)
|
||||
|
||||
|
||||
def pytest_sessionstart(session):
|
||||
plugin_base.post_begin()
|
||||
|
||||
if has_xdist:
|
||||
|
@ -57,11 +70,11 @@ if has_xdist:
|
|||
plugin_base.memoize_important_follower_config(node.slaveinput)
|
||||
|
||||
node.slaveinput["follower_ident"] = "test_%s" % next(_follower_count)
|
||||
from . import provision
|
||||
from alembic.testing import provision
|
||||
provision.create_follower_db(node.slaveinput["follower_ident"])
|
||||
|
||||
def pytest_testnodedown(node, error):
|
||||
from . import provision
|
||||
from alembic.testing import provision
|
||||
provision.drop_follower_db(node.slaveinput["follower_ident"])
|
||||
|
||||
|
||||
|
@ -121,6 +134,7 @@ def pytest_pycollect_makeitem(collector, name, obj):
|
|||
|
||||
_current_class = None
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
# here we seem to get called only based on what we collected
|
||||
# in pytest_collection_modifyitems. So to do class-based stuff
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
|
||||
this should be removable when Alembic targets SQLAlchemy 0.9.4.
|
||||
this should be removable when Alembic targets SQLAlchemy 1.0.0
|
||||
"""
|
||||
from sqlalchemy.engine import url as sa_url
|
||||
from sqlalchemy import text
|
||||
|
@ -7,6 +7,8 @@ from alembic import compat
|
|||
from alembic.testing import config, engines
|
||||
from alembic.testing.compat import get_url_backend_name
|
||||
|
||||
FOLLOWER_IDENT = None
|
||||
|
||||
|
||||
class register(object):
|
||||
def __init__(self):
|
|
@ -29,9 +29,7 @@ plugin in a special (somewhat hacky) way so that coverage against
|
|||
SQLAlchemy itself is possible.
|
||||
|
||||
"""
|
||||
|
||||
from alembic.testing.plugin.noseplugin import NoseSQLAlchemy
|
||||
|
||||
from .plugin.noseplugin import NoseSQLAlchemy
|
||||
import nose
|
||||
|
||||
|
||||
|
|
18
run_tests.py
18
run_tests.py
|
@ -1,3 +1,17 @@
|
|||
from alembic.testing import runner
|
||||
import os
|
||||
# use bootstrapping so that test plugins are loaded
|
||||
# without touching the main library before coverage starts
|
||||
bootstrap_file = os.path.join(
|
||||
os.path.dirname(__file__), "alembic",
|
||||
"testing", "plugin", "bootstrap.py"
|
||||
)
|
||||
|
||||
runner.main()
|
||||
with open(bootstrap_file) as f:
|
||||
code = compile(f.read(), "bootstrap.py", 'exec')
|
||||
to_bootstrap = "nose"
|
||||
exec(code, globals(), locals())
|
||||
|
||||
|
||||
from noseplugin import NoseSQLAlchemy
|
||||
import nose
|
||||
nose.main(addplugins=[NoseSQLAlchemy()])
|
||||
|
|
|
@ -6,10 +6,17 @@ This script is an extension to py.test which
|
|||
installs SQLAlchemy's testing plugin into the local environment.
|
||||
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
|
||||
from os import path
|
||||
for pth in ['../lib']:
|
||||
sys.path.insert(0, path.join(path.dirname(path.abspath(__file__)), pth))
|
||||
# use bootstrapping so that test plugins are loaded
|
||||
# without touching the main library before coverage starts
|
||||
bootstrap_file = os.path.join(
|
||||
os.path.dirname(__file__), "..", "alembic",
|
||||
"testing", "plugin", "bootstrap.py"
|
||||
)
|
||||
|
||||
from alembic.testing.plugin.pytestplugin import *
|
||||
with open(bootstrap_file) as f:
|
||||
code = compile(f.read(), "bootstrap.py", 'exec')
|
||||
to_bootstrap = "pytest"
|
||||
exec(code, globals(), locals())
|
||||
from pytestplugin import * # noqa
|
||||
|
|
4
tox.ini
4
tox.ini
|
@ -32,10 +32,10 @@ recreate=True
|
|||
recreate=True
|
||||
|
||||
[testenv:coverage]
|
||||
# see also .coveragerc
|
||||
deps=coverage
|
||||
commands=
|
||||
python -m pytest --cov=alembic {posargs}
|
||||
python -m coverage xml --include=alembic/*
|
||||
python -m pytest --cov=alembic --cov-report term --cov-report xml {posargs}
|
||||
|
||||
[testenv:pep8]
|
||||
deps=flake8
|
||||
|
|
Loading…
Reference in New Issue