5
SQLAlchemy unit tests by default run using Python's built-in sqlite3
6
module. If running on Python 2.4, pysqlite must be installed.
8
Unit tests are run using nose. Nose is available at:
10
http://pypi.python.org/pypi/nose/
12
SQLAlchemy implements a nose plugin that must be present when tests are run.
13
This plugin is invoked when the test runner script provided with
16
**NOTE:** - the nose plugin is no longer installed by setuptools as of
17
version 0.7 ! Use "python setup.py test" or "./sqla_nose.py".
19
RUNNING TESTS VIA SETUP.PY
20
--------------------------
21
A plain vanilla run of all tests using sqlite can be run via setup.py:
23
$ python setup.py test
25
The -v flag also works here:
27
$ python setup.py test -v
35
If you're running the tests on Microsoft Windows, then there is an additional
36
argument that must be passed to ./sqla_nose.py:
38
> ./sqla_nose.py --first-package-wins
40
This is required because nose's importer will normally evict a package from
41
sys.modules if it sees a package with the same name in a different location.
42
Setting this argument disables that behavior.
44
Assuming all tests pass, this is a very unexciting output. To make it more
49
RUNNING INDIVIDUAL TESTS
50
-------------------------
51
Any directory of test modules can be run at once by specifying the directory
54
$ ./sqla_nose.py test/dialect
56
Any test module can be run directly by specifying its module name:
58
$ ./sqla_nose.py test.orm.test_mapper
60
To run a specific test within the module, specify it as module:ClassName.methodname:
62
$ ./sqla_nose.py test.orm.test_mapper:MapperTest.test_utils
67
Help is available via --help:
69
$ ./sqla_nose.py --help
71
The --help screen is a combination of common nose options and options which
72
the SQLAlchemy nose plugin adds. The most commonly SQLAlchemy-specific
73
options used are '--db' and '--dburi'.
79
Tests will target an in-memory SQLite database by default. To test against
80
another database, use the --dburi option with any standard SQLAlchemy URL:
82
--dburi=postgresql://user:password@localhost/test
84
Use an empty database and a database user with general DBA privileges.
85
The test suite will be creating and dropping many tables and other DDL, and
86
preexisting tables will interfere with the tests.
88
Several tests require alternate usernames or schemas to be present, which
89
are used to test dotted-name access scenarios. On some databases such
90
as Oracle or Sybase, these are usernames, and others such as Postgresql
91
and MySQL they are schemas. The requirement applies to all backends
92
except SQLite and Firebird. The names are:
95
test_schema_2 (only used on Postgresql)
97
Please refer to your vendor documentation for the proper syntax to create
98
these namespaces - the database user must have permission to create and drop
99
tables within these schemas. Its perfectly fine to run the test suite
100
without these namespaces present, it only means that a handful of tests which
101
expect them to be present will fail.
103
Additional steps specific to individual databases are as follows:
105
MYSQL: Default storage engine should be "MyISAM". Tests that require
106
"InnoDB" as the engine will specify this explicitly.
108
ORACLE: a user named "test_schema" is created.
110
The primary database user needs to be able to create and drop tables,
111
synonyms, and constraints within the "test_schema" user. For this
112
to work fully, including that the user has the "REFERENCES" role
113
in a remote schema for tables not yet defined (REFERENCES is per-table),
114
it is required that the test the user be present in the "DBA" role:
118
SYBASE: Similar to Oracle, "test_schema" is created as a user, and the
119
primary test user needs to have the "sa_role".
121
It's also recommended to turn on "trunc log on chkpt" and to use a
122
separate transaction log device - Sybase basically seizes up when
123
the transaction log is full otherwise.
125
A full series of setup assuming sa/master:
127
disk init name="translog", physname="/opt/sybase/data/translog.dat", size="10M"
128
create database sqlalchemy on default log on translog="10M"
129
sp_dboption sqlalchemy, "trunc log on chkpt", true
130
sp_addlogin scott, "tiger7"
131
sp_addlogin test_schema, "tiger7"
134
sp_adduser test_schema
136
sp_role "grant", sa_role, scott
138
Sybase will still freeze for up to a minute when the log becomes
139
full. To manually dump the log:
141
dump tran sqlalchemy with truncate_only
143
MSSQL: Tests that involve multiple connections require Snapshot Isolation
144
ability implemented on the test database in order to prevent deadlocks that
145
will occur with record locking isolation. This feature is only available
146
with MSSQL 2005 and greater. You must enable snapshot isolation at the
147
database level and set the default cursor isolation with two SQL commands:
149
ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
151
ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
153
MSSQL+zxJDBC: Trying to run the unit tests on Windows against SQL Server
154
requires using a test.cfg configuration file as the cmd.exe shell won't
155
properly pass the URL arguments into the nose test runner.
157
If you'll be running the tests frequently, database aliases can save a lot of
158
typing. The --dbs option lists the built-in aliases and their matching URLs:
160
$ ./sqla_nose.py --dbs
161
Available --db options (use --dburi to override)
162
mysql mysql://scott:tiger@127.0.0.1:3306/test
163
oracle oracle://scott:tiger@127.0.0.1:1521
164
postgresql postgresql://scott:tiger@127.0.0.1:5432/test
167
To run tests against an aliased database:
169
$ ./sqla_nose.py --db=postgresql
171
To customize the URLs with your own users or hostnames, make a simple .ini
172
file called `test.cfg` at the top level of the SQLAlchemy source distribution
173
or a `.satest.cfg` in your home directory:
176
postgresql=postgresql://myuser:mypass@localhost/mydb
178
Your custom entries will override the defaults and you'll see them reflected
179
in the output of --dbs.
183
SQLAlchemy logs its activity and debugging through Python's logging package.
184
Any log target can be directed to the console with command line options, such
187
$ ./sqla_nose.py test.orm.unitofwork --log-info=sqlalchemy.orm.mapper \
188
--log-debug=sqlalchemy.pool --log-info=sqlalchemy.engine
190
This would log mapper configuration, connection pool checkouts, and SQL
194
BUILT-IN COVERAGE REPORTING
195
------------------------------
196
Coverage is tracked using Nose's coverage plugin. See the nose
197
documentation for details. Basic usage is:
199
$ ./sqla_nose.py test.sql.test_query --with-coverage
201
BIG COVERAGE TIP !!! There is an issue where existing .pyc files may
202
store the incorrect filepaths, which will break the coverage system. If
203
coverage numbers are coming out as low/zero, try deleting all .pyc files.
207
You can use the SQLAlchemy test suite to test any new database dialect in
208
development. All possible database features will be exercised by default.
209
Test decorators are provided that can exclude unsupported tests for a
210
particular dialect. You'll see them all over the source, feel free to add
211
your dialect to them or apply new decorations to existing tests as required.
213
It's fine to start out with very broad exclusions, e.g. "2-phase commit is not
214
supported on this database" and later refine that as needed "2-phase commit is
215
not available until server version 8".
217
To be considered for inclusion in the SQLAlchemy distribution, a dialect must
218
be integrated with the standard test suite. Dialect-specific tests can be
219
placed in the 'dialects/' directory. Comprehensive testing of
220
database-specific column types and their proper reflection are a very good
223
When working through the tests, start with 'engine' and 'sql' tests. 'engine'
224
performs a wide range of transaction tests that might deadlock on a brand-new
225
dialect- try disabling those if you're having problems and revisit them later.
227
Once the 'sql' tests are passing, the 'orm' tests should pass as well, modulo
228
any adjustments needed for SQL features the ORM uses that might not be
229
available in your database. But if an 'orm' test requires changes to your
230
dialect or the SQLAlchemy core to pass, there's a test missing in 'sql'! Any
231
time you can spend boiling down the problem to it's essential sql roots and
232
adding a 'sql' test will be much appreciated.
234
The test suite is very effective at illuminating bugs and inconsistencies in
235
an underlying DB-API (or database!) implementation. Workarounds are almost
236
always possible. If you hit a wall, join us on the mailing list or, better,