{"id":7783,"library":"testresources","title":"Testresources: Unittest Extension for Resource Management","description":"Testresources extends Python's `unittest` module with a clean and simple API to optimize tests by managing expensive, common resources. This includes scenarios like setting up sample working directories for version control systems, establishing reference databases, or spinning up web servers. The library is currently at version 2.0.2, with its latest release in April 2025, indicating active maintenance.","status":"active","version":"2.0.2","language":"en","source_language":"en","source_url":"https://github.com/testing-cabal/testresources","tags":["testing","unit-testing","unittest","fixtures","resource-management","test-optimization"],"install":[{"cmd":"pip install testresources","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for package metadata and setup utilities.","package":"pbr","optional":false}],"imports":[{"note":"Base class for test cases that declare and use shared resources.","symbol":"ResourcedTestCase","correct":"from testresources import ResourcedTestCase"},{"note":"Base class for defining custom resource managers (factories for resources).","symbol":"TestResourceManager","correct":"from testresources import TestResourceManager"},{"note":"A TestSuite that orders tests to minimize resource setup/teardown operations.","symbol":"OptimisingTestSuite","correct":"from testresources import OptimisingTestSuite"},{"note":"A simple base class for resource objects that need explicit make() and clean() methods.","symbol":"TestResource","correct":"from testresources import TestResource"}],"quickstart":{"code":"import unittest\nfrom testresources import TestResource, ResourcedTestCase, OptimisingTestSuite\n\n# 1. Define your expensive resource and how to set it up/tear it down\nclass DatabaseResource(TestResource):\n    def make(self):\n        print(\"\\n--- Creating database connection ---\")\n        # Simulate a database connection object\n        self.connection = {'host': 'localhost', 'port': 5432, 'db': 'test'}\n        return self.connection\n\n    def clean(self, connection):\n        print(\"--- Closing database connection ---\")\n        self.connection = None\n\n    # Optional: Implement isDirty if the resource can become dirty and needs resetting\n    # def isDirty(self, connection):\n    #     return False # Assume it's always clean for this example\n\n# Create a singleton instance of the resource manager\ndb_resource_manager = DatabaseResource()\n\n# 2. Define your test case, inheriting from ResourcedTestCase\nclass MyDatabaseTest(ResourcedTestCase):\n    # Declare the resources needed by tests in this class\n    # The resource will be assigned to self.db_conn\n    resources = [('db_conn', db_resource_manager)]\n\n    def test_query_data(self):\n        print(f\"Test 1: Querying data with {self.db_conn}\")\n        self.assertIn('host', self.db_conn)\n\n    def test_insert_data(self):\n        print(f\"Test 2: Inserting data with {self.db_conn}\")\n        # Simulate modifying the resource, then mark it dirty if necessary\n        # db_resource_manager.dirtied(self.db_conn) # Uncomment if isDirty is implemented\n        self.assertEqual(self.db_conn['db'], 'test')\n\n    def test_another_query(self):\n        print(f\"Test 3: Another query with {self.db_conn}\")\n        self.assertTrue(self.db_conn['port'] == 5432)\n\n# 3. Use OptimisingTestSuite to run your tests efficiently\nif __name__ == '__main__':\n    suite = unittest.TestSuite()\n    suite.addTest(unittest.makeSuite(MyDatabaseTest))\n\n    # Wrap the suite in OptimisingTestSuite\n    optimised_suite = OptimisingTestSuite(suite)\n\n    # Run the tests\n    runner = unittest.TextTestRunner(verbosity=2)\n    runner.run(optimised_suite)","lang":"python","description":"This quickstart demonstrates how to define a shared resource (a simulated database connection) using `TestResource`, declare its usage within a `ResourcedTestCase`, and then execute tests efficiently with `OptimisingTestSuite` to minimize setup and teardown overhead."},"warnings":[{"fix":"Migrate class/module-level resource setup to `testresources.TestResourceManager` implementations and declare them via the `resources` attribute of `ResourcedTestCase`.","message":"When using `OptimisingTestSuite`, `unittest.TestCase.setUpClass` and `unittest.TestCase.setUpModule` are bypassed. The suite is flattened for resource optimization, meaning these class/module-level setup methods will not run.","severity":"breaking","affected_versions":"All versions when `OptimisingTestSuite` is used."},{"fix":"Always ensure your `TestResourceManager.make()` method returns a valid, non-`None` resource object upon successful creation, or raises an appropriate exception if resource creation genuinely fails.","message":"If a `TestResourceManager.make()` method successfully completes but returns `None`, `testresources` does not consider this an error. This can lead to `AttributeError` in tests attempting to use the `None` resource.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Declare all necessary resources statically as class attributes of your `ResourcedTestCase` via the `resources` tuple. If a test needs sub-elements, let a statically declared resource provide methods to generate them.","message":"Dynamically requesting resources inside a test method is generally discouraged. `testresources` is designed for statically declared resources to allow for optimal test ordering and resource reuse.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Review your `TestResourceManager` implementation. Ensure its `make()` method always returns a valid, non-`None` object representing the resource, or explicitly raises an exception if the resource cannot be created.","cause":"A custom `TestResourceManager`'s `make()` method (or `getResource()` in older terms) returned `None`, which `testresources` doesn't inherently flag as an error, leading to tests trying to use a `None` object.","error":"AttributeError: 'NoneType' object has no attribute 'some_method'"},{"fix":"Refactor your class or module-level setup logic to be handled by a `testresources.TestResourceManager`. Define your resource manager, then declare it in your `ResourcedTestCase`'s `resources` attribute to leverage `testresources`'s optimized lifecycle management.","cause":"You are using `OptimisingTestSuite` to run your tests, which flattens test suites and bypasses the `setUpClass` and `setUpModule` hooks from standard `unittest` classes.","error":"MyClass.setUpClass was never called / MyModule.setUpModule was never called"},{"fix":"If your resource can be reused without full recreation, implement `isDirty(self, resource)` in your `TestResourceManager` to return `False` if the resource is in a reusable state. If tests modify the resource and it needs to be reset, call `self.resource_manager.dirtied(self.resource)` within the test method to signal a state change.","cause":"The `testresources` framework re-creates or resets resources if it determines they are 'dirty'. This often happens if `TestResourceManager.isDirty()` is not correctly implemented or if `resource.dirtied()` is not called after a test modifies a shared resource.","error":"Resource is re-created for every test despite using OptimisingTestSuite."}]}