<< All versions
Skill v1.0.2
currentAutomated scan100/100seldomqa/lounger/api
1 files
──Details
PublishedAugust 25, 2026 at 11:33 PM
Content Hashsha256:d90acbc72751b067...
Git SHA1da7ceb39b55
Bump Typepatch
──Files
Files (1 file, 7.4 KB)
SKILL.md7.4 KBactive
SKILL.md · 242 lines · 7.4 KB
version: "1.0.2"
Skill: Layered API Automation Design with the Lounger Framework
Core Philosophy
Test-Centric Design: Move away from script-style request calls and adopt object-oriented, layered test architecture.
- Single API: Use a semantic facade pattern to hide raw HTTP details.
- Multiple APIs: Use a service layer to orchestrate business flows and improve reuse.
- Goal: Improve readability and maintainability while reducing long-term case maintenance cost.
Architecture Layers
Use a classic three-layer structure to separate responsibilities:
| Layer | Name | Responsibility | Keywords | |
|---|---|---|---|---|
| L1 | Test Case | Describes "what to verify" and focuses on assertions plus business data | pytest, assert, BDD | |
| L2 | Service | Describes "how the flow works" and composes multiple APIs into one business scenario | Flow, Orchestration, Reuse | |
| L3 | Client | Describes "how to call the API" and wraps a single endpoint with semantic methods | HttpRequest, Facade, Semantic |
mermaid
graph TDA["Test Case"] -->|Calls| B["Service Layer"]B -->|Composes| C["API Client Layer"]C -->|Requests| D["Target API"]
Implementation Standards
3.1 L3: API Client Layer
Principle: One endpoint should map to one clearly named method, and the method name should express business intent.
Key rules:
- Inherit every API client from
lounger.request.HttpRequest. - Initialize shared settings such as
base_url, headers, and auth in__init__. - Add type hints to method parameters.
- Keep docstrings short and focused on business meaning.
Example:
python
from lounger.request import HttpRequestfrom lounger.request import apiclass EmailAPI(HttpRequest):"""Email API client."""def __init__(self, base_url: str, token: str):super().__init__(base_url=base_url)self.token = token@api(describe="Update an email campaign")def update_campaign(self, campaign_data: dict):"""Update an email campaign."""api_path = "/api/{service}/v1/{action}"headers = {"Authorization": f"Bearer {self.token}",}return self.post(api_path, json=campaign_data, headers=headers)@api(describe="Get contrast campaign details")def get_contrast_campaigns_detail(self, params: dict):"""Get details for contrast campaigns."""api_path = "/api/{service}/v1/{action_name}"headers = {"Authorization": f"Bearer {self.token}","Content-Type": "application/json",}return self.post(api_path, json=params, headers=headers)
Characteristics:
- Use the
@apidecorator to mark client methods. - Let method names carry the business meaning.
- Pass flexible request data with
dictto support both normal and negative scenarios. - Choose GET or POST based on the endpoint contract.
- Define request headers inside the method when the API needs custom headers.
3.2 L2: Business Service Layer
Principle: Encapsulate cross-endpoint business logic and hide intermediate steps from test cases.
Key rules:
- Inject dependent client instances through
__init__. - Keep flows as black boxes so the test only calls one business action.
- Pass dependent data between endpoints automatically, such as propagating a login token.
Recommended for:
- Multi-endpoint flows such as create user -> login -> place order
- Tests that need setup steps before the real verification
- Reusable and complex business scenarios
Note: If your project mainly tests single endpoints, you can add the service layer later when it becomes useful.
3.3 L1: Test Case Layer
Principle: Keep test files extremely small and focused on data plus assertions.
Key rules:
- Use fixtures in
conftest.pyto manage client and service initialization. - Standardize assertions with
lounger.request.expect. - Put complex data into JSON files and keep simple parameters inline.
Example:
python
import pytestfrom lounger.request import expectfrom lounger.utils.resource_loader import resource_file@pytest.fixture(scope="module")def payload():return resource_file("campaign_data.json")def test_update_campaign(email_api, payload):"""Verify campaign update."""response = email_api.update_campaign(payload)expect(response).to_have_path_value("msg", "success")
Project Structure
shell
project_root/├── config/├── api/│ ├── clients/│ │ ├── __init__.py│ │ └── posts_api.py│ └── services/│ └── __init__.py├── test_dir/│ ├── conftest.py│ ├── posts_case/│ │ ├── test_create_post.py│ │ └── test_get_post.py│ └── test_data/│ └── create_post_payload.json├── reports/├── conftest.py├── pytest.ini└── SKILL.md
Decision Matrix
| Scenario | Recommended Approach | Why | |
|---|---|---|---|
| Single-endpoint functional test | Call the API client directly | Simple and direct | |
| Multi-endpoint business flow | Use a service layer | Avoid duplicated flow logic | |
| Temporary exploration or debugging | Use raw requests or Lounger directly | Faster validation | |
| Third-party API integration | Wrap it with client + service | Isolate external changes | |
| Fewer than 5 input fields | Keep parameters inline in the test | Easier to read | |
| 5 or more input fields | Store data in JSON | Better separation of data and code |
Pitfalls To Avoid
Do not:
- Write raw
get()orpost()calls directly insidetest_*.pyfiles. - Hardcode endpoint URLs inside the service layer.
- Over-design one-off flows with no reuse value.
- Duplicate fixtures in each test file.
Best practices:
- Add new files and methods instead of rewriting existing code whenever possible.
- Use
dictpayloads for flexible positive and negative testing. - Keep test data separate from code when the payload becomes complex.
- Reuse shared fixtures from a central
conftest.py. - Register post-run notifications through support modules instead of writing summary logic directly in
conftest.py. - Keep docstrings short and meaningful.
Key Takeaways
Readability
posts_api.create_post(data)is clearer thanpost("/posts", ...).- Good method names turn tests into readable documentation.
Maintainability
- Endpoint changes belong in the client layer only.
- Flow changes belong in the service layer only.
- Test files can stay untouched.
Reusability
- A business flow can be reused across happy-path, negative, and performance scenarios.
- Shared fixtures reduce duplicate setup logic.
Engineering Quality
- The structure follows SRP and OCP.
- It scales better for medium and large automation projects.
- It works well with CI pipelines and automated delivery.
Example Workflow
- Define an API client in
api/clients/posts_api.py. - Register fixtures in
test_dir/conftest.py. - Write focused test cases under
test_dir/posts_case/. - Store reusable payloads in
test_dir/test_data/.
Run Tests
bash
# Run one filepytest test_dir/posts_case/test_get_post.py -v# Run the whole posts case folderpytest test_dir/posts_case/ -v# Run one test casepytest test_dir/posts_case/test_create_post.py::test_create_post -v# Generate a reportpytest test_dir/posts_case/ -v --html=reports/report.html
Version: v2.0 Updated: 2024-03-20