File size: 10,786 Bytes
b9c68d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
"""Test patterns and best practices examples.

This module demonstrates various testing patterns and best practices
used throughout the test suite.
"""

import pytest
from unittest.mock import Mock, patch, MagicMock, call
from factory import Factory, Faker, SubFactory
import json
from pathlib import Path


class TestPatterns:
    """Examples of different testing patterns."""
    
    def test_basic_unit_test(self):
        """Basic unit test pattern."""
        # Arrange
        input_value = 10
        expected_result = 20
        
        # Act
        result = input_value * 2
        
        # Assert
        assert result == expected_result
    
    def test_with_fixture(self, sample_market_data):
        """Test using fixture data."""
        # Arrange & Act
        symbol = sample_market_data['symbol']
        price = sample_market_data['price']
        
        # Assert
        assert symbol == 'AAPL'
        assert price == 150.0
    
    def test_with_mock(self, mock_market_processor):
        """Test using mock objects."""
        # Arrange
        test_data = {'price': 100}
        
        # Act
        result = mock_market_processor.process_data(test_data)
        
        # Assert
        assert result == {'processed': True}
        mock_market_processor.process_data.assert_called_once_with(test_data)
    
    @patch('src.core.advanced_market_processing.AdvancedMarketProcessor')
    def test_with_patch_decorator(self, mock_processor_class):
        """Test using patch decorator."""
        # Arrange
        mock_instance = Mock()
        mock_instance.analyze_trends.return_value = {'trend': 'bullish'}
        mock_processor_class.return_value = mock_instance
        
        # Act
        from src.core.advanced_market_processing import AdvancedMarketProcessor
        processor = AdvancedMarketProcessor()
        result = processor.analyze_trends()
        
        # Assert
        assert result == {'trend': 'bullish'}
        mock_processor_class.assert_called_once()
    
    def test_with_context_manager_patch(self):
        """Test using patch as context manager."""
        with patch('builtins.open', create=True) as mock_open:
            mock_open.return_value.__enter__.return_value.read.return_value = 'test data'
            
            # Act
            with open('test_file.txt', 'r') as f:
                content = f.read()
            
            # Assert
            assert content == 'test data'
            mock_open.assert_called_once_with('test_file.txt', 'r')
    
    def test_exception_handling(self):
        """Test exception handling patterns."""
        # Test that exception is raised
        with pytest.raises(ValueError, match="Invalid input"):
            raise ValueError("Invalid input")
        
        # Test that no exception is raised
        try:
            result = 1 + 1
            assert result == 2
        except Exception as e:
            pytest.fail(f"Unexpected exception: {e}")
    
    @pytest.mark.parametrize("input_value,expected", [
        (1, 2),
        (2, 4),
        (3, 6),
        (0, 0),
        (-1, -2)
    ])
    def test_parametrized(self, input_value, expected):
        """Parametrized test pattern."""
        result = input_value * 2
        assert result == expected
    
    @pytest.mark.slow
    def test_slow_operation(self):
        """Test marked as slow."""
        import time
        time.sleep(0.1)  # Simulate slow operation
        assert True
    
    def test_with_caplog(self, caplog):
        """Test log capture pattern."""
        import logging
        
        logger = logging.getLogger('test_logger')
        logger.info('Test log message')
        
        assert 'Test log message' in caplog.text
        assert caplog.records[0].levelname == 'INFO'
    
    def test_with_temp_file(self, tmp_path):
        """Test with temporary file."""
        # Create temporary file
        test_file = tmp_path / "test.txt"
        test_file.write_text("test content")
        
        # Test
        content = test_file.read_text()
        assert content == "test content"
        assert test_file.exists()
    
    def test_async_function(self):
        """Test async function pattern."""
        import asyncio
        
        async def async_function():
            await asyncio.sleep(0.01)
            return "async result"
        
        # Run async test
        result = asyncio.run(async_function())
        assert result == "async result"
    
    def test_mock_multiple_calls(self):
        """Test mock with multiple calls."""
        mock_func = Mock()
        mock_func.side_effect = [1, 2, 3]
        
        # Multiple calls
        assert mock_func() == 1
        assert mock_func() == 2
        assert mock_func() == 3
        
        # Verify call count
        assert mock_func.call_count == 3
        
        # Verify call arguments
        expected_calls = [call(), call(), call()]
        mock_func.assert_has_calls(expected_calls)
    
    def test_mock_side_effect_exception(self):
        """Test mock raising exception."""
        mock_func = Mock()
        mock_func.side_effect = ValueError("Mock error")
        
        with pytest.raises(ValueError, match="Mock error"):
            mock_func()
    
    def test_json_data_loading(self, test_data_dir):
        """Test loading JSON test data."""
        json_file = test_data_dir / "sample_market_data.json"
        
        if json_file.exists():
            with open(json_file) as f:
                data = json.load(f)
            
            assert 'market_data' in data
            assert len(data['market_data']) > 0
        else:
            pytest.skip("Test data file not found")


class TestFactoryPatterns:
    """Examples using Factory Boy for test data generation."""
    
    class MarketDataFactory(Factory):
        """Factory for generating market data."""
        
        class Meta:
            model = dict
        
        symbol = Faker('random_element', elements=['AAPL', 'GOOGL', 'MSFT', 'AMZN'])
        price = Faker('pyfloat', left_digits=3, right_digits=2, positive=True)
        volume = Faker('pyint', min_value=100000, max_value=10000000)
        timestamp = Faker('date_time_this_year')
    
    def test_with_factory(self):
        """Test using factory-generated data."""
        market_data = self.MarketDataFactory()
        
        assert 'symbol' in market_data
        assert 'price' in market_data
        assert 'volume' in market_data
        assert market_data['price'] > 0
        assert market_data['volume'] > 0
    
    def test_factory_batch(self):
        """Test generating batch data with factory."""
        batch_data = self.MarketDataFactory.build_batch(5)
        
        assert len(batch_data) == 5
        for item in batch_data:
            assert 'symbol' in item
            assert 'price' in item


class TestIntegrationPatterns:
    """Integration test patterns."""
    
    @pytest.mark.integration
    def test_database_integration(self, database_connection):
        """Integration test with database."""
        cursor = database_connection.cursor()
        
        # Insert test data
        cursor.execute(
            "INSERT INTO logs (timestamp, level, message) VALUES (?, ?, ?)",
            ('2024-01-01 10:00:00', 'INFO', 'Test message')
        )
        database_connection.commit()
        
        # Query data
        cursor.execute("SELECT * FROM logs WHERE message = ?", ('Test message',))
        result = cursor.fetchone()
        
        assert result is not None
        assert result['level'] == 'INFO'
    
    @pytest.mark.integration
    def test_api_integration(self, mock_external_apis):
        """Integration test with external APIs."""
        mock_yf, mock_requests = mock_external_apis
        
        # Test would use actual API calls here
        # but they're mocked for testing
        import yfinance as yf
        data = yf.download('AAPL')
        
        assert not data.empty
        mock_yf.assert_called_once_with('AAPL')


class TestPerformancePatterns:
    """Performance testing patterns."""
    
    @pytest.mark.performance
    def test_performance_benchmark(self, benchmark):
        """Performance test using pytest-benchmark."""
        def function_to_test():
            return sum(range(1000))
        
        result = benchmark(function_to_test)
        assert result == 499500
    
    @pytest.mark.performance
    def test_memory_usage(self):
        """Test memory usage patterns."""
        import psutil
        import os
        
        process = psutil.Process(os.getpid())
        initial_memory = process.memory_info().rss
        
        # Perform memory-intensive operation
        large_list = [i for i in range(100000)]
        
        final_memory = process.memory_info().rss
        memory_increase = final_memory - initial_memory
        
        # Assert memory increase is reasonable
        assert memory_increase > 0
        assert len(large_list) == 100000


class TestSecurityPatterns:
    """Security testing patterns."""
    
    @pytest.mark.security
    def test_input_validation(self):
        """Test input validation patterns."""
        # Test SQL injection prevention
        malicious_input = "'; DROP TABLE users; --"
        
        # Your validation function should handle this
        # This is just an example pattern
        def validate_input(user_input):
            if any(char in user_input for char in [';', '--', 'DROP', 'DELETE']):
                raise ValueError("Invalid input detected")
            return user_input
        
        with pytest.raises(ValueError, match="Invalid input detected"):
            validate_input(malicious_input)
    
    @pytest.mark.security
    def test_sensitive_data_handling(self):
        """Test sensitive data handling."""
        # Test that sensitive data is not logged
        sensitive_data = "password123"
        
        # Mock logger to verify sensitive data is not logged
        with patch('logging.getLogger') as mock_logger:
            mock_log_instance = Mock()
            mock_logger.return_value = mock_log_instance
            
            # Function that should not log sensitive data
            def process_login(password):
                logger = mock_logger()
                logger.info("Login attempt")
                # Should NOT log the password
                return len(password) > 0
            
            result = process_login(sensitive_data)
            
            assert result is True
            # Verify password was not logged
            logged_calls = mock_log_instance.info.call_args_list
            for call_args in logged_calls:
                assert sensitive_data not in str(call_args)