Python automated test framework
Project description
vault88
vault88 is a Python automated test framework designed for structured hardware and software validation in CI/CD pipelines. Tests are written as Python classes, organised into stages, and results can be published through configurable reporters.
Architecture
| Component | Role |
|---|---|
Loader |
Discovers test classes from files or directories; supports tag-based include/exclude filtering |
Logger |
Centralised logging with rotating file handler and optional verbose (debug) output |
Runner |
Instantiates and executes a test class through its full lifecycle: selfCheck → setup → run → teardown |
Reporter |
Pluggable reporters loaded from the config file; built-in reporters include JUnit XML and log archive |
Test results are grouped into named stages within each test, and each result records an action, expected value, actual value, outcome, timestamp, and optional requirement references.
Installation
pip install vault88
Or with uv:
uv add vault88
Writing a test
Subclass Test and implement the four lifecycle methods:
from vault88 import Test
class MyTest(Test):
name = "My Test"
tags = ["smoke"]
def selfCheck(self) -> bool:
# Return False to skip the test entirely
return True
def setup(self) -> bool:
# Prepare resources; return False to abort
return True
def run(self) -> None:
self.newStage("Basic checks")
self.assertEqual("Verify result", expected=42, actual=compute())
def teardown(self) -> None:
pass
Available assertion helpers: assertEqual, assertNotEqual, assertTrue, assertFalse, assertGreaterThan, assertLessThan, assertGreaterThanOrEqual, assertLessThanOrEqual, assertIn, assertNotIn, assertIsNone, assertIsNotNone.
Running tests
vault88 <testpath> [options]
| Option | Description |
|---|---|
testpath |
Path to a test file or directory |
-t TAG [TAG ...] |
Only run tests that have at least one of these tags |
-nt TAG [TAG ...] |
Exclude tests that have any of these tags |
-r |
Recursively search directories for tests |
-l FILE |
Log file path (default: ./test_execution.log) |
-v |
Verbose / debug logging |
--env PATH_OR_URL |
Load an environment from a JSON file or HTTP(S) URL |
--junit |
Generate a testresults.xml JUnit report in the current directory |
Environments
An environment passes host addresses, service details, and credentials into tests at runtime so the same test class can run against different targets without code changes.
Environment file format
Environments are defined as JSON. The top-level hosts list is the main entry point; each host can carry services and credentials:
{
"name": "staging",
"hosts": [
{
"name": "app-server",
"address": "10.0.1.10",
"credential": {
"username": "deploy",
"key_path": "/home/ci/.ssh/id_rsa"
},
"services": [
{
"name": "api",
"port": 8080,
"url": "http://10.0.1.10:8080"
}
]
}
]
}
All fields other than name and address (on a host) are optional.
Loading an environment
Pass the file path or an HTTP(S) URL to --env:
# from a local file
vault88 tests/ --env ./staging.json
# from an API endpoint
vault88 tests/ --env https://inventory.example.com/envs/staging
The API loader expects the endpoint to return the same JSON structure.
Using the environment in a test
The loaded Environment object is available as self.environment. Walk the hosts list or look up a host by name:
from vault88 import Test
class DeploymentTest(Test):
name = "Deployment smoke test"
tags = ["smoke"]
def selfCheck(self) -> bool:
return self.environment is not None
def setup(self) -> bool:
return True
def run(self) -> None:
self.newStage("Connectivity")
host = next(h for h in self.environment.hosts if h.name == "app-server")
api = next(s for s in host.services if s.name == "api")
response = requests.get(f"{api.url}/health")
self.assertEqual("Health endpoint returns 200", expected=200, actual=response.status_code)
def teardown(self) -> None:
pass
| Attribute | Type | Description |
|---|---|---|
environment.name |
str |
Environment name from the JSON |
environment.hosts |
List[Host] |
All hosts in the environment |
host.name |
str |
Host label |
host.address |
str |
IP address or hostname |
host.credential |
Credential | None |
SSH or login credential for the host |
host.services |
List[Service] |
Services running on the host |
service.name |
str |
Service label |
service.port |
int | None |
Port number |
service.url |
str | None |
Full URL |
service.credential |
Credential | None |
Service-specific credential |
credential.username |
str |
Username |
credential.password |
str | None |
Password |
credential.key_path |
str | None |
Path to a private key file |
Configuration
Reporters are configured in /etc/vault88.conf (INI format). Each [REPORTER<n>] section loads one reporter:
[REPORTER1]
module = vault88.core.reporters.junit_reporter
class = JUnitReporter
enabled = true
suite_name = My Project Tests
[REPORTER2]
module = vault88.core.reporters.log_archive_reporter
class = LogArchiveReporter
enabled = true
output_dir = ./logs
License
MIT License
Copyright (c) 2025 Brad Murdoch
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vault88-0.3.0.tar.gz.
File metadata
- Download URL: vault88-0.3.0.tar.gz
- Upload date:
- Size: 34.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b43e243908ed33c2820b8b1058679ab2996058fc7167b2cee7d142eb84b765bc
|
|
| MD5 |
aa6b4c63ce7414506f88be96cd814efa
|
|
| BLAKE2b-256 |
0028df1d70a654de76aa8fb4bd2e158750bf067eddf3dcd876f53129ed414331
|
File details
Details for the file vault88-0.3.0-py3-none-any.whl.
File metadata
- Download URL: vault88-0.3.0-py3-none-any.whl
- Upload date:
- Size: 24.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e433364684128a77e428d68e33b5bb945de642ab56441de63732d7f63d82b24
|
|
| MD5 |
56ad49bcaaa14b34e2ea536eee321add
|
|
| BLAKE2b-256 |
c339ac2d62db228c9ca58724ffb67527a5cdc9fca8ef5ae88c039ef2c3c4f6c4
|