Universal Bud Test Automation Framework for Hardware-in-Loop, Software-in-the-Loop, Web-Apps, Mobile, Cloud, and End-to-End Testing. Created by EmbedLabs.
Project description
budtestlibrary
Universal test automation framework for HIL, SIL, Web, Mobile, Cloud, and E2E testing. It provides a comprehensive test framework with lifecycle management, rich assertions, logging, and Bloom PLM integration.
Installation
pip install budtestlibrary
Quick Start
import logging
from budtestlibrary import BudTestCase, BloomMetaData
class MyTest(BudTestCase):
bloom_metadata = BloomMetaData("PRJ", "001")
def setUpClass(self):
self.log_info("Setting up test...")
def bud_check_response(self):
response = get_response()
self.assertTrue(response.ok, msg="Response is successful")
def bud_validate_output(self):
result = compute_result()
self.assertInTolerance(
result,
expected=42.0,
absolute_tolerance=0.5,
msg="Output within expected range",
)
def tearDownClass(self):
self.log_info("Tearing down test...")
if __name__ == "__main__":
test = MyTest()
test.set_loglevel(logging.INFO)
test.run()
Configuration
Configure via environment variables or app.properties:
Environment Variables
export BUD_BACKEND_URL="https://<your-bud-instance-url>/"
export BUD_TOKEN="your-api-token"
app.properties
budBackend=https://<your-bud-instance-url>/
budRunnerAccount=my-runner
Examples
The examples/ directory includes runnable starting points for common use cases:
| File | Scenario |
|---|---|
minimal_test.py |
Smallest possible BudTestCase with core assertions |
bloom_metadata_test.py |
Bloom PLM traceability metadata on test results |
flash_event_example.py |
Firmware flashing with FlashEvent, FlashSuccess, and FlashFailure |
hil_test.py |
Hardware-in-the-loop checks against a target board |
sil_test.py |
Software-in-the-loop logic validation |
api_testing_example.py |
Service/API assertions with response payload checks |
ui_testing_example.py |
UI-style assertions for page state and user feedback |
cloud_e2e_example.py |
Cloud / end-to-end test flow with latency checks |
Assertions
assertTrue / assertFalse
self.assertTrue(condition, msg="Description", abort_on_fail=False)
self.assertFalse(condition, msg="Description")
assertEqual / assertNotEqual
self.assertEqual(actual, expected, msg="Description")
self.assertNotEqual(actual, expected, msg="Description")
assertGreater / assertLess
self.assertGreater(actual, expected, msg="Description")
self.assertLess(actual, expected, msg="Description")
assertIn / assertNotIn
self.assertIn(member=2, container=[1, 2, 3], msg="Description")
self.assertNotIn(member=99, container=[1, 2, 3], msg="Description")
assertRegex
self.assertRegex(text="hello world", pattern=r"hello", msg="Description")
assertInTolerance
self.assertInTolerance(
actual,
expected,
absolute_tolerance=0.1, # ±0.1
relative_tolerance=0.05, # ±5%
msg="Description",
)
assertInRange
self.assertInRange(
actual,
lower_bound=0.0,
upper_bound=10.0,
include_bounds=True,
msg="Description",
)
# upper_bound is optional — checks >= lower_bound when omitted
self.assertInRange(
actual,
lower_bound=5.0,
msg="Description",
)
Result capture options
Subclass attributes on BudTestCase control what is stored in assertion and method results (and serialized via to_dict()):
| Attribute | Default | Description |
|---|---|---|
CAPTURE_SOURCE_PATH |
True |
When True, failed assertions record source_file, source_line, and source_function from the call site. Set to False to omit source location (smaller payloads, less introspection overhead). |
CAPTURE_TRACEBACK |
True |
When True, tracebacks are attached to failed assertions and method results where applicable. Set to False to omit traceback strings from stored results. |
MAX_RESULT_VALUE_LENGTH |
5000 |
Maximum character length for expected, actual, and result strings in TestResult.to_dict(). Longer values are truncated with "... <truncated>". |
class CompactResultsTest(BudTestCase):
CAPTURE_SOURCE_PATH = False
CAPTURE_TRACEBACK = False
MAX_RESULT_VALUE_LENGTH = 500
def bud_check(self):
self.assertTrue(True, msg="minimal result payload")
Default shared configuration (backend URLs, tokens) is available via get_default_config() from budtestlibrary or budtestlibrary.config — it is created on first use, not at import time.
Result and Flash Abstractions
TestMethodResult
The result objects include detailed failure and summary messages:
error_message: Richly formatted with the exact assertion line when failed.summary_message: Concisely summarizes the execution (e.g., "Passed: N assertion(s) in M.NNs" or mirrorserror_messageon failure).
FlashFailure
Firmware flash results use a unified interface. FlashFailure defaults to a message key (matching FlashSuccess), while preserving a read-only error_message for backward compatibility. Its to_dict() keys include message, error_message, error_code, and recoverable.
FlashEvent
Flash events accept a firmware_path parameter in both flash() and execute() methods:
class MyFlashEvent(FlashEvent):
def flash(self, firmware_path):
...
return FlashSuccess()
event = MyFlashEvent()
result = event.execute("/path/to/firmware.hex")
Result Schema
budtestlibrary produces two primary result shapes:
TestResult
One assertion-level record. Serialized keys include:
passedmessageskippedassertion_typeexpectedactualresultsource_filesource_linesource_functioncode_contexttracebacktimestampmetadata
TestMethodResult
One bud_* method-level record. Serialized keys include:
method_namepassedskippedassertionsduration_secondserror_messagesummary_messagetracebackmetadata
In a typical integration, bud_runner flattens these method-level results into
the payload it uploads to Bud TMP while preserving assertion detail.
Compatibility
budtestlibrary |
Intended bud_runner pairing |
Notes |
|---|---|---|
0.3.x |
0.4.7+ |
Supports configurable traceback/source capture, result truncation, FlashEvent, and separate test_software vs software_under_test metadata in the runner flow |
Related Packages
- bud_runner: CLI tool for test execution and CI/CD integration
- pybudgui: PyQt6 desktop application for manual testing and result visualization
License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the LICENSE file for the full text.
Copyright (C) 2026 EmbedLabs.
For commercial licensing options that do not require AGPL compliance, contact dev@embedlabs.net. For support or private-source collaboration, email dev@embedlabs.net.
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 budtestlibrary-1.0.0.tar.gz.
File metadata
- Download URL: budtestlibrary-1.0.0.tar.gz
- Upload date:
- Size: 38.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0726a3c00df05d6c5668774baa4f1923cd7015559dbad7dff7091172cd19664a
|
|
| MD5 |
d4503a830d4b12a3483754cd8badf340
|
|
| BLAKE2b-256 |
fca7a7db2451ebce7e190e0793d7c95d491bae6001ff8f260eebbc1d72077c28
|
Provenance
The following attestation bundles were made for budtestlibrary-1.0.0.tar.gz:
Publisher:
ci-cd.yml on MbedLabs/bud-test-library
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
budtestlibrary-1.0.0.tar.gz -
Subject digest:
0726a3c00df05d6c5668774baa4f1923cd7015559dbad7dff7091172cd19664a - Sigstore transparency entry: 1996903736
- Sigstore integration time:
-
Permalink:
MbedLabs/bud-test-library@3760efb9dc037a3f94785a2b75e1fc442f6efa15 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/MbedLabs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci-cd.yml@3760efb9dc037a3f94785a2b75e1fc442f6efa15 -
Trigger Event:
push
-
Statement type:
File details
Details for the file budtestlibrary-1.0.0-py3-none-any.whl.
File metadata
- Download URL: budtestlibrary-1.0.0-py3-none-any.whl
- Upload date:
- Size: 28.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c8d710d9c9f5d9786ba3476b447f85a7c23f20ded99f557008322b980d1bfee
|
|
| MD5 |
5a184666ced6b99e72efaa8d17968c97
|
|
| BLAKE2b-256 |
725c907b7c991fdab2522316206e4e8bddb7561adcc5bf53d5bd5643719261bf
|
Provenance
The following attestation bundles were made for budtestlibrary-1.0.0-py3-none-any.whl:
Publisher:
ci-cd.yml on MbedLabs/bud-test-library
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
budtestlibrary-1.0.0-py3-none-any.whl -
Subject digest:
6c8d710d9c9f5d9786ba3476b447f85a7c23f20ded99f557008322b980d1bfee - Sigstore transparency entry: 1996903855
- Sigstore integration time:
-
Permalink:
MbedLabs/bud-test-library@3760efb9dc037a3f94785a2b75e1fc442f6efa15 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/MbedLabs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci-cd.yml@3760efb9dc037a3f94785a2b75e1fc442f6efa15 -
Trigger Event:
push
-
Statement type: