From c312b3b2def89029c76a60ab84e3f58cb49a3a96 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 22 Oct 2019 18:40:41 -0400 Subject: [PATCH] Remove python setup.py test; fix SQL Server URL general README.unittest.rst edits Fixes: #4789 Fixes: #4900 Change-Id: Ifddd3bfd1e6a4d24d3b0a3e1702e04e66a42a4dd --- README.unittests.rst | 80 ++++++++++++++-------- doc/build/changelog/unreleased_14/4789.rst | 7 ++ setup.cfg | 2 +- setup.py | 42 +++--------- tox.ini | 3 +- 5 files changed, 71 insertions(+), 63 deletions(-) create mode 100644 doc/build/changelog/unreleased_14/4789.rst diff --git a/README.unittests.rst b/README.unittests.rst index c32837f780..e587a89eb5 100644 --- a/README.unittests.rst +++ b/README.unittests.rst @@ -2,35 +2,34 @@ SQLALCHEMY UNIT TESTS ===================== -Updated for 1.1, 1.2 - Basic Test Running ================== -A test target exists within the setup.py script. For basic test runs:: +Tox is used to run the test suite fully. For basic test runs against +a single Python interpreter:: - python setup.py test + tox -Running with Tox -================ +Advanced Tox Options +==================== For more elaborate CI-style test running, the tox script provided will run against various Python / database targets. For a basic run against Python 2.7 using an in-memory SQLite database:: - tox -e py27-sqlite + tox -e py38-sqlite The tox runner contains a series of target combinations that can run against various combinations of databases. The test suite can be run against SQLite with "backend" tests also running against a PostgreSQL database:: - tox -e py36-sqlite-postgresql + tox -e py38-sqlite-postgresql -Or to run just "backend" tests against a MySQL database:: +Or to run just "backend" tests against a MySQL databases:: - tox -e py36-mysql-backendonly + tox -e py38-mysql-backendonly Running against backends other than SQLite requires that a database of that vendor be available at a specific URL. See "Setting Up Databases" below @@ -39,12 +38,12 @@ for details. The py.test Engine ================== -Both the tox runner and the setup.py runner are using py.test to invoke -the test suite. Within the realm of py.test, SQLAlchemy itself is adding -a large series of option and customizations to the py.test runner using -plugin points, to allow for SQLAlchemy's multiple database support, -database setup/teardown and connectivity, multi process support, as well as -lots of skip / database selection rules. +The tox runner is using py.test to invoke the test suite. Within the realm of +py.test, SQLAlchemy itself is adding a large series of option and +customizations to the py.test runner using plugin points, to allow for +SQLAlchemy's multiple database support, database setup/teardown and +connectivity, multi process support, as well as lots of skip / database +selection rules. Running tests with py.test directly grants more immediate control over database options and test selection. @@ -66,11 +65,12 @@ Above will run the tests in the test/sql/test_query.py file (a pretty good file for basic "does this database work at all?" to start with) against a running PostgreSQL database at the given URL. -The py.test frontend can also run tests against multiple kinds of databases -at once - a large subset of tests are marked as "backend" tests, which will -be run against each available backend, and additionally lots of tests are targeted -at specific backends only, which only run if a matching backend is made available. -For example, to run the test suite against both PostgreSQL and MySQL at the same time:: +The py.test frontend can also run tests against multiple kinds of databases at +once - a large subset of tests are marked as "backend" tests, which will be run +against each available backend, and additionally lots of tests are targeted at +specific backends only, which only run if a matching backend is made available. +For example, to run the test suite against both PostgreSQL and MySQL at the +same time:: py.test -n4 --db postgresql --db mysql @@ -85,7 +85,7 @@ a pre-set URL. These can be seen using --dbs:: Available --db options (use --dburi to override) default sqlite:///:memory: firebird firebird://sysdba:masterkey@localhost//Users/classic/foo.fdb - mssql mssql+pyodbc://scott:tiger@ms_2008 + mssql mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+13+for+SQL+Server mssql_pymssql mssql+pymssql://scott:tiger@ms_2008 mysql mysql://scott:tiger@127.0.0.1:3306/test?charset=utf8 oracle oracle://scott:tiger@127.0.0.1:1521 @@ -97,6 +97,11 @@ a pre-set URL. These can be seen using --dbs:: sqlite sqlite:///:memory: sqlite_file sqlite:///querytest.db +Note that a pyodbc URL **must be against a hostname / database name +combination, not a DSN name** when using the multiprocessing option; this is +because the test suite needs to generate new URLs to refer to per-process +databases that are created on the fly. + What those mean is that if you have a database running that can be accessed by the above URL, you can run the test suite against it using ``--db ``. @@ -124,15 +129,30 @@ of the fixed one in setup.cfg. Database Configuration ====================== +Step one, the **database chosen for tests must be entirely empty**. A lot +of what SQLAlchemy tests is creating and dropping lots of tables +as well as running database introspection to see what is there. If there +are pre-existing tables or other objects in the target database already, +these will get in the way. A failed test run can also be followed by + a run that includes the "--dropfirst" option, which will try to drop +all existing tables in the target database. + +The above paragraph changes somewhat when the multiprocessing option +is used, in that separate databases will be created instead, however +in the case of Postgresql, the starting database is used as a template, +so the starting database must still be empty. + The test runner will by default create and drop tables within the default -database that's in the database URL, *unless* the multiprocessing option -is in use via the py.test "-n" flag, which invokes pytest-xdist. The -multiprocessing option is **enabled by default** for both the tox runner -and the setup.py frontend. When multiprocessing is used, the SQLAlchemy -testing framework will create a new database for each process, and then -tear it down after the test run is complete. So it will be necessary -for the database user to have access to CREATE DATABASE in order for this -to work. +database that's in the database URL, *unless* the multiprocessing option is in +use via the py.test "-n" flag, which invokes pytest-xdist. The +multiprocessing option is **enabled by default** when using the tox runner. +When multiprocessing is used, the SQLAlchemy testing framework will create a +new database for each process, and then tear it down after the test run is +complete. So it will be necessary for the database user to have access to +CREATE DATABASE in order for this to work. Additionally, as mentioned +earlier, the database URL must be formatted such that it can be rewritten on +the fly to refer to these other databases, which means for pyodbc it must refer +to a hostname/database name combination, not a DSN name. Several tests require alternate usernames or schemas to be present, which are used to test dotted-name access scenarios. On some databases such diff --git a/doc/build/changelog/unreleased_14/4789.rst b/doc/build/changelog/unreleased_14/4789.rst new file mode 100644 index 0000000000..0d7e1855ac --- /dev/null +++ b/doc/build/changelog/unreleased_14/4789.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: change, tests + :tickets: 4789 + + "python setup.py test" is no longer a test runner, as this is deprecated by + Pypa. Please use "tox" with no arguments for a basic test run. + diff --git a/setup.cfg b/setup.cfg index d711080e1b..0b83985245 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,7 +59,7 @@ postgresql_psycopg2cffi=postgresql+psycopg2cffi://scott:tiger@127.0.0.1:5432/tes mysql=mysql://scott:tiger@127.0.0.1:3306/test?charset=utf8mb4 pymysql=mysql+pymysql://scott:tiger@127.0.0.1:3306/test?charset=utf8mb4 -mssql=mssql+pyodbc://scott:tiger@ms_2008 +mssql=mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+13+for+SQL+Server mssql_pymssql=mssql+pymssql://scott:tiger@ms_2008 oracle=oracle://scott:tiger@127.0.0.1:1521 diff --git a/setup.py b/setup.py index e035145234..560d76fca2 100644 --- a/setup.py +++ b/setup.py @@ -81,37 +81,22 @@ class Distribution(_Distribution): return True -class PyTest(TestCommand): - # from http://pytest.org/latest/goodpractices.html\ - # #integrating-with-setuptools-python-setup-py-test-pytest-runner - # TODO: prefer pytest-runner package at some point, however it was - # not working at the time of this comment. - user_options = [("pytest-args=", "a", "Arguments to pass to py.test")] - - default_options = ["-n", "4", "-q", "--nomemory"] - - def initialize_options(self): - TestCommand.initialize_options(self) - self.pytest_args = "" - - def finalize_options(self): - TestCommand.finalize_options(self) - self.test_args = [] - self.test_suite = True +class UseTox(TestCommand): + RED = 31 + RESET_SEQ = "\033[0m" + BOLD_SEQ = "\033[1m" + COLOR_SEQ = "\033[1;%dm" def run_tests(self): - import shlex - - # import here, cause outside the eggs aren't loaded - import pytest - - errno = pytest.main( - self.default_options + shlex.split(self.pytest_args) + sys.stderr.write( + "%s%spython setup.py test is deprecated by pypa. Please invoke " + "'tox' with no arguments for a basic test run.\n%s" + % (self.COLOR_SEQ % self.RED, self.BOLD_SEQ, self.RESET_SEQ) ) - sys.exit(errno) + sys.exit(1) -cmdclass["test"] = PyTest +cmdclass["test"] = UseTox def status_msgs(*msgs): @@ -156,11 +141,6 @@ def run_setup(with_cext): package_dir={"": "lib"}, license="MIT", cmdclass=cmdclass, - tests_require=[ - "pytest>=2.5.2,!=3.9.1,!=3.9.2", - "mock", - "pytest-xdist", - ], long_description=readme, python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", classifiers=[ diff --git a/tox.ini b/tox.ini index 0855ac6c6c..532c720024 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] -envlist = py{27,34,35,36,37,38}-{cext,nocext} +envlist = py [testenv] # note that we have a .coveragerc file that points coverage specifically @@ -75,6 +75,7 @@ passenv=ORACLE_HOME NLS_LANG TOX_POSTGRESQL TOX_MYSQL TOX_ORACLE TOX_MSSQL TOX_S # for nocext, we rm *.so in lib in case we are doing usedevelop=True commands= + cext: /bin/true nocext: sh -c "rm -f lib/sqlalchemy/*.so" {env:BASECOMMAND} {env:WORKERS} {env:SQLITE:} {env:POSTGRESQL:} {env:MYSQL:} {env:ORACLE:} {env:MSSQL:} {env:BACKENDONLY:} {env:IDENTS:} {env:NOMEMORY:} {env:COVERAGE:} {posargs} oracle,oracle6,oracle5,mssql: python reap_dbs.py db_idents.txt -- 2.47.3