This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a comprehensive test suite for pCloud's sync functionality. It tests file synchronization between local drives and pCloud's cloud storage using real pCloud Drive instances. Tests verify data integrity using SHA1 checksums.
The test suite supports two testing modes:
- Drive Mode: Tests with mounted virtual drive
- Sync Folder Mode: Tests with both a mounted virtual drive and a regular folder synced via pCloud app
fstests/
├── tests/ # Test suite
│ ├── conftest.py # Shared pytest fixtures
│ ├── drive/ # Virtual Drive mode tests
│ │ └── conftest.py # Drive-specific fixtures (VirtualDriveHelper)
│ ├── sync/ # Sync Folder mode tests
│ │ └── conftest.py # Sync-specific fixtures (SyncFolderHelper)
├── utils/ # Helper utilities
│ ├── pcloud_helper.py # pCloud API wrapper
│ ├── file_operations.py # Local file operations hepler
│ ├── virtual_drive_helper.py # Virtual drive helper
│ ├── sync_folder_helper.py # Sync folder helper
│ ├── test_helper.py # Base class for drive/sync helpers
│ └── test_context.py # A test case helper. Used by each test to perform various operations
├── .env.example # Example configuration
├── requirements.txt # Python dependencies
└── pytest.ini # Pytest configuration
Check README.md for instructions on how to set up and configure the project.
Check README.md for instructions on how to run tests.
The test suite is built around helper classes in utils/:
- Wrapper for pCloud API operations
- You must use this class whenever you need to communicate with the pCloud API.
- A base class for the other two file system helpers.
- All methods and properties used by the
TestContextclass must be first declared here. If there would be no difference between the implementation for methods/properties in any of the subclasses, then the implementation should be added in this class. Otherwise, the implementation in this class should just throw an exception specifying that this method must be implemented in subclasses. - Provides a folder within which all tests would run.
- A subclass of
TestHelper. - Provides specialized methods and properties when working in drive-only mode.
- Works with real mounted drive filesystem
- Instantiated by
tests/drive/conftest.py
- A subclass of
TestHelper. - Provides specialized methods and properties when working in drive+sync mode.
- Works with real mounted drive filesystem
- Instantiated by
tests/sync/conftest.py - Supports triple verification (sync folder → cloud → virtual drive)
- Local file system operations
- All local file system operations must go through here.
- The class used by all test methods.
- It exposes API for the test methods.
- Provides a test folder (inside the
TestHelper's test folder) unique for each test method.
Key fixtures:
sync_helper: Helper instance provided by per-directory conftest files (tests/drive/conftest.pyortests/sync/conftest.py). Not used by tests directly. Tests use it via thetest_subfolderfixture.test_subfolder: TheTestContextcontext class which provides an isolated test subfolder and operations that can be used by methods. Defined intests/conftest.py.pcloud: Direct pCloud API access. Defined intests/conftest.py.
Use strong types everywhere and write type-safe code. Make sure to check the types of function parameters and return value before calling a function or if modifying the handling of its return value. Same thing for properties. There must be no hidden classes that are used in multiple places. No Any types.
Follow the SOLID principle. Write clean, easy-to-read and maintainable code.
- Avoid making the same variable in multiple places. Make it easy to swap values. Whenever you see that you're creating the same variable with the same value in multiple places, consider storing it in a local variable.
- Avoid duplicating logic and code in helpers. Prefer to extract common logic in methods and call those methods where needed.
Only comment API for helpers and other used by the tests. Don't comment the implementation details unless it is not obvious what the code does. Don't comment the tests unless the code is convoluted and/or long and it is not obvious what the test does or how it does it.
This project uses ruff to maintain code style. After you finish making changes to files, run the following commands to fix linter errors and reformat:
ruff check . --fix
ruff format .Note that after you run those commands, the files you just modified would have changed. If you need to apply further changes, you need to read them again.
Tests use a two-dimension marker scheme:
Speed tier (exactly one per test, mutually exclusive):
essential— fast, high-value tests suitable for per-commit runs. Simple CRUD, basic sync verification, small files.extended— thorough but not punishing tests for nightly/PR runs. Larger files (50MB+), multi-step workflows, advanced conflict scenarios.stress— heavy, large-scale tests for weekly/manual runs. Hundreds of files, GB-sized files, concurrent operations, combined workflows.manual— requires human intervention or specific hardware setup.
Functional area (one or more per test):
filesystem— all drive-mode tests (intests/drive/)sync— all sync-folder-mode tests (intests/sync/)
How to apply markers:
- For files where all tests share the same speed tier, use module-level
pytestmark:pytestmark = [pytest.mark.essential, pytest.mark.filesystem]
- For files with mixed speed tiers, use module-level for the area marker and per-function decorators for speed:
pytestmark = [pytest.mark.filesystem] @pytest.mark.essential def test_simple(test_subfolder): ... @pytest.mark.extended def test_heavy(test_subfolder): ...
- Every new test must include appropriate speed tier and area markers.
- Plan carefully how you would approach each test case. Think about what needs to be tested and the minimum amount of steps that need to be taken to unequivocally test this case.
- Place tests in appropriate file under
tests/ - Use
test_subfolderfixture when making any local/remote file I/O. - Follow naming:
test_descriptive_name - Use
FileOperationsfor local file I/O only when you need access to files/folders outside the test subfolder. - Use
pcloudfixture when you need direct access to the pCloud API and thetest_subfolderdoes not provide a useful method/property. First think about adding such method to thetest_subfolder(and adding it to theTestHelperand subclasses). use thetest_subfolderhelper. - Use the default timeout for methods unless necessary to reduce/increase it.
- Always conform to the helper method parameter types.
- Always wait for any local modifications to sync to the cloud and vice versa to verify file operations. If running multiple file operations, prefer to first batch all local I/O and then check for remote existence or vice-versa. This makes sure the tests aren't needlessly slow as all batched file operations will get synced quicker compared to performing them one by one and then waiting.
Example test structure:
def test_my_new_feature(test_subfolder):
"""Test description"""
# Create test file
test_subfolder.create_file('test.txt', content='content')
# Wait to sync
assert test_subfolder.wait_for_file_sync('test.txt')When modifying helper classes:
- Both
VirtualDriveHelperandSyncFolderHelpermust support same interface inherited byTestHelper. They must not override methods that don't require to be overridden in the base class. - Always work with
Pathwhen doing any local file I/O. This makes sure tests run on both Linux/macOS and Windows. - Always work with
PurePosixPathwhen working with any paths outside of local file I/O. This makes sure you don't make random mistakes with path construction/parsing.
Check README.md for troubleshooting tips.