[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6D878ABZCPY3PDT1Q9GD02R":3,"skill-same:01M6D878ABZCPY3PDT1Q9GD02R":63},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":34,"linkOnly":35,"markdownContent":36,"markdownBody":37,"frontMatter":38,"refName":40,"commitSha":41,"skillDirectory":42,"forksCount":43,"repositoryHtmlUrl":44,"repositoryHomepageUrl":6,"ownerHtmlUrl":45,"ownerBlogUrl":46,"ownerDescription":47,"updatedAt":48,"install":49,"resources":62},"01M6D878ABZCPY3PDT1Q9GD02R","python-testing",null,"Python testing strategies using pytest, TDD methodology, fixtures, mocking, parametrization, and coverage requirements.","oabdelmaksoud\u002FSuperClaw","oabdelmaksoud","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F50699149?v=4","01M6D5CVVN778ZCDP1WHS816SP","Omar Abdelmaksoud","01M6D5CW1RHNSKCJR85GJACBFT",2,"MIT","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fpython-testing\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33],"testing","python","python testing","tdd","methodology","coverage","pytest","strategies","requirements","fixtures","2026-11-10 10:12:30",false,"---\nname: python-testing\ndescription: Python testing strategies using pytest, TDD methodology, fixtures, mocking, parametrization, and coverage requirements.\norigin: ECC\n---\n\n# Python Testing Patterns\n\nComprehensive testing strategies for Python applications using pytest, TDD methodology, and best practices.\n\n## When to Activate\n\n- Writing new Python code (follow TDD: red, green, refactor)\n- Designing test suites for Python projects\n- Reviewing Python test coverage\n- Setting up testing infrastructure\n\n## Core Testing Philosophy\n\n### Test-Driven Development (TDD)\n\nAlways follow the TDD cycle:\n\n1. **RED**: Write a failing test for the desired behavior\n2. **GREEN**: Write minimal code to make the test pass\n3. **REFACTOR**: Improve code while keeping tests green\n\n```python\n# Step 1: Write failing test (RED)\ndef test_add_numbers():\n    result = add(2, 3)\n    assert result == 5\n\n# Step 2: Write minimal implementation (GREEN)\ndef add(a, b):\n    return a + b\n\n# Step 3: Refactor if needed (REFACTOR)\n```\n\n### Coverage Requirements\n\n- **Target**: 80%+ code coverage\n- **Critical paths**: 100% coverage required\n- Use `pytest --cov` to measure coverage\n\n```bash\npytest --cov=mypackage --cov-report=term-missing --cov-report=html\n```\n\n## pytest Fundamentals\n\n### Basic Test Structure\n\n```python\nimport pytest\n\ndef test_addition():\n    \"\"\"Test basic addition.\"\"\"\n    assert 2 + 2 == 4\n\ndef test_string_uppercase():\n    \"\"\"Test string uppercasing.\"\"\"\n    text = \"hello\"\n    assert text.upper() == \"HELLO\"\n\ndef test_list_append():\n    \"\"\"Test list append.\"\"\"\n    items = [1, 2, 3]\n    items.append(4)\n    assert 4 in items\n    assert len(items) == 4\n```\n\n### Assertions\n\n```python\n# Equality\nassert result == expected\n\n# Inequality\nassert result != unexpected\n\n# Truthiness\nassert result  # Truthy\nassert not result  # Falsy\nassert result is True  # Exactly True\nassert result is False  # Exactly False\nassert result is None  # Exactly None\n\n# Membership\nassert item in collection\nassert item not in collection\n\n# Comparisons\nassert result > 0\nassert 0 \u003C= result \u003C= 100\n\n# Type checking\nassert isinstance(result, str)\n\n# Exception testing (preferred approach)\nwith pytest.raises(ValueError):\n    raise ValueError(\"error message\")\n\n# Check exception message\nwith pytest.raises(ValueError, match=\"invalid input\"):\n    raise ValueError(\"invalid input provided\")\n\n# Check exception attributes\nwith pytest.raises(ValueError) as exc_info:\n    raise ValueError(\"error message\")\nassert str(exc_info.value) == \"error message\"\n```\n\n## Fixtures\n\n### Basic Fixture Usage\n\n```python\nimport pytest\n\n@pytest.fixture\ndef sample_data():\n    \"\"\"Fixture providing sample data.\"\"\"\n    return {\"name\": \"Alice\", \"age\": 30}\n\ndef test_sample_data(sample_data):\n    \"\"\"Test using the fixture.\"\"\"\n    assert sample_data[\"name\"] == \"Alice\"\n    assert sample_data[\"age\"] == 30\n```\n\n### Fixture with Setup\u002FTeardown\n\n```python\n@pytest.fixture\ndef database():\n    \"\"\"Fixture with setup and teardown.\"\"\"\n    # Setup\n    db = Database(\":memory:\")\n    db.create_tables()\n    db.insert_test_data()\n\n    yield db  # Provide to test\n\n    # Teardown\n    db.close()\n\ndef test_database_query(database):\n    \"\"\"Test database operations.\"\"\"\n    result = database.query(\"SELECT * FROM users\")\n    assert len(result) > 0\n```\n\n### Fixture Scopes\n\n```python\n# Function scope (default) - runs for each test\n@pytest.fixture\ndef temp_file():\n    with open(\"temp.txt\", \"w\") as f:\n        yield f\n    os.remove(\"temp.txt\")\n\n# Module scope - runs once per module\n@pytest.fixture(scope=\"module\")\ndef module_db():\n    db = Database(\":memory:\")\n    db.create_tables()\n    yield db\n    db.close()\n\n# Session scope - runs once per test session\n@pytest.fixture(scope=\"session\")\ndef shared_resource():\n    resource = ExpensiveResource()\n    yield resource\n    resource.cleanup()\n```\n\n### Fixture with Parameters\n\n```python\n@pytest.fixture(params=[1, 2, 3])\ndef number(request):\n    \"\"\"Parameterized fixture.\"\"\"\n    return request.param\n\ndef test_numbers(number):\n    \"\"\"Test runs 3 times, once for each parameter.\"\"\"\n    assert number > 0\n```\n\n### Using Multiple Fixtures\n\n```python\n@pytest.fixture\ndef user():\n    return User(id=1, name=\"Alice\")\n\n@pytest.fixture\ndef admin():\n    return User(id=2, name=\"Admin\", role=\"admin\")\n\ndef test_user_admin_interaction(user, admin):\n    \"\"\"Test using multiple fixtures.\"\"\"\n    assert admin.can_manage(user)\n```\n\n### Autouse Fixtures\n\n```python\n@pytest.fixture(autouse=True)\ndef reset_config():\n    \"\"\"Automatically runs before every test.\"\"\"\n    Config.reset()\n    yield\n    Config.cleanup()\n\ndef test_without_fixture_call():\n    # reset_config runs automatically\n    assert Config.get_setting(\"debug\") is False\n```\n\n### Conftest.py for Shared Fixtures\n\n```python\n# tests\u002Fconftest.py\nimport pytest\n\n@pytest.fixture\ndef client():\n    \"\"\"Shared fixture for all tests.\"\"\"\n    app = create_app(testing=True)\n    with app.test_client() as client:\n        yield client\n\n@pytest.fixture\ndef auth_headers(client):\n    \"\"\"Generate auth headers for API testing.\"\"\"\n    response = client.post(\"\u002Fapi\u002Flogin\", json={\n        \"username\": \"test\",\n        \"password\": \"test\"\n    })\n    token = response.json[\"token\"]\n    return {\"Authorization\": f\"Bearer {token}\"}\n```\n\n## Parametrization\n\n### Basic Parametrization\n\n```python\n@pytest.mark.parametrize(\"input,expected\", [\n    (\"hello\", \"HELLO\"),\n    (\"world\", \"WORLD\"),\n    (\"PyThOn\", \"PYTHON\"),\n])\ndef test_uppercase(input, expected):\n    \"\"\"Test runs 3 times with different inputs.\"\"\"\n    assert input.upper() == expected\n```\n\n### Multiple Parameters\n\n```python\n@pytest.mark.parametrize(\"a,b,expected\", [\n    (2, 3, 5),\n    (0, 0, 0),\n    (-1, 1, 0),\n    (100, 200, 300),\n])\ndef test_add(a, b, expected):\n    \"\"\"Test addition with multiple inputs.\"\"\"\n    assert add(a, b) == expected\n```\n\n### Parametrize with IDs\n\n```python\n@pytest.mark.parametrize(\"input,expected\", [\n    (\"valid@email.com\", True),\n    (\"invalid\", False),\n    (\"@no-domain.com\", False),\n], ids=[\"valid-email\", \"missing-at\", \"missing-domain\"])\ndef test_email_validation(input, expected):\n    \"\"\"Test email validation with readable test IDs.\"\"\"\n    assert is_valid_email(input) is expected\n```\n\n### Parametrized Fixtures\n\n```python\n@pytest.fixture(params=[\"sqlite\", \"postgresql\", \"mysql\"])\ndef db(request):\n    \"\"\"Test against multiple database backends.\"\"\"\n    if request.param == \"sqlite\":\n        return Database(\":memory:\")\n    elif request.param == \"postgresql\":\n        return Database(\"postgresql:\u002F\u002Flocalhost\u002Ftest\")\n    elif request.param == \"mysql\":\n        return Database(\"mysql:\u002F\u002Flocalhost\u002Ftest\")\n\ndef test_database_operations(db):\n    \"\"\"Test runs 3 times, once for each database.\"\"\"\n    result = db.query(\"SELECT 1\")\n    assert result is not None\n```\n\n## Markers and Test Selection\n\n### Custom Markers\n\n```python\n# Mark slow tests\n@pytest.mark.slow\ndef test_slow_operation():\n    time.sleep(5)\n\n# Mark integration tests\n@pytest.mark.integration\ndef test_api_integration():\n    response = requests.get(\"https:\u002F\u002Fapi.example.com\")\n    assert response.status_code == 200\n\n# Mark unit tests\n@pytest.mark.unit\ndef test_unit_logic():\n    assert calculate(2, 3) == 5\n```\n\n### Run Specific Tests\n\n```bash\n# Run only fast tests\npytest -m \"not slow\"\n\n# Run only integration tests\npytest -m integration\n\n# Run integration or slow tests\npytest -m \"integration or slow\"\n\n# Run tests marked as unit but not slow\npytest -m \"unit and not slow\"\n```\n\n### Configure Markers in pytest.ini\n\n```ini\n[pytest]\nmarkers =\n    slow: marks tests as slow\n    integration: marks tests as integration tests\n    unit: marks tests as unit tests\n    django: marks tests as requiring Django\n```\n\n## Mocking and Patching\n\n### Mocking Functions\n\n```python\nfrom unittest.mock import patch, Mock\n\n@patch(\"mypackage.external_api_call\")\ndef test_with_mock(api_call_mock):\n    \"\"\"Test with mocked external API.\"\"\"\n    api_call_mock.return_value = {\"status\": \"success\"}\n\n    result = my_function()\n\n    api_call_mock.assert_called_once()\n    assert result[\"status\"] == \"success\"\n```\n\n### Mocking Return Values\n\n```python\n@patch(\"mypackage.Database.connect\")\ndef test_database_connection(connect_mock):\n    \"\"\"Test with mocked database connection.\"\"\"\n    connect_mock.return_value = MockConnection()\n\n    db = Database()\n    db.connect()\n\n    connect_mock.assert_called_once_with(\"localhost\")\n```\n\n### Mocking Exceptions\n\n```python\n@patch(\"mypackage.api_call\")\ndef test_api_error_handling(api_call_mock):\n    \"\"\"Test error handling with mocked exception.\"\"\"\n    api_call_mock.side_effect = ConnectionError(\"Network error\")\n\n    with pytest.raises(ConnectionError):\n        api_call()\n\n    api_call_mock.assert_called_once()\n```\n\n### Mocking Context Managers\n\n```python\n@patch(\"builtins.open\", new_callable=mock_open)\ndef test_file_reading(mock_file):\n    \"\"\"Test file reading with mocked open.\"\"\"\n    mock_file.return_value.read.return_value = \"file content\"\n\n    result = read_file(\"test.txt\")\n\n    mock_file.assert_called_once_with(\"test.txt\", \"r\")\n    assert result == \"file content\"\n```\n\n### Using Autospec\n\n```python\n@patch(\"mypackage.DBConnection\", autospec=True)\ndef test_autospec(db_mock):\n    \"\"\"Test with autospec to catch API misuse.\"\"\"\n    db = db_mock.return_value\n    db.query(\"SELECT * FROM users\")\n\n    # This would fail if DBConnection doesn't have query method\n    db_mock.assert_called_once()\n```\n\n### Mock Class Instances\n\n```python\nclass TestUserService:\n    @patch(\"mypackage.UserRepository\")\n    def test_create_user(self, repo_mock):\n        \"\"\"Test user creation with mocked repository.\"\"\"\n        repo_mock.return_value.save.return_value = User(id=1, name=\"Alice\")\n\n        service = UserService(repo_mock.return_value)\n        user = service.create_user(name=\"Alice\")\n\n        assert user.name == \"Alice\"\n        repo_mock.return_value.save.assert_called_once()\n```\n\n### Mock Property\n\n```python\n@pytest.fixture\ndef mock_config():\n    \"\"\"Create a mock with a property.\"\"\"\n    config = Mock()\n    type(config).debug = PropertyMock(return_value=True)\n    type(config).api_key = PropertyMock(return_value=\"test-key\")\n    return config\n\ndef test_with_mock_config(mock_config):\n    \"\"\"Test with mocked config properties.\"\"\"\n    assert mock_config.debug is True\n    assert mock_config.api_key == \"test-key\"\n```\n\n## Testing Async Code\n\n### Async Tests with pytest-asyncio\n\n```python\nimport pytest\n\n@pytest.mark.asyncio\nasync def test_async_function():\n    \"\"\"Test async function.\"\"\"\n    result = await async_add(2, 3)\n    assert result == 5\n\n@pytest.mark.asyncio\nasync def test_async_with_fixture(async_client):\n    \"\"\"Test async with async fixture.\"\"\"\n    response = await async_client.get(\"\u002Fapi\u002Fusers\")\n    assert response.status_code == 200\n```\n\n### Async Fixture\n\n```python\n@pytest.fixture\nasync def async_client():\n    \"\"\"Async fixture providing async test client.\"\"\"\n    app = create_app()\n    async with app.test_client() as client:\n        yield client\n\n@pytest.mark.asyncio\nasync def test_api_endpoint(async_client):\n    \"\"\"Test using async fixture.\"\"\"\n    response = await async_client.get(\"\u002Fapi\u002Fdata\")\n    assert response.status_code == 200\n```\n\n### Mocking Async Functions\n\n```python\n@pytest.mark.asyncio\n@patch(\"mypackage.async_api_call\")\nasync def test_async_mock(api_call_mock):\n    \"\"\"Test async function with mock.\"\"\"\n    api_call_mock.return_value = {\"status\": \"ok\"}\n\n    result = await my_async_function()\n\n    api_call_mock.assert_awaited_once()\n    assert result[\"status\"] == \"ok\"\n```\n\n## Testing Exceptions\n\n### Testing Expected Exceptions\n\n```python\ndef test_divide_by_zero():\n    \"\"\"Test that dividing by zero raises ZeroDivisionError.\"\"\"\n    with pytest.raises(ZeroDivisionError):\n        divide(10, 0)\n\ndef test_custom_exception():\n    \"\"\"Test custom exception with message.\"\"\"\n    with pytest.raises(ValueError, match=\"invalid input\"):\n        validate_input(\"invalid\")\n```\n\n### Testing Exception Attributes\n\n```python\ndef test_exception_with_details():\n    \"\"\"Test exception with custom attributes.\"\"\"\n    with pytest.raises(CustomError) as exc_info:\n        raise CustomError(\"error\", code=400)\n\n    assert exc_info.value.code == 400\n    assert \"error\" in str(exc_info.value)\n```\n\n## Testing Side Effects\n\n### Testing File Operations\n\n```python\nimport tempfile\nimport os\n\ndef test_file_processing():\n    \"\"\"Test file processing with temp file.\"\"\"\n    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:\n        f.write(\"test content\")\n        temp_path = f.name\n\n    try:\n        result = process_file(temp_path)\n        assert result == \"processed: test content\"\n    finally:\n        os.unlink(temp_path)\n```\n\n### Testing with pytest's tmp_path Fixture\n\n```python\ndef test_with_tmp_path(tmp_path):\n    \"\"\"Test using pytest's built-in temp path fixture.\"\"\"\n    test_file = tmp_path \u002F \"test.txt\"\n    test_file.write_text(\"hello world\")\n\n    result = process_file(str(test_file))\n    assert result == \"hello world\"\n    # tmp_path automatically cleaned up\n```\n\n### Testing with tmpdir Fixture\n\n```python\ndef test_with_tmpdir(tmpdir):\n    \"\"\"Test using pytest's tmpdir fixture.\"\"\"\n    test_file = tmpdir.join(\"test.txt\")\n    test_file.write(\"data\")\n\n    result = process_file(str(test_file))\n    assert result == \"data\"\n```\n\n## Test Organization\n\n### Directory Structure\n\n```\ntests\u002F\n├── conftest.py                 # Shared fixtures\n├── __init__.py\n├── unit\u002F                       # Unit tests\n│   ├── __init__.py\n│   ├── test_models.py\n│   ├── test_utils.py\n│   └── test_services.py\n├── integration\u002F                # Integration tests\n│   ├── __init__.py\n│   ├── test_api.py\n│   └── test_database.py\n└── e2e\u002F                        # End-to-end tests\n    ├── __init__.py\n    └── test_user_flow.py\n```\n\n### Test Classes\n\n```python\nclass TestUserService:\n    \"\"\"Group related tests in a class.\"\"\"\n\n    @pytest.fixture(autouse=True)\n    def setup(self):\n        \"\"\"Setup runs before each test in this class.\"\"\"\n        self.service = UserService()\n\n    def test_create_user(self):\n        \"\"\"Test user creation.\"\"\"\n        user = self.service.create_user(\"Alice\")\n        assert user.name == \"Alice\"\n\n    def test_delete_user(self):\n        \"\"\"Test user deletion.\"\"\"\n        user = User(id=1, name=\"Bob\")\n        self.service.delete_user(user)\n        assert not self.service.user_exists(1)\n```\n\n## Best Practices\n\n### DO\n\n- **Follow TDD**: Write tests before code (red-green-refactor)\n- **Test one thing**: Each test should verify a single behavior\n- **Use descriptive names**: `test_user_login_with_invalid_credentials_fails`\n- **Use fixtures**: Eliminate duplication with fixtures\n- **Mock external dependencies**: Don't depend on external services\n- **Test edge cases**: Empty inputs, None values, boundary conditions\n- **Aim for 80%+ coverage**: Focus on critical paths\n- **Keep tests fast**: Use marks to separate slow tests\n\n### DON'T\n\n- **Don't test implementation**: Test behavior, not internals\n- **Don't use complex conditionals in tests**: Keep tests simple\n- **Don't ignore test failures**: All tests must pass\n- **Don't test third-party code**: Trust libraries to work\n- **Don't share state between tests**: Tests should be independent\n- **Don't catch exceptions in tests**: Use `pytest.raises`\n- **Don't use print statements**: Use assertions and pytest output\n- **Don't write tests that are too brittle**: Avoid over-specific mocks\n\n## Common Patterns\n\n### Testing API Endpoints (FastAPI\u002FFlask)\n\n```python\n@pytest.fixture\ndef client():\n    app = create_app(testing=True)\n    return app.test_client()\n\ndef test_get_user(client):\n    response = client.get(\"\u002Fapi\u002Fusers\u002F1\")\n    assert response.status_code == 200\n    assert response.json[\"id\"] == 1\n\ndef test_create_user(client):\n    response = client.post(\"\u002Fapi\u002Fusers\", json={\n        \"name\": \"Alice\",\n        \"email\": \"alice@example.com\"\n    })\n    assert response.status_code == 201\n    assert response.json[\"name\"] == \"Alice\"\n```\n\n### Testing Database Operations\n\n```python\n@pytest.fixture\ndef db_session():\n    \"\"\"Create a test database session.\"\"\"\n    session = Session(bind=engine)\n    session.begin_nested()\n    yield session\n    session.rollback()\n    session.close()\n\ndef test_create_user(db_session):\n    user = User(name=\"Alice\", email=\"alice@example.com\")\n    db_session.add(user)\n    db_session.commit()\n\n    retrieved = db_session.query(User).filter_by(name=\"Alice\").first()\n    assert retrieved.email == \"alice@example.com\"\n```\n\n### Testing Class Methods\n\n```python\nclass TestCalculator:\n    @pytest.fixture\n    def calculator(self):\n        return Calculator()\n\n    def test_add(self, calculator):\n        assert calculator.add(2, 3) == 5\n\n    def test_divide_by_zero(self, calculator):\n        with pytest.raises(ZeroDivisionError):\n            calculator.divide(10, 0)\n```\n\n## pytest Configuration\n\n### pytest.ini\n\n```ini\n[pytest]\ntestpaths = tests\npython_files = test_*.py\npython_classes = Test*\npython_functions = test_*\naddopts =\n    --strict-markers\n    --disable-warnings\n    --cov=mypackage\n    --cov-report=term-missing\n    --cov-report=html\nmarkers =\n    slow: marks tests as slow\n    integration: marks tests as integration tests\n    unit: marks tests as unit tests\n```\n\n### pyproject.toml\n\n```toml\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\npython_files = [\"test_*.py\"]\npython_classes = [\"Test*\"]\npython_functions = [\"test_*\"]\naddopts = [\n    \"--strict-markers\",\n    \"--cov=mypackage\",\n    \"--cov-report=term-missing\",\n    \"--cov-report=html\",\n]\nmarkers = [\n    \"slow: marks tests as slow\",\n    \"integration: marks tests as integration tests\",\n    \"unit: marks tests as unit tests\",\n]\n```\n\n## Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run specific file\npytest tests\u002Ftest_utils.py\n\n# Run specific test\npytest tests\u002Ftest_utils.py::test_function\n\n# Run with verbose output\npytest -v\n\n# Run with coverage\npytest --cov=mypackage --cov-report=html\n\n# Run only fast tests\npytest -m \"not slow\"\n\n# Run until first failure\npytest -x\n\n# Run and stop on N failures\npytest --maxfail=3\n\n# Run last failed tests\npytest --lf\n\n# Run tests with pattern\npytest -k \"test_user\"\n\n# Run with debugger on failure\npytest --pdb\n```\n\n## Quick Reference\n\n| Pattern | Usage |\n|---------|-------|\n| `pytest.raises()` | Test expected exceptions |\n| `@pytest.fixture()` | Create reusable test fixtures |\n| `@pytest.mark.parametrize()` | Run tests with multiple inputs |\n| `@pytest.mark.slow` | Mark slow tests |\n| `pytest -m \"not slow\"` | Skip slow tests |\n| `@patch()` | Mock functions and classes |\n| `tmp_path` fixture | Automatic temp directory |\n| `pytest --cov` | Generate coverage report |\n| `assert` | Simple and readable assertions |\n\n**Remember**: Tests are code too. Keep them clean, readable, and maintainable. Good tests catch bugs; great tests prevent them.\n","# Python Testing Patterns\n\nComprehensive testing strategies for Python applications using pytest, TDD methodology, and best practices.\n\n## When to Activate\n\n- Writing new Python code (follow TDD: red, green, refactor)\n- Designing test suites for Python projects\n- Reviewing Python test coverage\n- Setting up testing infrastructure\n\n## Core Testing Philosophy\n\n### Test-Driven Development (TDD)\n\nAlways follow the TDD cycle:\n\n1. **RED**: Write a failing test for the desired behavior\n2. **GREEN**: Write minimal code to make the test pass\n3. **REFACTOR**: Improve code while keeping tests green\n\n```python\n# Step 1: Write failing test (RED)\ndef test_add_numbers():\n    result = add(2, 3)\n    assert result == 5\n\n# Step 2: Write minimal implementation (GREEN)\ndef add(a, b):\n    return a + b\n\n# Step 3: Refactor if needed (REFACTOR)\n```\n\n### Coverage Requirements\n\n- **Target**: 80%+ code coverage\n- **Critical paths**: 100% coverage required\n- Use `pytest --cov` to measure coverage\n\n```bash\npytest --cov=mypackage --cov-report=term-missing --cov-report=html\n```\n\n## pytest Fundamentals\n\n### Basic Test Structure\n\n```python\nimport pytest\n\ndef test_addition():\n    \"\"\"Test basic addition.\"\"\"\n    assert 2 + 2 == 4\n\ndef test_string_uppercase():\n    \"\"\"Test string uppercasing.\"\"\"\n    text = \"hello\"\n    assert text.upper() == \"HELLO\"\n\ndef test_list_append():\n    \"\"\"Test list append.\"\"\"\n    items = [1, 2, 3]\n    items.append(4)\n    assert 4 in items\n    assert len(items) == 4\n```\n\n### Assertions\n\n```python\n# Equality\nassert result == expected\n\n# Inequality\nassert result != unexpected\n\n# Truthiness\nassert result  # Truthy\nassert not result  # Falsy\nassert result is True  # Exactly True\nassert result is False  # Exactly False\nassert result is None  # Exactly None\n\n# Membership\nassert item in collection\nassert item not in collection\n\n# Comparisons\nassert result > 0\nassert 0 \u003C= result \u003C= 100\n\n# Type checking\nassert isinstance(result, str)\n\n# Exception testing (preferred approach)\nwith pytest.raises(ValueError):\n    raise ValueError(\"error message\")\n\n# Check exception message\nwith pytest.raises(ValueError, match=\"invalid input\"):\n    raise ValueError(\"invalid input provided\")\n\n# Check exception attributes\nwith pytest.raises(ValueError) as exc_info:\n    raise ValueError(\"error message\")\nassert str(exc_info.value) == \"error message\"\n```\n\n## Fixtures\n\n### Basic Fixture Usage\n\n```python\nimport pytest\n\n@pytest.fixture\ndef sample_data():\n    \"\"\"Fixture providing sample data.\"\"\"\n    return {\"name\": \"Alice\", \"age\": 30}\n\ndef test_sample_data(sample_data):\n    \"\"\"Test using the fixture.\"\"\"\n    assert sample_data[\"name\"] == \"Alice\"\n    assert sample_data[\"age\"] == 30\n```\n\n### Fixture with Setup\u002FTeardown\n\n```python\n@pytest.fixture\ndef database():\n    \"\"\"Fixture with setup and teardown.\"\"\"\n    # Setup\n    db = Database(\":memory:\")\n    db.create_tables()\n    db.insert_test_data()\n\n    yield db  # Provide to test\n\n    # Teardown\n    db.close()\n\ndef test_database_query(database):\n    \"\"\"Test database operations.\"\"\"\n    result = database.query(\"SELECT * FROM users\")\n    assert len(result) > 0\n```\n\n### Fixture Scopes\n\n```python\n# Function scope (default) - runs for each test\n@pytest.fixture\ndef temp_file():\n    with open(\"temp.txt\", \"w\") as f:\n        yield f\n    os.remove(\"temp.txt\")\n\n# Module scope - runs once per module\n@pytest.fixture(scope=\"module\")\ndef module_db():\n    db = Database(\":memory:\")\n    db.create_tables()\n    yield db\n    db.close()\n\n# Session scope - runs once per test session\n@pytest.fixture(scope=\"session\")\ndef shared_resource():\n    resource = ExpensiveResource()\n    yield resource\n    resource.cleanup()\n```\n\n### Fixture with Parameters\n\n```python\n@pytest.fixture(params=[1, 2, 3])\ndef number(request):\n    \"\"\"Parameterized fixture.\"\"\"\n    return request.param\n\ndef test_numbers(number):\n    \"\"\"Test runs 3 times, once for each parameter.\"\"\"\n    assert number > 0\n```\n\n### Using Multiple Fixtures\n\n```python\n@pytest.fixture\ndef user():\n    return User(id=1, name=\"Alice\")\n\n@pytest.fixture\ndef admin():\n    return User(id=2, name=\"Admin\", role=\"admin\")\n\ndef test_user_admin_interaction(user, admin):\n    \"\"\"Test using multiple fixtures.\"\"\"\n    assert admin.can_manage(user)\n```\n\n### Autouse Fixtures\n\n```python\n@pytest.fixture(autouse=True)\ndef reset_config():\n    \"\"\"Automatically runs before every test.\"\"\"\n    Config.reset()\n    yield\n    Config.cleanup()\n\ndef test_without_fixture_call():\n    # reset_config runs automatically\n    assert Config.get_setting(\"debug\") is False\n```\n\n### Conftest.py for Shared Fixtures\n\n```python\n# tests\u002Fconftest.py\nimport pytest\n\n@pytest.fixture\ndef client():\n    \"\"\"Shared fixture for all tests.\"\"\"\n    app = create_app(testing=True)\n    with app.test_client() as client:\n        yield client\n\n@pytest.fixture\ndef auth_headers(client):\n    \"\"\"Generate auth headers for API testing.\"\"\"\n    response = client.post(\"\u002Fapi\u002Flogin\", json={\n        \"username\": \"test\",\n        \"password\": \"test\"\n    })\n    token = response.json[\"token\"]\n    return {\"Authorization\": f\"Bearer {token}\"}\n```\n\n## Parametrization\n\n### Basic Parametrization\n\n```python\n@pytest.mark.parametrize(\"input,expected\", [\n    (\"hello\", \"HELLO\"),\n    (\"world\", \"WORLD\"),\n    (\"PyThOn\", \"PYTHON\"),\n])\ndef test_uppercase(input, expected):\n    \"\"\"Test runs 3 times with different inputs.\"\"\"\n    assert input.upper() == expected\n```\n\n### Multiple Parameters\n\n```python\n@pytest.mark.parametrize(\"a,b,expected\", [\n    (2, 3, 5),\n    (0, 0, 0),\n    (-1, 1, 0),\n    (100, 200, 300),\n])\ndef test_add(a, b, expected):\n    \"\"\"Test addition with multiple inputs.\"\"\"\n    assert add(a, b) == expected\n```\n\n### Parametrize with IDs\n\n```python\n@pytest.mark.parametrize(\"input,expected\", [\n    (\"valid@email.com\", True),\n    (\"invalid\", False),\n    (\"@no-domain.com\", False),\n], ids=[\"valid-email\", \"missing-at\", \"missing-domain\"])\ndef test_email_validation(input, expected):\n    \"\"\"Test email validation with readable test IDs.\"\"\"\n    assert is_valid_email(input) is expected\n```\n\n### Parametrized Fixtures\n\n```python\n@pytest.fixture(params=[\"sqlite\", \"postgresql\", \"mysql\"])\ndef db(request):\n    \"\"\"Test against multiple database backends.\"\"\"\n    if request.param == \"sqlite\":\n        return Database(\":memory:\")\n    elif request.param == \"postgresql\":\n        return Database(\"postgresql:\u002F\u002Flocalhost\u002Ftest\")\n    elif request.param == \"mysql\":\n        return Database(\"mysql:\u002F\u002Flocalhost\u002Ftest\")\n\ndef test_database_operations(db):\n    \"\"\"Test runs 3 times, once for each database.\"\"\"\n    result = db.query(\"SELECT 1\")\n    assert result is not None\n```\n\n## Markers and Test Selection\n\n### Custom Markers\n\n```python\n# Mark slow tests\n@pytest.mark.slow\ndef test_slow_operation():\n    time.sleep(5)\n\n# Mark integration tests\n@pytest.mark.integration\ndef test_api_integration():\n    response = requests.get(\"https:\u002F\u002Fapi.example.com\")\n    assert response.status_code == 200\n\n# Mark unit tests\n@pytest.mark.unit\ndef test_unit_logic():\n    assert calculate(2, 3) == 5\n```\n\n### Run Specific Tests\n\n```bash\n# Run only fast tests\npytest -m \"not slow\"\n\n# Run only integration tests\npytest -m integration\n\n# Run integration or slow tests\npytest -m \"integration or slow\"\n\n# Run tests marked as unit but not slow\npytest -m \"unit and not slow\"\n```\n\n### Configure Markers in pytest.ini\n\n```ini\n[pytest]\nmarkers =\n    slow: marks tests as slow\n    integration: marks tests as integration tests\n    unit: marks tests as unit tests\n    django: marks tests as requiring Django\n```\n\n## Mocking and Patching\n\n### Mocking Functions\n\n```python\nfrom unittest.mock import patch, Mock\n\n@patch(\"mypackage.external_api_call\")\ndef test_with_mock(api_call_mock):\n    \"\"\"Test with mocked external API.\"\"\"\n    api_call_mock.return_value = {\"status\": \"success\"}\n\n    result = my_function()\n\n    api_call_mock.assert_called_once()\n    assert result[\"status\"] == \"success\"\n```\n\n### Mocking Return Values\n\n```python\n@patch(\"mypackage.Database.connect\")\ndef test_database_connection(connect_mock):\n    \"\"\"Test with mocked database connection.\"\"\"\n    connect_mock.return_value = MockConnection()\n\n    db = Database()\n    db.connect()\n\n    connect_mock.assert_called_once_with(\"localhost\")\n```\n\n### Mocking Exceptions\n\n```python\n@patch(\"mypackage.api_call\")\ndef test_api_error_handling(api_call_mock):\n    \"\"\"Test error handling with mocked exception.\"\"\"\n    api_call_mock.side_effect = ConnectionError(\"Network error\")\n\n    with pytest.raises(ConnectionError):\n        api_call()\n\n    api_call_mock.assert_called_once()\n```\n\n### Mocking Context Managers\n\n```python\n@patch(\"builtins.open\", new_callable=mock_open)\ndef test_file_reading(mock_file):\n    \"\"\"Test file reading with mocked open.\"\"\"\n    mock_file.return_value.read.return_value = \"file content\"\n\n    result = read_file(\"test.txt\")\n\n    mock_file.assert_called_once_with(\"test.txt\", \"r\")\n    assert result == \"file content\"\n```\n\n### Using Autospec\n\n```python\n@patch(\"mypackage.DBConnection\", autospec=True)\ndef test_autospec(db_mock):\n    \"\"\"Test with autospec to catch API misuse.\"\"\"\n    db = db_mock.return_value\n    db.query(\"SELECT * FROM users\")\n\n    # This would fail if DBConnection doesn't have query method\n    db_mock.assert_called_once()\n```\n\n### Mock Class Instances\n\n```python\nclass TestUserService:\n    @patch(\"mypackage.UserRepository\")\n    def test_create_user(self, repo_mock):\n        \"\"\"Test user creation with mocked repository.\"\"\"\n        repo_mock.return_value.save.return_value = User(id=1, name=\"Alice\")\n\n        service = UserService(repo_mock.return_value)\n        user = service.create_user(name=\"Alice\")\n\n        assert user.name == \"Alice\"\n        repo_mock.return_value.save.assert_called_once()\n```\n\n### Mock Property\n\n```python\n@pytest.fixture\ndef mock_config():\n    \"\"\"Create a mock with a property.\"\"\"\n    config = Mock()\n    type(config).debug = PropertyMock(return_value=True)\n    type(config).api_key = PropertyMock(return_value=\"test-key\")\n    return config\n\ndef test_with_mock_config(mock_config):\n    \"\"\"Test with mocked config properties.\"\"\"\n    assert mock_config.debug is True\n    assert mock_config.api_key == \"test-key\"\n```\n\n## Testing Async Code\n\n### Async Tests with pytest-asyncio\n\n```python\nimport pytest\n\n@pytest.mark.asyncio\nasync def test_async_function():\n    \"\"\"Test async function.\"\"\"\n    result = await async_add(2, 3)\n    assert result == 5\n\n@pytest.mark.asyncio\nasync def test_async_with_fixture(async_client):\n    \"\"\"Test async with async fixture.\"\"\"\n    response = await async_client.get(\"\u002Fapi\u002Fusers\")\n    assert response.status_code == 200\n```\n\n### Async Fixture\n\n```python\n@pytest.fixture\nasync def async_client():\n    \"\"\"Async fixture providing async test client.\"\"\"\n    app = create_app()\n    async with app.test_client() as client:\n        yield client\n\n@pytest.mark.asyncio\nasync def test_api_endpoint(async_client):\n    \"\"\"Test using async fixture.\"\"\"\n    response = await async_client.get(\"\u002Fapi\u002Fdata\")\n    assert response.status_code == 200\n```\n\n### Mocking Async Functions\n\n```python\n@pytest.mark.asyncio\n@patch(\"mypackage.async_api_call\")\nasync def test_async_mock(api_call_mock):\n    \"\"\"Test async function with mock.\"\"\"\n    api_call_mock.return_value = {\"status\": \"ok\"}\n\n    result = await my_async_function()\n\n    api_call_mock.assert_awaited_once()\n    assert result[\"status\"] == \"ok\"\n```\n\n## Testing Exceptions\n\n### Testing Expected Exceptions\n\n```python\ndef test_divide_by_zero():\n    \"\"\"Test that dividing by zero raises ZeroDivisionError.\"\"\"\n    with pytest.raises(ZeroDivisionError):\n        divide(10, 0)\n\ndef test_custom_exception():\n    \"\"\"Test custom exception with message.\"\"\"\n    with pytest.raises(ValueError, match=\"invalid input\"):\n        validate_input(\"invalid\")\n```\n\n### Testing Exception Attributes\n\n```python\ndef test_exception_with_details():\n    \"\"\"Test exception with custom attributes.\"\"\"\n    with pytest.raises(CustomError) as exc_info:\n        raise CustomError(\"error\", code=400)\n\n    assert exc_info.value.code == 400\n    assert \"error\" in str(exc_info.value)\n```\n\n## Testing Side Effects\n\n### Testing File Operations\n\n```python\nimport tempfile\nimport os\n\ndef test_file_processing():\n    \"\"\"Test file processing with temp file.\"\"\"\n    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:\n        f.write(\"test content\")\n        temp_path = f.name\n\n    try:\n        result = process_file(temp_path)\n        assert result == \"processed: test content\"\n    finally:\n        os.unlink(temp_path)\n```\n\n### Testing with pytest's tmp_path Fixture\n\n```python\ndef test_with_tmp_path(tmp_path):\n    \"\"\"Test using pytest's built-in temp path fixture.\"\"\"\n    test_file = tmp_path \u002F \"test.txt\"\n    test_file.write_text(\"hello world\")\n\n    result = process_file(str(test_file))\n    assert result == \"hello world\"\n    # tmp_path automatically cleaned up\n```\n\n### Testing with tmpdir Fixture\n\n```python\ndef test_with_tmpdir(tmpdir):\n    \"\"\"Test using pytest's tmpdir fixture.\"\"\"\n    test_file = tmpdir.join(\"test.txt\")\n    test_file.write(\"data\")\n\n    result = process_file(str(test_file))\n    assert result == \"data\"\n```\n\n## Test Organization\n\n### Directory Structure\n\n```\ntests\u002F\n├── conftest.py                 # Shared fixtures\n├── __init__.py\n├── unit\u002F                       # Unit tests\n│   ├── __init__.py\n│   ├── test_models.py\n│   ├── test_utils.py\n│   └── test_services.py\n├── integration\u002F                # Integration tests\n│   ├── __init__.py\n│   ├── test_api.py\n│   └── test_database.py\n└── e2e\u002F                        # End-to-end tests\n    ├── __init__.py\n    └── test_user_flow.py\n```\n\n### Test Classes\n\n```python\nclass TestUserService:\n    \"\"\"Group related tests in a class.\"\"\"\n\n    @pytest.fixture(autouse=True)\n    def setup(self):\n        \"\"\"Setup runs before each test in this class.\"\"\"\n        self.service = UserService()\n\n    def test_create_user(self):\n        \"\"\"Test user creation.\"\"\"\n        user = self.service.create_user(\"Alice\")\n        assert user.name == \"Alice\"\n\n    def test_delete_user(self):\n        \"\"\"Test user deletion.\"\"\"\n        user = User(id=1, name=\"Bob\")\n        self.service.delete_user(user)\n        assert not self.service.user_exists(1)\n```\n\n## Best Practices\n\n### DO\n\n- **Follow TDD**: Write tests before code (red-green-refactor)\n- **Test one thing**: Each test should verify a single behavior\n- **Use descriptive names**: `test_user_login_with_invalid_credentials_fails`\n- **Use fixtures**: Eliminate duplication with fixtures\n- **Mock external dependencies**: Don't depend on external services\n- **Test edge cases**: Empty inputs, None values, boundary conditions\n- **Aim for 80%+ coverage**: Focus on critical paths\n- **Keep tests fast**: Use marks to separate slow tests\n\n### DON'T\n\n- **Don't test implementation**: Test behavior, not internals\n- **Don't use complex conditionals in tests**: Keep tests simple\n- **Don't ignore test failures**: All tests must pass\n- **Don't test third-party code**: Trust libraries to work\n- **Don't share state between tests**: Tests should be independent\n- **Don't catch exceptions in tests**: Use `pytest.raises`\n- **Don't use print statements**: Use assertions and pytest output\n- **Don't write tests that are too brittle**: Avoid over-specific mocks\n\n## Common Patterns\n\n### Testing API Endpoints (FastAPI\u002FFlask)\n\n```python\n@pytest.fixture\ndef client():\n    app = create_app(testing=True)\n    return app.test_client()\n\ndef test_get_user(client):\n    response = client.get(\"\u002Fapi\u002Fusers\u002F1\")\n    assert response.status_code == 200\n    assert response.json[\"id\"] == 1\n\ndef test_create_user(client):\n    response = client.post(\"\u002Fapi\u002Fusers\", json={\n        \"name\": \"Alice\",\n        \"email\": \"alice@example.com\"\n    })\n    assert response.status_code == 201\n    assert response.json[\"name\"] == \"Alice\"\n```\n\n### Testing Database Operations\n\n```python\n@pytest.fixture\ndef db_session():\n    \"\"\"Create a test database session.\"\"\"\n    session = Session(bind=engine)\n    session.begin_nested()\n    yield session\n    session.rollback()\n    session.close()\n\ndef test_create_user(db_session):\n    user = User(name=\"Alice\", email=\"alice@example.com\")\n    db_session.add(user)\n    db_session.commit()\n\n    retrieved = db_session.query(User).filter_by(name=\"Alice\").first()\n    assert retrieved.email == \"alice@example.com\"\n```\n\n### Testing Class Methods\n\n```python\nclass TestCalculator:\n    @pytest.fixture\n    def calculator(self):\n        return Calculator()\n\n    def test_add(self, calculator):\n        assert calculator.add(2, 3) == 5\n\n    def test_divide_by_zero(self, calculator):\n        with pytest.raises(ZeroDivisionError):\n            calculator.divide(10, 0)\n```\n\n## pytest Configuration\n\n### pytest.ini\n\n```ini\n[pytest]\ntestpaths = tests\npython_files = test_*.py\npython_classes = Test*\npython_functions = test_*\naddopts =\n    --strict-markers\n    --disable-warnings\n    --cov=mypackage\n    --cov-report=term-missing\n    --cov-report=html\nmarkers =\n    slow: marks tests as slow\n    integration: marks tests as integration tests\n    unit: marks tests as unit tests\n```\n\n### pyproject.toml\n\n```toml\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\npython_files = [\"test_*.py\"]\npython_classes = [\"Test*\"]\npython_functions = [\"test_*\"]\naddopts = [\n    \"--strict-markers\",\n    \"--cov=mypackage\",\n    \"--cov-report=term-missing\",\n    \"--cov-report=html\",\n]\nmarkers = [\n    \"slow: marks tests as slow\",\n    \"integration: marks tests as integration tests\",\n    \"unit: marks tests as unit tests\",\n]\n```\n\n## Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run specific file\npytest tests\u002Ftest_utils.py\n\n# Run specific test\npytest tests\u002Ftest_utils.py::test_function\n\n# Run with verbose output\npytest -v\n\n# Run with coverage\npytest --cov=mypackage --cov-report=html\n\n# Run only fast tests\npytest -m \"not slow\"\n\n# Run until first failure\npytest -x\n\n# Run and stop on N failures\npytest --maxfail=3\n\n# Run last failed tests\npytest --lf\n\n# Run tests with pattern\npytest -k \"test_user\"\n\n# Run with debugger on failure\npytest --pdb\n```\n\n## Quick Reference\n\n| Pattern | Usage |\n|---------|-------|\n| `pytest.raises()` | Test expected exceptions |\n| `@pytest.fixture()` | Create reusable test fixtures |\n| `@pytest.mark.parametrize()` | Run tests with multiple inputs |\n| `@pytest.mark.slow` | Mark slow tests |\n| `pytest -m \"not slow\"` | Skip slow tests |\n| `@patch()` | Mock functions and classes |\n| `tmp_path` fixture | Automatic temp directory |\n| `pytest --cov` | Generate coverage report |\n| `assert` | Simple and readable assertions |\n\n**Remember**: Tests are code too. Keep them clean, readable, and maintainable. Good tests catch bugs; great tests prevent them.\n",{"name":5,"origin":39,"description":7},"ECC","main","7b610356e36623652299fa2acb477ff821b1d920","upstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fpython-testing",0,"https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fo-abdelmaksoud\u002F","Full-Stack Engineer | AI Systems Architect | Building autonomous multi-agent systems","2026-03-08 21:12:53",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add oabdelmaksoud\u002FSuperClaw --skill python-testing",{"tool":55,"command":56},"bunx","bunx skills add oabdelmaksoud\u002FSuperClaw --skill python-testing",{"tool":58,"command":59},"pnpm","pnpm dlx skills add oabdelmaksoud\u002FSuperClaw --skill python-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fpython-testing\u002FSKILL.md",true,[],[64,83,97,124,150,168],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":73,"publishedAt":34},"01M6D88QCPTBZVCRED0NZ1Y8K8","visa-doc-translate","Translate visa application documents (images) to English and create a bilingual PDF with original and translation","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fvisa-doc-translate\u002FSKILL.md",[70],{"categoryNo":71,"categoryName":72,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理",[74,75,76,77,78,79,80,81,82],"translate","doc","visa doc translate","translation","application","create","images","PDF","documents",{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":34},"01M6D88NBM95T3TFM50CYYAP65","verification-loop","A comprehensive verification system for Claude Code sessions.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fverification-loop\u002FSKILL.md",[],[90,91,92,93,94,95,96],"verification","loop","verification loop","sessions","code","claude code sessions","system",{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":112,"publishedAt":34},"01M6D88JFZ2P996GVRHJNSZSTM","tdd-workflow","Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage including unit, integration, and E2E tests.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Ftdd-workflow\u002FSKILL.md",[103,104,107],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":105,"categoryName":106,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":108,"categoryName":109,"taxonomyType":110,"taxonomyTypeDesc":111},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[27,113,114,115,116,117,94,118,119,120,121,29,122,123],"workflow","tdd workflow","e2e tests","e2e","integration","development","use","test","refactoring","tests","writing",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":34},"01M6D88FTHRRSVJMXF2G7MQAK3","swiftui-patterns","SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS\u002FmacOS UI best practices.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fswiftui-patterns\u002FSKILL.md",[],[131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149],"patterns","swiftui","swiftui patterns","architecture","macos","performance","state management","best practices","state","ui","Optimization","ios","architecture patterns","Composition","performance optimization","view","management","swiftui architecture","navigation",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":157,"publishedAt":34},"01M6D88D527QTQT9DKHTRFN6EA","swift-protocol-di-testing","Protocol-based dependency injection for testable Swift code — mock file system, network, and external APIs using focused protocols and Swift Testing.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fswift-protocol-di-testing\u002FSKILL.md",[156],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[158,159,160,24,94,161,162,163,164,96,165,166,167],"swift protocol di testing","protocol","swift","protocols","file","network","injection","dependency","swift testing","dependency injection",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":34},"01M6D88AJW8H2QNWSW5ZY82R43","swift-concurrency-6-2","Swift 6.2 Approachable Concurrency — single-threaded by default, @concurrent for explicit background offloading, isolated conformances for main actor types.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fswift-concurrency-6-2\u002FSKILL.md",[],[175,176,160,177,178,40],"concurrency","swift concurrency","swift concurrency 6 2","default"]