generate-conftest.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #!/bin/bash
  2. # Generate conftest.py boilerplate
  3. # Usage: ./generate-conftest.sh [--async] [--db] [--api]
  4. set -e
  5. OUTPUT="tests/conftest.py"
  6. # Check if tests directory exists
  7. if [[ ! -d "tests" ]]; then
  8. echo "Creating tests directory..."
  9. mkdir -p tests
  10. fi
  11. # Check if conftest.py already exists
  12. if [[ -f "$OUTPUT" ]]; then
  13. read -p "conftest.py already exists. Overwrite? [y/N] " -n 1 -r
  14. echo
  15. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  16. exit 0
  17. fi
  18. fi
  19. # Parse arguments
  20. ASYNC=""
  21. DB=""
  22. API=""
  23. while [[ $# -gt 0 ]]; do
  24. case $1 in
  25. --async)
  26. ASYNC=1
  27. shift
  28. ;;
  29. --db)
  30. DB=1
  31. shift
  32. ;;
  33. --api)
  34. API=1
  35. shift
  36. ;;
  37. *)
  38. shift
  39. ;;
  40. esac
  41. done
  42. # Generate conftest.py
  43. cat > "$OUTPUT" << 'HEADER'
  44. """
  45. Pytest configuration and fixtures.
  46. Generated by generate-conftest.sh
  47. """
  48. import pytest
  49. HEADER
  50. # Add async imports if needed
  51. if [[ -n "$ASYNC" ]]; then
  52. cat >> "$OUTPUT" << 'ASYNC_IMPORTS'
  53. import asyncio
  54. ASYNC_IMPORTS
  55. fi
  56. # Add database imports if needed
  57. if [[ -n "$DB" ]]; then
  58. cat >> "$OUTPUT" << 'DB_IMPORTS'
  59. from sqlalchemy import create_engine
  60. from sqlalchemy.orm import sessionmaker
  61. ASYNC_IMPORTS
  62. fi
  63. # Add API imports if needed
  64. if [[ -n "$API" ]]; then
  65. cat >> "$OUTPUT" << 'API_IMPORTS'
  66. from fastapi.testclient import TestClient
  67. # or: from flask.testing import FlaskClient
  68. ASYNC_IMPORTS
  69. fi
  70. # Add base fixtures
  71. cat >> "$OUTPUT" << 'BASE_FIXTURES'
  72. # ============================================================
  73. # Test Configuration
  74. # ============================================================
  75. def pytest_configure(config):
  76. """Register custom markers."""
  77. config.addinivalue_line("markers", "slow: marks tests as slow")
  78. config.addinivalue_line("markers", "integration: marks integration tests")
  79. config.addinivalue_line("markers", "e2e: marks end-to-end tests")
  80. def pytest_collection_modifyitems(config, items):
  81. """Skip slow tests unless --slow flag is provided."""
  82. if not config.getoption("--slow", default=False):
  83. skip_slow = pytest.mark.skip(reason="use --slow to run")
  84. for item in items:
  85. if "slow" in item.keywords:
  86. item.add_marker(skip_slow)
  87. def pytest_addoption(parser):
  88. """Add custom CLI options."""
  89. parser.addoption(
  90. "--slow",
  91. action="store_true",
  92. default=False,
  93. help="run slow tests"
  94. )
  95. # ============================================================
  96. # Common Fixtures
  97. # ============================================================
  98. @pytest.fixture
  99. def sample_data():
  100. """Provide sample test data."""
  101. return {
  102. "id": 1,
  103. "name": "Test",
  104. "active": True,
  105. }
  106. @pytest.fixture
  107. def temp_file(tmp_path):
  108. """Create a temporary file for testing."""
  109. file_path = tmp_path / "test_file.txt"
  110. file_path.write_text("test content")
  111. return file_path
  112. BASE_FIXTURES
  113. # Add async fixtures if requested
  114. if [[ -n "$ASYNC" ]]; then
  115. cat >> "$OUTPUT" << 'ASYNC_FIXTURES'
  116. # ============================================================
  117. # Async Fixtures
  118. # ============================================================
  119. @pytest.fixture(scope="session")
  120. def event_loop():
  121. """Create event loop for async tests."""
  122. loop = asyncio.new_event_loop()
  123. yield loop
  124. loop.close()
  125. @pytest.fixture
  126. async def async_client():
  127. """Async HTTP client fixture."""
  128. import aiohttp
  129. async with aiohttp.ClientSession() as session:
  130. yield session
  131. ASYNC_FIXTURES
  132. fi
  133. # Add database fixtures if requested
  134. if [[ -n "$DB" ]]; then
  135. cat >> "$OUTPUT" << 'DB_FIXTURES'
  136. # ============================================================
  137. # Database Fixtures
  138. # ============================================================
  139. @pytest.fixture(scope="session")
  140. def db_engine():
  141. """Create test database engine."""
  142. engine = create_engine("sqlite:///:memory:")
  143. # Create tables here
  144. yield engine
  145. engine.dispose()
  146. @pytest.fixture
  147. def db_session(db_engine):
  148. """Create database session with transaction rollback."""
  149. Session = sessionmaker(bind=db_engine)
  150. session = Session()
  151. yield session
  152. session.rollback()
  153. session.close()
  154. DB_FIXTURES
  155. fi
  156. # Add API fixtures if requested
  157. if [[ -n "$API" ]]; then
  158. cat >> "$OUTPUT" << 'API_FIXTURES'
  159. # ============================================================
  160. # API Fixtures
  161. # ============================================================
  162. @pytest.fixture
  163. def app():
  164. """Create test application."""
  165. from myapp import create_app
  166. app = create_app(testing=True)
  167. return app
  168. @pytest.fixture
  169. def client(app):
  170. """Create test client."""
  171. return TestClient(app)
  172. @pytest.fixture
  173. def authenticated_client(client):
  174. """Create authenticated test client."""
  175. # Add authentication logic here
  176. client.headers["Authorization"] = "Bearer test-token"
  177. return client
  178. API_FIXTURES
  179. fi
  180. echo "Generated $OUTPUT"
  181. echo ""
  182. echo "Options used:"
  183. [[ -n "$ASYNC" ]] && echo " --async: Async fixtures included"
  184. [[ -n "$DB" ]] && echo " --db: Database fixtures included"
  185. [[ -n "$API" ]] && echo " --api: API fixtures included"