Skip to main content

galaxy-testing

Galaxy testing with pytest and run_tests.sh - run/write unit, integration, API, selenium tests. Use for: test execution, test failures, pytest errors, ApiTestCase patterns, test fixtures, writing new tests, debugging test failures, test/integration, lib/galaxy_test/api tests. CRITICAL: Always use ./run_tests.sh, never pytest directly.

Source facts

Repository
arash77/galaxy-claude-marketplace
Last source activity
February 11, 2026 at 11:12
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
galaxy-testing
description
Galaxy testing with pytest and run_tests.sh - run/write unit, integration, API, selenium tests. Use for: test execution, test failures, pytest errors, ApiTestCase patterns, test fixtures, writing new tests, debugging test failures, test/integration, lib/galaxy_test/api tests. CRITICAL: Always use ./run_tests.sh, never pytest directly.
argument-hint
[run|write|unit|api|integration]
Persona: You are a senior Galaxy QA engineer specializing in pytest and Galaxy's test infrastructure. Arguments: - $ARGUMENTS - Optional: "run", "write", "unit", "api", "integration" Examples: "", "run", "write unit", "api" Parse $ARGUMENTS to determine which guidance to provide. --- ## Galaxy Testing Guide Galaxy uses **pytest** with a custom test runner script that sets up the proper environment. **CRITICAL:** Always use `./run_tests.sh`, never run `pytest` directly. --- ## If $ARGUMENTS is empty or "run": Test Running Reference ### Basic Test Running **Run integration tests (most common):** ```bash ./run_tests.sh -integration test/integration/test_credentials.py ``` **Run specific test method:** ```bash ./run_tests.sh -integration test/integration/test_credentials.py::TestCredentialsApi::test_list_credentials ``` **Run all tests in a directory:** ```bash ./run_tests.sh -integration test/integration/ ``` ### Test Type Flags - **`-unit`** - Fast unit tests (no server, mocked dependencies) ```bash ./run_tests.sh -unit test/unit/managers/test_workflows.py ``` - **`-api`** - API endpoint tests (starts Galaxy server) ```bash ./run_tests.sh -api lib/galaxy_test/api/test_workflows.py ``` - **`-integration`** - Integration tests (full Galaxy setup) ```bash ./run_tests.sh -integration test/integration/test_vault.py ``` - **`-selenium`** - Browser-based E2E tests ```bash ./run_tests.sh -selenium test/integration_selenium/test_workflow_editor.py ``` - **`-framework`** - Test infrastructure tests ```bash ./run_tests.sh -framework test/framework/ ``` ### Useful Flags **Show detailed output:** ```bash ./run_tests.sh -integration test/integration/test_credentials.py --verbose_errors ``` **Generate coverage report:** ```bash ./run_tests.sh --coverage -integration test/integration/test_credentials.py ``` **Debug mode (drop into pdb on failure):** ```bash ./run_tests.sh --debug -integration test/integration/test_credentials.py ``` **Run tests matching pattern:** ```bash ./run_tests.sh -integration test/integration/test_credentials.py -k "test_create" ``` **Show print statements:** ```bash ./run_tests.sh -integration test/integration/test_credentials.py -s ``` **Run with specific number of workers (parallel):** ```bash ./run_tests.sh -integration test/integration/ -n 4 ``` ### When Using pytest Directly (Advanced) If you must use pytest directly (e.g., for IDE integration), use markers: ```bash pytest -m "not slow" test/unit/ pytest -m "unit" test/unit/managers/test_workflows.py pytest -m "integration" test/integration/test_credentials.py ``` But prefer `./run_tests.sh` for normal usage. --- ## If $ARGUMENTS is "write": Guide to Writing Tests Ask the user what type of test they want to write: 1. **Unit tests** - Fast, isolated tests with mocked dependencies 2. **API tests** - Test API endpoints with Galaxy server 3. **Integration tests** - Full system tests with real database Then provide guidance based on their choice (see sections below). --- ## If $ARGUMENTS contains "unit": Unit Test Writing Guide ### What Are Unit Tests? Unit tests are fast, isolated tests that: - Run without starting Galaxy server - Use in-memory SQLite database - Mock external dependencies - Test individual manager/service methods - Are located in `test/unit/` ### Unit Test Structure **Location:** `test/unit/<module>/test_<class>.py` **Base class:** `BaseTestCase` from `test.unit.app.managers.base` **Example unit test:** ```python """ Unit tests for MyResourceManager. """ from galaxy import model from galaxy.managers.myresources import MyResourceManager from test.unit.app.managers.base import BaseTestCase class TestMyResourceManager(BaseTestCase): """Unit tests for MyResourceManager.""" def setUp(self): super().setUp() self.set_up_managers() def set_up_managers(self): """Set up managers under test.""" self.manager = MyResourceManager(self.app) def test_create_myresource(self): """Test creating a resource.""" # Arrange trans = self.trans # MockTrans from BaseTestCase name = "Test Resource" # Act resource = self.manager.create(trans, name=name) self.session.flush() # Assert assert resource.name == name assert resource.user_id == trans.user.id assert resource.id is not None def test_get_myresource(self): """Test getting a resource by ID.""" # Arrange resource = self._create_resource("Test Resource") # Act retrieved = self.manager.get(self.trans, resource.id) # Assert assert retrieved.id == resource.id assert retrieved.name == resource.name def test_get_nonexistent_myresource_raises_not_found(self): """Test that getting nonexistent resource raises exception.""" from galaxy.exceptions import ObjectNotFound with self.assertRaises(ObjectNotFound): self.manager.get(self.trans, 99999) def test_list_myresources_for_user(self): """Test listing resources for current user.""" # Arrange self._create_resource("Resource 1") self._create_resource("Resource 2") # Act resources = self.manager.list_for_user(self.trans) # Assert assert len(resources) >= 2 names = [r.name for r in resources] assert "Resource 1" in names assert "Resource 2" in names def test_update_myresource(self): """Test updating a resource.""" # Arrange resource = self._create_resource("Original Name") new_name = "Updated Name" # Act updated = self.manager.update(self.trans, resource.id, name=new_name) self.session.flush() # Assert assert updated.id == resource.id assert updated.name == new_name def test_delete_myresource(self): """Test soft-deleting a resource.""" # Arrange resource = self._create_resource("To Delete") # Act self.manager.delete(self.trans, resource.id) self.session.flush() # Assert assert resource.deleted is True def test_cannot_access_other_user_resource(self): """Test access control for other users' resources.""" from galaxy.exceptions import ItemAccessibilityException # Arrange other_user = self._create_user("other@example.com") other_trans = self._create_trans(user=other_user) resource = self.manager.create(other_trans, name="Other User Resource") self.session.flush() # Act & Assert with self.assertRaises(ItemAccessibilityException): self.manager.get(self.trans, resource.id) def _create_resource(self, name: str, **kwargs): """Helper to create a test resource.""" resource = self.manager.create(self.trans, name=name, **kwargs) self.session.flush() return resource def _create_user(self, email: str): """Helper to create a test user.""" user = model.User(email=email, username=email.split("@")[0]) self.session.add(user) self.session.flush() return user def _create_trans(self, user=None): """Helper to create a transaction context for a user.""" from galaxy_mock import MockTrans return MockTrans(app=self.app, user=user or self.user) ``` ### Key Points for Unit Tests - **Extend `BaseTestCase`** from `test.unit.app.managers.base` - **Use `self.trans`** - Pre-configured MockTrans with test user - **Use `self.session`** - SQLAlchemy session (in-memory SQLite) - **Call `self.session.flush()`** after creates/updates to persist - **Override `set_up_managers()`** to instantiate managers under test - **Use helper methods** like `_create_resource()` for test data - **Test error cases** with `self.assertRaises()` - **Follow AAA pattern** - Arrange, Act, Assert ### Available from BaseTestCase ```python self.app # Galaxy application mock self.trans # MockTrans with test user self.user # Test user (admin) self.session # SQLAlchemy session self.history # Default test history ``` ### Running Unit Tests ```bash # Run all unit tests for a manager ./run_tests.sh -unit test/unit/managers/test_myresources.py # Run specific test ./run_tests.sh -unit test/unit/managers/test_myresources.py::TestMyResourceManager::test_create_myresource # Run with coverage ./run_tests.sh --coverage -unit test/unit/managers/test_myresources.py ``` --- ## If $ARGUMENTS contains "api": API Test Writing Guide ### What Are API Tests? API tests: - Start a Galaxy server - Make HTTP requests to API endpoints - Test request/response handling - Verify status codes and response schemas - Are located in `lib/galaxy_test/api/` ### API Test Structure **Location:** `lib/galaxy_test/api/test_<resource>s.py` **Base class:** `ApiTestCase` from `lib/galaxy_test/api/_framework` **Example API test:** ```python """ API tests for MyResource endpoints. """ from galaxy_test.base.populators import DatasetPopulator from ._framework import ApiTestCase class TestMyResourcesApi(ApiTestCase): """Tests for /api/myresources endpoints.""" def setUp(self): super().setUp() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) def test_create_myresource(self): """Test POST /api/myresources.""" payload = { "name": "Test Resource", "description": "Test description", } response = self._post("myresources", data=payload, json=True) self._assert_status_code_is(response, 201) resource = response.json() self._assert_has_keys(resource, "id", "name", "description", "create_time") assert resource["name"] == "Test Resource" assert resource["description"] == "Test description" def test_list_myresources(self): """Test GET /api/myresources.""" # Create test data self._create_myresource("Resource 1") self._create_myresource("Resource 2") # List response = self._get("myresources") self._assert_status_code_is_ok(response) data = response.json() assert "items" in data assert "total_count" in data assert data["total_count"] >= 2 assert len(data["items"]) >= 2 def test_get_myresource(self): """Test GET /api/myresources/{id}.""" resource_id = self._create_myresource("Test Resource") response = self._get(f"myresources/{resource_id}") self._assert_status_code_is_ok(response) resource = response.json() assert resource["id"] == resource_id assert resource["name"] == "Test Resource" def test_update_myresource(self): """Test PUT /api/myresources/{id}.""" resource_id = self._create_myresource("Original Name") payload = {"name": "Updated Name"} response = self._put(f"myresources/{resource_id}", data=payload, json=True) self._assert_status_code_is_ok(response) updated = response.json() assert updated["name"] == "Updated Name" def test_delete_myresource(self): """Test DELETE /api/myresources/{id}.""" resource_id = self._create_myresource("To Delete") response = self._delete(f"myresources/{resource_id}")
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub