budtestlibrary 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- budtestlibrary/__init__.py +54 -0
- budtestlibrary/bloom_metadata.py +49 -0
- budtestlibrary/budtestcase.py +702 -0
- budtestlibrary/config.py +215 -0
- budtestlibrary/flash_event.py +264 -0
- budtestlibrary-1.0.0.dist-info/METADATA +279 -0
- budtestlibrary-1.0.0.dist-info/RECORD +10 -0
- budtestlibrary-1.0.0.dist-info/WHEEL +5 -0
- budtestlibrary-1.0.0.dist-info/licenses/LICENSE +669 -0
- budtestlibrary-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
budtestlibrary - Bud Test Automation Framework.
|
|
3
|
+
|
|
4
|
+
A comprehensive test framework providing:
|
|
5
|
+
- BudTestCase: Base class for test cases with lifecycle management, assertions, and logging
|
|
6
|
+
- BloomMetaData: Bloom PLM integration for test case traceability (*-TC-*)
|
|
7
|
+
- FlashEvent: Firmware flashing abstraction with success/failure handling
|
|
8
|
+
|
|
9
|
+
Backend: Bud TMP
|
|
10
|
+
PLM/PLM: Bloom PLM
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 EmbedLabs
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from importlib.metadata import version
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from budtestlibrary.bloom_metadata import BloomMetaData
|
|
19
|
+
from budtestlibrary.budtestcase import BudTestCase
|
|
20
|
+
from budtestlibrary.config import BudConfig, get_default_config
|
|
21
|
+
from budtestlibrary.flash_event import FlashEvent, FlashFailure, FlashSuccess
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _get_version():
|
|
25
|
+
"""Reads version from pyproject.toml."""
|
|
26
|
+
try:
|
|
27
|
+
return version("budtestlibrary")
|
|
28
|
+
except Exception:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
|
|
33
|
+
if pyproject_path.exists():
|
|
34
|
+
for line in pyproject_path.read_text().splitlines():
|
|
35
|
+
if line.startswith("version = "):
|
|
36
|
+
return line.split("=")[1].strip().strip('"')
|
|
37
|
+
except Exception:
|
|
38
|
+
pass
|
|
39
|
+
return "unknown"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
__version__ = _get_version()
|
|
43
|
+
__author__ = "EmbedLabs"
|
|
44
|
+
__email__ = "dev@embedlabs.net"
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
"BudTestCase",
|
|
48
|
+
"BloomMetaData",
|
|
49
|
+
"FlashEvent",
|
|
50
|
+
"FlashSuccess",
|
|
51
|
+
"FlashFailure",
|
|
52
|
+
"BudConfig",
|
|
53
|
+
"get_default_config",
|
|
54
|
+
]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BloomMetadata - Direct linkage to Bloom PLM Test Cases (*-TC-*).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Any, Optional
|
|
8
|
+
|
|
9
|
+
_TC_ID_SUFFIX_PATTERN = re.compile(r"^[a-zA-Z0-9_-]+$")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class BloomMetaData:
|
|
14
|
+
"""
|
|
15
|
+
Metadata linking a test class to a Test Case in Bloom PLM.
|
|
16
|
+
Standard Format: {Project}-TC-{ID}
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
project: str
|
|
20
|
+
tc_id_suffix: str
|
|
21
|
+
description: Optional[str] = None
|
|
22
|
+
|
|
23
|
+
def __post_init__(self):
|
|
24
|
+
if not self.project or not self.project.strip():
|
|
25
|
+
raise ValueError("BloomMetaData.project must be a non-empty string")
|
|
26
|
+
if not self.tc_id_suffix or not self.tc_id_suffix.strip():
|
|
27
|
+
raise ValueError("BloomMetaData.tc_id_suffix must be a non-empty string")
|
|
28
|
+
if not _TC_ID_SUFFIX_PATTERN.match(self.tc_id_suffix):
|
|
29
|
+
raise ValueError(
|
|
30
|
+
f"BloomMetaData.tc_id_suffix must match '{_TC_ID_SUFFIX_PATTERN.pattern}', "
|
|
31
|
+
f"got '{self.tc_id_suffix}'"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def get_full_tc_id(self) -> str:
|
|
35
|
+
"""Returns the full standard ID: *-TC-*"""
|
|
36
|
+
return f"{self.project}-TC-{self.tc_id_suffix}"
|
|
37
|
+
|
|
38
|
+
def get_url(self, base_url: str = "") -> str:
|
|
39
|
+
"""Get the direct URL to the test case."""
|
|
40
|
+
return f"{base_url.rstrip('/')}/projects/{self.project}/test-cases/{self.tc_id_suffix}"
|
|
41
|
+
|
|
42
|
+
def to_dict(self) -> dict[str, Any]:
|
|
43
|
+
return {
|
|
44
|
+
"project": self.project,
|
|
45
|
+
"tc_id": self.get_full_tc_id(),
|
|
46
|
+
"display_id": self.get_full_tc_id(),
|
|
47
|
+
"description": self.description,
|
|
48
|
+
"url": self.get_url(),
|
|
49
|
+
}
|