Successfully implemented comprehensive test suite for utils/character_storage.py with 100% code coverage and 28 passing tests.
- File:
tests/utils/test_character_storage.py - Lines: 579 lines of test code
- Coverage: 100% (49/49 statements covered)
Tests for save_character(name, char_data, selected_fields) function:
- ✅
test_save_character_new_character- Creating new character with all fields - ✅
test_save_character_update_existing- Updating existing character, preserving unmodified fields - ✅
test_save_character_partial_fields- Saving only specific fields (e.g., dice only) - ✅
test_save_character_empty_fields_list- Handling empty fields list - ✅
test_save_character_database_error- Error handling for DB failures - ✅
test_save_character_missing_fields_in_data- Graceful handling of missing fields in input
Verifies:
- Correct JSON structure in database
- SQL INSERT/UPDATE queries
- Field selection logic
- Error logging with ❌ emoji
- Return value (True/False)
Tests for get_character(name) function:
- ✅
test_get_character_exists- Retrieving existing character - ✅
test_get_character_not_found- Handling non-existent character (returns None) - ✅
test_get_character_invalid_json- Handling corrupted JSON data - ✅
test_get_character_database_error- Error handling for DB failures - ✅
test_get_character_empty_string_name- Handling empty name parameter
Verifies:
- Correct SQL SELECT query
- JSON parsing and deserialization
- Error handling and logging
- Return value (dict or None)
Tests for delete_character(name) function:
- ✅
test_delete_character_success- Successful deletion (DELETE 1) - ✅
test_delete_character_not_found- Handling non-existent character (DELETE 0) - ✅
test_delete_character_database_error- Error handling for DB failures - ✅
test_delete_character_empty_name- Handling empty name parameter
Verifies:
- Correct SQL DELETE query
- "DELETE 0" vs "DELETE 1" result handling
- Error logging with ❌ emoji
- Success logging with 🗑️ emoji
- Return value (True/False)
Tests for get_all_names() function:
- ✅
test_get_all_names_multiple- Retrieving multiple character names - ✅
test_get_all_names_empty- Handling empty database - ✅
test_get_all_names_single- Retrieving single character - ✅
test_get_all_names_database_error- Error handling for DB failures - ✅
test_get_all_names_ordered- Verifying ORDER BY name clause
Verifies:
- Correct SQL SELECT query with ORDER BY
- Row extraction and name list building
- Error handling (returns empty list on error)
- Return value (list of strings)
Integration tests for complete workflows:
- ✅
test_save_and_retrieve_workflow- Save then retrieve character - ✅
test_save_update_delete_workflow- Complete CRUD workflow - ✅
test_list_and_retrieve_multiple- List and retrieve multiple characters
Verifies:
- End-to-end functionality
- State consistency across operations
- Multiple function interactions
Edge cases and boundary conditions:
- ✅
test_character_name_with_special_characters- Names with quotes, parentheses - ✅
test_character_with_unicode_name- Japanese/Unicode character names - ✅
test_character_with_very_long_name- 1000+ character names - ✅
test_character_with_large_data- Large data structures (100+ dice) - ✅
test_get_character_with_null_values- Handling null/None values in data
Verifies:
- Robustness with unusual inputs
- Unicode and special character handling
- Large data handling
- Null value preservation
@pytest.fixture
def mock_database():
"""Mock Database class"""
with patch('utils.character_storage.Database') as mock_db:
yield mock_dbMocked Methods:
Database.execute()- AsyncMock for INSERT/UPDATE/DELETEDatabase.fetchval()- AsyncMock for SELECT single valueDatabase.fetch()- AsyncMock for SELECT multiple rows
Return Value Examples:
execute(): "INSERT 1", "UPDATE 1", "DELETE 0", "DELETE 1"fetchval(): JSON string or Nonefetch(): List of dict rows
@pytest.fixture
def mock_log_message():
"""Mock log_message function"""
with patch('utils.character_storage.log_message') as mock_log:
yield mock_logVerified:
- Called with correct emoji (💾, ❌, 🗑️)
- Called with appropriate messages
- Not called when not expected
@pytest.fixture
def sample_char_data():
"""Sample character data from initiative entry"""
return {
"hp": 100,
"elements": ["fire", "water"],
"atk": 15,
"def_": 10,
"favorite_dice": {"initiative": "1d20+5", "attack": "2d6+3"},
"last_formula": "1d20+5"
}
@pytest.fixture
def sample_stored_data():
"""Sample data as stored in database"""
return {
"stats": {"hp": 100, "elements": ["fire", "water"], "atk": 15, "def_": 10},
"favorite_dice": {"initiative": "1d20+5", "attack": "2d6+3"},
"initiative_formula": "1d20+5"
}Name Stmts Miss Cover
-----------------------------------------------------
utils/character_storage.py 49 0 100%
tests/utils/test_character_storage.py 264 0 100%
All 49 statements in character_storage.py are covered:
- Line 22-26:
get_character()call and default initialization - Line 28-43: Field selection and update logic
- Line 46-56: INSERT/UPDATE query execution and error handling
- Line 60-68:
get_character()function - Line 72-78:
get_all_names()function - Line 82-92:
delete_character()function
============================= 28 passed in 0.92s ==============================
All tests pass with:
- ✅ 28/28 tests passing
- ✅ 100% code coverage
- ✅ No warnings or errors
- ✅ Execution time: ~0.9 seconds
@pytest.mark.asyncio
async def test_save_character_new_character(self, mock_database, ...):
result = await save_character("Aragorn", sample_char_data, ["stats", "dice", "formula"])# Verify function was called
mock_database.execute.assert_called_once()
# Verify call arguments
call_args = mock_database.execute.call_args
assert "INSERT INTO characters" in call_args[0][0]
assert call_args[0][1] == "Aragorn"
# Verify JSON data structure
saved_data = json.loads(call_args[0][2])
assert saved_data["stats"]["hp"] == 100# Test exception handling
mock_database.execute = AsyncMock(side_effect=Exception("DB connection failed"))
result = await save_character("Aragorn", sample_char_data, ["stats"])
assert result is False
mock_log_message.assert_called()
assert "❌" in mock_log_message.call_args[0][0]Test Dependencies:
pytest- Test frameworkpytest-asyncio- Async test supportpytest-cov- Coverage reportingunittest.mock- Mocking utilities
Module Dependencies:
utils.character_storage- Module under testutils.db.Database- Mockedutils.music.log_message- Mocked
- ✅ Test file created:
tests/utils/test_character_storage.py - ✅ All 4 functions tested:
- ✅
save_character()- 6 tests - ✅
get_character()- 5 tests - ✅
delete_character()- 4 tests - ✅
get_all_names()- 5 tests
- ✅
- ✅ Database mocking implemented
- ✅ Log message mocking implemented
- ✅ Error handling tested
- ✅ Edge cases covered
- ✅ Integration workflows tested
- ✅ 100% code coverage achieved
- ✅ All 28 tests passing
- ✅ No linting errors
Tas