# Test Suite Documentation Este diretório contém a suíte completa de testes para o projeto Hugging Face Spaces. O sistema de testes foi projetado seguindo as melhores práticas de desenvolvimento Python, utilizando pytest como framework principal. ## 📁 Estrutura de Testes ``` tests/ ├── README.md # Esta documentação ├── conftest.py # Configurações globais e fixtures ├── test_patterns.py # Exemplos de padrões de teste ├── data/ # Dados de teste │ └── sample_market_data.json # Dados de mercado para testes ├── unit/ # Testes unitários │ ├── conftest.py # Fixtures específicas para testes unitários │ ├── test_advanced_market_processing.py │ └── test_voting_system.py └── integration/ # Testes de integração ├── conftest.py # Fixtures específicas para testes de integração └── test_market_analysis_integration.py ``` ## 🚀 Como Executar os Testes ### Usando o Makefile (Recomendado) ```bash # Executar todos os testes make test # Executar apenas testes unitários make test-unit # Executar apenas testes de integração make test-integration # Executar testes com relatório de cobertura make test-coverage # Executar apenas testes rápidos (excluir testes lentos) make test-fast # Executar testes em paralelo make test-parallel # Executar testes em modo debug make test-debug ``` ### Usando pytest diretamente ```bash # Executar todos os testes pytest -v # Executar testes específicos por marcador pytest -m unit # Apenas testes unitários pytest -m integration # Apenas testes de integração pytest -m "not slow" # Excluir testes lentos pytest -m performance # Apenas testes de performance # Executar testes com cobertura pytest --cov=src --cov-report=html # Executar testes em paralelo pytest -n auto # Executar testes específicos pytest tests/unit/test_voting_system.py::test_majority_voting ``` ## 🏷️ Marcadores de Teste O sistema utiliza marcadores para categorizar e filtrar testes: - `unit`: Testes unitários - `integration`: Testes de integração - `slow`: Testes que demoram mais para executar - `api`: Testes de API - `ui`: Testes de interface do usuário - `smoke`: Testes de fumaça (básicos) - `regression`: Testes de regressão - `performance`: Testes de performance - `security`: Testes de segurança ### Exemplo de uso de marcadores: ```python import pytest @pytest.mark.unit def test_basic_functionality(): assert True @pytest.mark.slow @pytest.mark.performance def test_large_dataset_processing(): # Teste que demora mais tempo pass @pytest.mark.integration @pytest.mark.api def test_api_integration(): # Teste de integração com API pass ``` ## 🔧 Configuração ### pytest.ini O arquivo `pytest.ini` na raiz do projeto contém as configurações principais: - Descoberta automática de testes - Configuração de relatórios de cobertura - Definição de marcadores - Configuração de timeout - Filtros de warnings ### conftest.py Cada nível possui seu próprio `conftest.py`: - **Global** (`tests/conftest.py`): Fixtures compartilhadas por todos os testes - **Unit** (`tests/unit/conftest.py`): Fixtures específicas para testes unitários - **Integration** (`tests/integration/conftest.py`): Fixtures para testes de integração ## 📊 Fixtures Disponíveis ### Fixtures Globais - `project_root`: Caminho para a raiz do projeto - `test_data`: Dados de teste carregados - `temp_dir`: Diretório temporário para testes - `mock_db`: Mock do banco de dados - `sample_market_data`: Dados de mercado de exemplo - `mock_gradio_interface`: Mock da interface Gradio - `mock_transformers`: Mock da biblioteca transformers - `test_env_vars`: Variáveis de ambiente para testes - `caplog_setup`: Configuração de captura de logs ### Fixtures de Testes Unitários - `mock_logger`: Mock do sistema de logging - `mock_config`: Mock da configuração - `mock_market_processor`: Mock do processador de mercado - `mock_voting_strategy`: Mock da estratégia de votação - `mock_sentiment_analyzer`: Mock do analisador de sentimento - `mock_fibonacci_analyzer`: Mock do analisador de Fibonacci - `sample_price_data`: Dados de preço para testes - `mock_database_logger`: Mock do logger de banco de dados ### Fixtures de Testes de Integração - `temp_db`: Banco de dados SQLite temporário - `db_connection`: Conexão com banco de dados de teste - `populated_db`: Banco de dados populado com dados de teste - `mock_yfinance`: Mock da API yfinance - `mock_requests`: Mock da biblioteca requests - `integration_config`: Configuração para testes de integração - `temp_cache_dir`: Diretório de cache temporário ## 📈 Relatórios de Cobertura Os relatórios de cobertura são gerados em múltiplos formatos: - **HTML**: `htmlcov/index.html` - Relatório visual detalhado - **XML**: `coverage.xml` - Para integração com CI/CD - **Terminal**: Exibido diretamente no terminal ### Visualizar relatório HTML: ```bash # Gerar e abrir relatório make test-coverage open htmlcov/index.html # macOS start htmlcov/index.html # Windows ``` ## 🔍 Padrões de Teste O arquivo `test_patterns.py` demonstra padrões e melhores práticas: ### 1. Testes Unitários Básicos ```python def test_basic_functionality(): """Teste básico de funcionalidade.""" result = some_function() assert result is not None assert isinstance(result, expected_type) ``` ### 2. Uso de Fixtures ```python def test_with_fixture(sample_data): """Teste usando fixture.""" processor = DataProcessor() result = processor.process(sample_data) assert result.is_valid ``` ### 3. Mocking ```python @patch('module.external_service') def test_with_mock(mock_service): """Teste com mock de serviço externo.""" mock_service.return_value = expected_response result = function_that_uses_service() assert result == expected_result mock_service.assert_called_once() ``` ### 4. Testes Parametrizados ```python @pytest.mark.parametrize("input_value,expected", [ (1, 2), (2, 4), (3, 6), ]) def test_multiplication(input_value, expected): """Teste parametrizado.""" assert multiply_by_two(input_value) == expected ``` ### 5. Tratamento de Exceções ```python def test_exception_handling(): """Teste de tratamento de exceções.""" with pytest.raises(ValueError, match="Invalid input"): function_that_should_raise(invalid_input) ``` ### 6. Testes Assíncronos ```python @pytest.mark.asyncio async def test_async_function(): """Teste de função assíncrona.""" result = await async_function() assert result is not None ``` ## 🚀 Performance e Benchmarking ### Testes de Performance ```python @pytest.mark.performance def test_performance_benchmark(benchmark): """Teste de benchmark de performance.""" result = benchmark(expensive_function, large_dataset) assert result is not None ``` ### Monitoramento de Memória ```python @pytest.mark.performance def test_memory_usage(): """Teste de uso de memória.""" import psutil import os process = psutil.Process(os.getpid()) initial_memory = process.memory_info().rss # Executar operação que consome memória result = memory_intensive_operation() final_memory = process.memory_info().rss memory_increase = final_memory - initial_memory # Verificar se o aumento de memória está dentro do esperado assert memory_increase < 100 * 1024 * 1024 # 100MB ``` ## 🔒 Testes de Segurança ```python @pytest.mark.security def test_input_validation(): """Teste de validação de entrada.""" malicious_inputs = [ "", "'; DROP TABLE users; --", "../../../etc/passwd", ] for malicious_input in malicious_inputs: with pytest.raises((ValueError, SecurityError)): process_user_input(malicious_input) ``` ## 📝 Melhores Práticas ### 1. Nomenclatura - Arquivos de teste: `test_*.py` ou `*_test.py` - Funções de teste: `test_*` - Classes de teste: `Test*` - Fixtures: nomes descritivos sem prefixo `test_` ### 2. Organização - Um arquivo de teste por módulo - Agrupar testes relacionados em classes - Usar fixtures para setup/teardown - Manter testes independentes ### 3. Assertions ```python # Bom: específico e claro assert result.status == "success" assert len(result.items) == 3 assert result.total > 0 # Evitar: muito genérico assert result ``` ### 4. Documentação ```python def test_complex_scenario(): """Teste cenário complexo de processamento de dados. Este teste verifica se o sistema consegue processar corretamente um dataset com múltiplas anomalias. """ # Given: dados com anomalias data = create_anomalous_dataset() # When: processamento é executado result = processor.process(data) # Then: anomalias são detectadas e tratadas assert result.anomalies_detected > 0 assert result.status == "processed_with_warnings" ``` ## 🔧 Troubleshooting ### Problemas Comuns 1. **Testes lentos**: Use marcador `@pytest.mark.slow` e execute com `make test-fast` 2. **Falhas intermitentes**: Verifique dependências externas e use mocks 3. **Problemas de importação**: Verifique `sys.path` no `conftest.py` 4. **Fixtures não encontradas**: Verifique se estão no `conftest.py` correto ### Debug de Testes ```bash # Executar com output detalhado pytest -v -s # Executar com debugger pytest --pdb # Executar teste específico com debug pytest tests/unit/test_module.py::test_function -v -s --pdb ``` ### Logs durante Testes ```python import logging def test_with_logging(caplog): """Teste com captura de logs.""" with caplog.at_level(logging.INFO): function_that_logs() assert "Expected log message" in caplog.text assert caplog.records[0].levelname == "INFO" ``` ## 📚 Recursos Adicionais - [Documentação do pytest](https://docs.pytest.org/) - [pytest-cov](https://pytest-cov.readthedocs.io/) - [pytest-mock](https://pytest-mock.readthedocs.io/) - [pytest-benchmark](https://pytest-benchmark.readthedocs.io/) - [Factory Boy](https://factoryboy.readthedocs.io/) - [Faker](https://faker.readthedocs.io/) ## 🤝 Contribuindo Ao adicionar novos testes: 1. Siga os padrões estabelecidos 2. Adicione marcadores apropriados 3. Documente testes complexos 4. Mantenha cobertura > 80% 5. Execute `make pre-commit` antes de commitar --- **Nota**: Esta documentação é mantida junto com o código. Mantenha-a atualizada conforme o sistema evolui.