Testing the Resource¶
Concourse Tools contains a number of functions for easier testing.
You can take advantage of the class-based paradigm in Concourse Tools to test your resource class as a standard Python object. You can call the functions with specific inputs to check that they are turning the correct outputs. However, this does limit your ability to mock the script environment when your code relies on external factors.
Using Test Wrappers¶
Multiple test wrappers are available:
Test Class |
Input / Output |
Executed As |
|---|---|---|
Python |
Resource class |
|
JSON |
Main scripts |
|
Python |
Main scripts |
|
JSON |
External scripts |
|
Python |
External scripts |
|
JSON |
Docker container |
|
Python |
Docker container |
Base Wrapper¶
All of the above inherit from TestResourceWrapper:
- class concoursetools.testing.TestResourceWrapper(directory_dict=None, one_off_build=False, instance_vars=None, **env_vars)[source]¶
A simplistic resource wrapper designed to reduce test code.
The most accurate way to test your resource class is to invoke a test wrapper. Each one inherits from this class, and exposes a method for each of the three resource operations:
fetch_new_versions(),download_version()andpublish_new_version().Tip
Make use of the
capture_debugging()andcapture_directory_state()methods to capture the debugging output and directory state changes respectively.- Parameters:
directory_dict (
dict[str,Any] |None) – The initial state of the resource directory. SeeTemporaryDirectoryStateone_off_build (
bool) – Set toTrueif you are testing a one-off build.instance_vars (
dict[str,str] |None) – Pass optional instance vars to emulate an instanced pipeline.env_vars (
str) – Pass additional environment variables, or overload the default ones.
Caution
Each wrapper will use different signatures for these methods to reflect the different ways that inputs can be passed to the inner resource. Make sure to select the wrapper which works best for how you wish to test your resource.
- Example:
>>> from tests.resource import TestResource, TestVersion >>> resource = TestResource("git://some-uri") >>> wrapper = SimpleTestResourceWrapper(resource) >>> version = TestVersion("61cbef") >>> with wrapper.capture_debugging() as debugging: ... with wrapper.capture_directory_state() as directory_state: ... _, metadata = wrapper.download_version(version) ... assert directory_state.final_state == {"README.txt": "Downloaded README for ref 61cbef.\n"} ... assert metadata == {"team_name": "my-team"} ... assert debugging == "Downloading.\n"
- abstractmethod download_version()[source]¶
Download a version and place its files within the resource directory in your pipeline.
- Return type:
- abstractmethod publish_new_version()[source]¶
Update a resource by publishing a new version.
- Return type:
- capture_debugging()[source]¶
Redirect the resource debugging output within a context manager into a variable.
- Seealso:
This is done using an instance of
StringIOWrapper. A call is made toclear()when the context manager is opened.
Note
The output is directed regardless of whether this is used.
- Return type:
- capture_directory_state(starting_state=None)[source]¶
Open a context manager to expose the internal state of the resource.
- Parameters:
starting_state (
dict[str,Any] |None) – Set the starting state of the directory. If not set this defaults to the starting state as passed to the instance via thedirectory_dictparameter.- Seealso:
This is done using an instance of
TemporaryDirectoryState.- Return type:
Note
It is impossible to call the
fetch_new_versions()method from within this context manager.