The SharedResource class is a mechanism used to document the dependencies for a given test in your test code. By creating a new Resource and decorating the classes or functions that require it with its decorator you are declaring both to the test runner and to other programmers what the test's otherwise implicit dependencies are. In particular, this allows the test runner to run tests in multiple threads without running two tests that depend on the same resource at the same time. For example, we might have a class that tests the permissions of different users. We could also have a class that tests the creation of some object. Both classes make use of the "administrator" user, and the "administrator" cannot be logged in in more than one session. Using ResourceGroups we would declare this dependency in the code like so:
from egautotest.shared_resource import SharedResource from egautotest.testset import UnorderedTestSet from egautotest.testset import SequentialTestSet # First we create our AdminUserResource, a subclass of SharedResource. class AdminUserResource(SharedResource): pass # This class tests the permissions for a certain web application. class PermissionsTests(UnorderedTestSet): def testManagerCanCreateUsers(self): assert(True) def testManagerCannotDeleteUsers(self): assert(True) # This method uses the Administrator User, who cannot be logged in in more than # one session. It is decorated with the AdminUserResource decorator to signify # this. @AdminUserResource.decorator def testAdminCanCreateUsers(self): assert(True) # This method also uses the Administrator User. Since it is also decorated with # the AdminUserResource, the TestRunner knows not to run this method at the same # time as any other tests with the AdminUserResource. @AdminUserResource.decorator def testAdminCanDeleteUsers(self): assert(True) # This class tests the process of creating an object Foo. class TestFooCreation(SequentialTestSet): def testOpenFooPage(self): assert(True) def testClickCreateFooButton(self): assert(True) def testFooWasCreated(self): assert(True) # The testFooAuditLog test uses the Administrator username again, so it is # decorated with the AdminUserResource decorator. It will not run at the same # time as the other methods with the AdminUserResource decorator. @AdminUserResource.decorator def testFooAuditLog(self): assert(True)
If we ask the test runner to run these files in multiple threads, it now knows not to run any of the methods with the AdminUserResource decorator at the same time. ResourceGroup decorators are applied to functions in this example, but the decorators can also be applied to whole classes. Applying a ResourceGroup decorator to a class is the same thing as decorating every function in that class. ResourceGroups work across classes and modules.