{"id":2804,"library":"testing-common-database","title":"Testing Common Database","description":"testing.common.database is a Python utility library that provides a base class and helpers for testing packages that interact with databases. It offers functionalities like managing temporary database instances, caching initialized databases to speed up tests, and decorators to skip tests if database commands are not found. The current version is 2.0.3, released in 2017, suggesting a maintenance or stable release cadence rather than active development.","status":"maintenance","version":"2.0.3","language":"en","source_language":"en","source_url":"https://github.com/tk0miya/testing.common.database","tags":["testing","database","utilities","development"],"install":[{"cmd":"pip install testing-common-database","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"Base class for database testing packages, intended for inheritance.","symbol":"Database","correct":"from testing.common.database import Database"},{"note":"Factory class for creating and caching database instances to optimize test setup time.","symbol":"DatabaseFactory","correct":"from testing.common.database import DatabaseFactory"},{"note":"Decorator to conditionally skip test cases if a required database command is not found.","symbol":"SkipIfNotInstalledDecorator","correct":"from testing.common.database import SkipIfNotInstalledDecorator"},{"note":"Utility function to find an available TCP port.","symbol":"get_unused_port","correct":"from testing.common.database import get_unused_port"},{"note":"Utility function to search for a command in the system's PATH.","symbol":"get_path_of","correct":"from testing.common.database import get_path_of"}],"quickstart":{"code":"import os\nimport unittest\nfrom testing.common.database import Database, DatabaseFactory\n\nclass MyTestDatabase(Database):\n    # This is a minimal mock for demonstration; real implementation would\n    # manage a database server (e.g., PostgreSQL, MySQL).\n    def initialize(self):\n        # Simulate database initialization\n        print(f\"[{self.name}] Initializing database...\")\n\n    def get_data_directory(self):\n        # Return a temporary directory for data\n        return os.path.join(self.base_dir, 'data')\n\n    def get_server_commandline(self):\n        # No actual server command for this mock\n        return ['echo', 'Mock database server started']\n\n    def is_server_available(self):\n        # Always available for this mock\n        return True\n\n    def stop(self):\n        # Simulate stopping the database\n        print(f\"[{self.name}] Stopping database...\")\n\n# Create a factory for the mock database, with caching enabled\n# In a real scenario, this would be a specific database factory like PostgresqlFactory\nMyCachedDatabase = DatabaseFactory(target_class=MyTestDatabase, cache_initialized_db=True)\n\n# Ensure the cache is cleared after all tests in this module\ndef tearDownModule():\n    MyCachedDatabase.clear_cache()\n\nclass MyDatabaseTestCase(unittest.TestCase):\n    def setUp(self):\n        # Each test gets a fresh copy of the cached database\n        self.db = MyCachedDatabase()\n        print(f\"Setting up test with database instance at: {self.db.data_dir}\")\n\n    def tearDown(self):\n        self.db.stop()\n        print(f\"Tearing down test: {self.db.data_dir}\")\n\n    def test_database_interaction(self):\n        # Simulate interacting with the database\n        self.assertTrue(self.db.is_alive())\n        print(\"Performing test operations...\")\n        self.assertIn('data', self.db.data_dir)\n\nif __name__ == '__main__':\n    unittest.main()","lang":"python","description":"This quickstart demonstrates how to create a custom database testing class by inheriting from `testing.common.database.Database` and how to use `DatabaseFactory` to cache initialized database instances, speeding up subsequent tests. The `tearDownModule` ensures the cached database is properly cleaned up."},"warnings":[{"fix":"Thoroughly test compatibility with your specific Python version and dependencies. Consider maintaining a fork or seeking alternative, more actively maintained testing utilities if critical issues arise.","message":"The library has not seen a release since October 2017 (version 2.0.3) and officially supports Python 3.4, 3.5, and 3.6. Using it with newer Python versions (3.7+) may lead to compatibility issues or unaddressed bugs.","severity":"deprecated","affected_versions":"2.0.3 and older, especially with Python > 3.6"},{"fix":"Always subclass `testing.common.database.Database` and implement all necessary abstract methods to define how your specific database instance is managed during tests. Refer to derived libraries like `testing.postgresql` for implementation examples.","message":"The `Database` class is designed as an abstract base class. Directly instantiating `testing.common.database.Database` without inheriting and overriding essential methods (e.g., `initialize`, `get_data_directory`, `get_server_commandline`) will result in `NotImplementedError` or incorrect behavior, as it lacks concrete implementation for database interaction.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure `DatabaseFactory.clear_cache()` is reliably called at the appropriate scope (e.g., once after all tests in a module or suite) to reset the cached database and prevent test pollution. Also, ensure any `on_initialized` handler is idempotent or handles setup/teardown cleanly for cached instances.","message":"When using `DatabaseFactory(cache_initialized_db=True)`, the initialized database is cached and reused across tests. Failing to call `factory.clear_cache()` in a `tearDownModule` or similar cleanup hook can lead to stale test data or unexpected interactions between unrelated test cases, especially if `on_initialized` is not idempotently handled or test data is not reset.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}