@@ -30,6 +30,17 @@ src/codesphere/
3030 └── pipeline/ # (Placeholder)
3131
3232tests/ # Test files mirroring src structure
33+ ├── conftest.py # Shared unit test fixtures
34+ ├── core/ # Core infrastructure tests
35+ ├── resources/ # Resource unit tests
36+ └── integration/ # Integration tests (real API)
37+ ├── conftest.py # Integration fixtures & workspace setup
38+ ├── test_domains.py
39+ ├── test_env_vars.py
40+ ├── test_metadata.py
41+ ├── test_teams.py
42+ └── test_workspaces.py
43+
3344examples/ # Usage examples organized by resource type
3445```
3546
@@ -67,7 +78,7 @@ _GET_OP = APIOperation(
6778
6879# Example resource method
6980async def get (self , resource_id : int ) -> ResourceModel:
70- return await self .get_op(data = resource_id)
81+ return await self .get_op(resource_id = resource_id)
7182```
7283
7384### Model Guidelines
@@ -91,26 +102,141 @@ class Workspace(WorkspaceBase, _APIOperationExecutor):
91102- Raise ` RuntimeError ` for SDK misuse (e.g., accessing resources without context manager)
92103- Use custom exceptions from ` exceptions.py ` for SDK-specific errors
93104
94- ### Testing
95-
96- - Use ` pytest.mark.asyncio ` for async tests
97- - Use ` @dataclass ` for test case definitions with parametrization
98- - Mock ` httpx.AsyncClient ` for HTTP request testing
99- - Test files should mirror the source structure in ` tests/ `
100-
101105### Code Style
102106
103107- Line length: 88 characters (Ruff/Black standard)
104108- Indentation: 4 spaces
105109- Quotes: Double quotes for strings
106110- Imports: Group stdlib, third-party, and local imports
107111
108- ### Development Commands
112+ ---
113+
114+ ## Testing Guidelines
115+
116+ When adding features or making changes, appropriate tests are ** required** . The SDK uses two types of tests:
117+
118+ ### Unit Tests
119+
120+ Located in ` tests/ ` (excluding ` tests/integration/ ` ). These mock HTTP responses and test SDK logic in isolation.
121+
122+ ** When to write unit tests:**
123+ - New Pydantic models or schemas
124+ - New API operations
125+ - Core handler or utility logic changes
126+
127+ ** Unit test patterns:**
128+
129+ ``` python
130+ import pytest
131+ from dataclasses import dataclass
132+ from unittest.mock import AsyncMock, MagicMock
133+
134+ # Use @dataclass for parameterized test cases
135+ @dataclass
136+ class WorkspaceTestCase :
137+ name: str
138+ workspace_id: int
139+ expected_name: str
140+
141+ @pytest.mark.asyncio
142+ @pytest.mark.parametrize (" case" , [
143+ WorkspaceTestCase(name = " basic" , workspace_id = 123 , expected_name = " test-ws" ),
144+ ])
145+ async def test_workspace_get (case : WorkspaceTestCase):
146+ """ Should fetch a workspace by ID."""
147+ mock_response = MagicMock()
148+ mock_response.json.return_value = {" id" : case.workspace_id, " name" : case.expected_name}
149+
150+ # Test implementation...
151+ ```
152+
153+ ### Integration Tests
154+
155+ Located in ` tests/integration/ ` . These run against the real Codesphere API.
156+
157+ ** When to write integration tests:**
158+ - New API endpoints (CRUD operations)
159+ - Changes to request/response serialization
160+ - Schema field changes (detect API contract changes early)
161+
162+ ** Integration test patterns:**
163+
164+ ``` python
165+ import pytest
166+ from codesphere import CodesphereSDK
167+
168+ pytestmark = [pytest.mark.integration, pytest.mark.asyncio]
169+
170+ class TestMyResourceIntegration :
171+ """ Integration tests for MyResource endpoints."""
172+
173+ async def test_list_resources (self , sdk_client : CodesphereSDK):
174+ """ Should retrieve a list of resources."""
175+ resources = await sdk_client.my_resource.list()
176+
177+ assert isinstance (resources, list )
178+
179+ async def test_create_and_delete (
180+ self ,
181+ sdk_client : CodesphereSDK,
182+ test_team_id : int ,
183+ ):
184+ """ Should create and delete a resource."""
185+ resource = await sdk_client.my_resource.create(name = " test" )
186+
187+ try :
188+ assert resource.name == " test"
189+ finally :
190+ # Always cleanup created resources
191+ await resource.delete()
192+ ```
193+
194+ ** Available integration test fixtures** (from ` tests/integration/conftest.py ` ):
195+
196+ | Fixture | Scope | Description |
197+ | ---------| -------| -------------|
198+ | ` sdk_client ` | function | Fresh SDK client for each test |
199+ | ` session_sdk_client ` | session | Shared SDK client for setup/teardown |
200+ | ` test_team_id ` | session | Team ID for testing |
201+ | ` test_workspace ` | session | Single pre-created workspace |
202+ | ` test_workspaces ` | session | List of 2 test workspaces |
203+ | ` integration_token ` | session | The API token (from ` CS_TOKEN ` ) |
204+
205+ ** Environment variables:**
206+
207+ | Variable | Required | Description |
208+ | ----------| ----------| -------------|
209+ | ` CS_TOKEN ` | Yes | Codesphere API token |
210+ | ` CS_TEST_TEAM_ID ` | No | Specific team ID (defaults to first team) |
211+ | ` CS_TEST_DC_ID ` | No | Datacenter ID (defaults to 1) |
212+
213+ ### Running Tests
214+
215+ ``` bash
216+ make test # Run unit tests only
217+ make test-unit # Run unit tests only (explicit)
218+ make test-integration # Run integration tests (requires CS_TOKEN)
219+ ```
220+
221+ ### Test Requirements Checklist
222+
223+ When submitting a PR, ensure:
224+
225+ - [ ] ** New endpoints** have integration tests covering all operations
226+ - [ ] ** New models** have unit tests for serialization/deserialization
227+ - [ ] ** Bug fixes** include a test that reproduces the issue
228+ - [ ] ** All tests pass** locally before pushing
229+
230+ ---
231+
232+ ## Development Commands
109233
110234``` bash
111- make install # Set up development environment
112- make lint # Run Ruff linter
113- make format # Format code with Ruff
114- make test # Run pytest
115- make commit # Guided commit with Commitizen
235+ make install # Set up development environment
236+ make lint # Run Ruff linter
237+ make format # Format code with Ruff
238+ make test # Run unit tests
239+ make test-unit # Run unit tests (excludes integration)
240+ make test-integration # Run integration tests
241+ make commit # Guided commit with Commitizen
116242```
0 commit comments