Services plugin for pytest testing framework
Services plugin for pytest testing framework
pip install pytest-services
The plugin provides a set of fixtures and utility functions to start service processes for your tests with pytest
- Determines whethere services should be run or not. False by default if not in distributed environment (without pytest-xdist). Can be manually set to True by overriding this fixture in your test config or just by using –run-services command line argument (see below).
- Test session id. Globally unique, and of course also guaranteed to be different for potentially multiple test sessions running on same test node via pytest-xdist.
- Function to instantiate test service watcher (popen object). Includes automatic finalization (exiting) of the service process, and testing the service before returning the watcher from the function. Example of usage for memcached service:
@pytest.fixture(scope='session') def memcached(request, run_services, memcached_socket, watcher_getter): """The memcached instance which is ready to be used by the tests.""" if run_services: return watcher_getter( name='memcached', arguments=['-s', memcached_socket], checker=lambda: os.path.exists(memcached_socket), # Needed for the correct execution order of finalizers request=request, )
- Logger used for debug logging when managing test services.
- Parent directory for test service artifacts (disk based). Set to /tmp by default.
- Base directory for test service artifacts (disk based), unique subdirectory of root_dir. Automatically removed recursively at the end of the test session.
- Temporary directory (disk based), subfolder of the base_dir. Used for strictly temporary artifacts (for example - folder where files are uploaded from the user input).
- Parent directory for test service artifacts (memory based). Main idea of having memory base directory is to store performance-critical files there. For example - mysql service will use it to store database file, it speeds up mysql server a lot, especially database management operations. Set to /var/shm by default, with a fallback to ‘root_dir`. Note that if apparmor is running on your system, most likely it will prevent your test service to use it (for example - mysql has it’s apparmor profile). You you’ll need to disable such profile in apparmor configuration. Example of disabling apparmor for mysqld:
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ sudo /etc/init.d/apparmor restart
- Base directory for test service artifacts (memory based), unique subdirectory of memory_root_dir. Automatically removed recursively at the end of the test session.
- Temporary directory (memory based), subfolder of the base_dir.
- Lock files directory for storing locks created for resource assignment (ports, display, etc). Subfolder of memory_root_dir.
- Process id and socket files directory (like system-wide /var/run but local for test session). Subfolder of memory_root_dir.
- Function to get unallocated port. Automatically ensures locking and un-locking of it on application level via flock.
- Function to get unallocated display. Automatically ensures locking and un-locking of it on application level via flock.
- Start memcached instance. Requires pylibmc installed or memcache indicated as an extra (pip install ‘pytest-services[memcached]’).
- Memcached unix socket file name to be used for connection.
- Memcached connection string.
- Determine if memcached should be cleared before every test run. Equals to run_services fixture by default. Requires pylibmc installed or memcache indicated as an extra (pip install ‘pytest-services[memcached]’).
- A pylibmc.Client instance bound to the service. Requires pylibmc installed or memcache indicated as an extra (pip install ‘pytest-services[memcached]’).
- Start mysql-server instance.
- MySQL database name to be created after initialization of the mysql service system database.
- Function with single parameter - database name. To create additional database(s) for tests. Used in mysql_database fixture which is used by mysql one.
- MySQL connection string.
- Start xvfb instance.
- Xvfb display to use for connection.
- Xvfb display resolution to use. Tuple in form (1366, 768, 8).
In some cases, there’s a need of switching django settings during test run, because several django projects are tested whithin the single test suite. pytest_services.django_settings simplifies switching of django settings to a single function call:
- Override the enviroment variable and call the _setup method of the settings object to reload them.
Example of usage:
from pytest_services import django_settings django_settings.clean_django_settings() django_settings.setup_django_settings('your.project.settings')
Note that the nice project pytest-django doesn’t help with the situation, as it’s single django project oriented, as well as standard django testing technique. Single project approach works fine, as long as there are no fixtures to share between them, but when there are fixtures to share, then you can get benefit of joining several django projects tests into a single test run, because all session-scoped fixtures will be instantiated only once for all projects tests. The benefit is only visible if you have big enough test suite and your fixtures are heavy enough.
- Force services to be run even if tests are executed in a non-distributed way (without pytest-xdist).
import MySQLdb def test_some_mysql_stuff(mysql): """Test using mysql server.""" conn = MySQLdb.connect(user='root')
If you have questions, bug reports, suggestions, etc. please create an issue on the GitHub project page.
- Add request param to watcher_getter to have proper execution order of finalizers (youtux).
- Swap kill and terminate in watcher_getter finalization, allowing for a more polite SIGTERM for terminating child procs on Unix. See #15 for details (jaraco)
- Make pylibmc an optional dependency, available as an extra (jaraco)
- Fixed hang with updated netcat-openbsd>=1.130.3 (joepvandijken)
- Use a different strategy to determine whether xvfb supports (youtux )
- use realpath for mysql base dir (bubenkoff)
- exclude locked displays for xvfb (bubenkoff)
- django settings fix (olegpidsadnyi)
- django 1.8 support (bubenkoff)
- old django support fix (olegpidsadnyi)
- django 1.7+ support (bubenkoff)
- removed auto artifacts cleanup (bubenkoff)
- fixed popen arguments (bubenkoff)
- added port and display getters (bubenkoff)
- Improved documentation (bubenkoff)
- Initial public release