Repository navigation
Expand file tree
/
Copy pathtest_py_downloading_img.py
More file actions
174 lines (148 loc) · 7.17 KB
/
Copy pathtest_py_downloading_img.py
File metadata and controls
174 lines (148 loc) · 7.17 KB
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
import unittest
import os
import shutil
from unittest.mock import patch, MagicMock
from PyDownloadingIMG import WebsiteImageDownloader
from urllib.parse import urlparse
class TestWebsiteImageDownloader(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Создаем тестовую директорию
cls.test_dir = "test_downloads"
os.makedirs(cls.test_dir, exist_ok=True)
# Тестовый URL
cls.test_url = "http://example.com"
@classmethod
def tearDownClass(cls):
# Удаляем тестовую директорию
shutil.rmtree(cls.test_dir)
def setUp(self):
# Создаем экземпляр класса для каждого теста
self.downloader = WebsiteImageDownloader(
base_url=self.test_url,
output_folder=self.test_dir,
max_pages=10,
max_threads=2
)
def test_init(self):
"""Тест инициализации класса"""
self.assertEqual(self.downloader.base_url, self.test_url)
self.assertEqual(self.downloader.output_folder, self.test_dir)
self.assertEqual(self.downloader.max_pages, 10)
self.assertEqual(self.downloader.max_threads, 2)
self.assertEqual(urlparse(self.downloader.base_url).netloc, "example.com")
self.assertTrue(os.path.exists(self.test_dir))
def test_is_valid_url(self):
"""Тест проверки валидности URL"""
# Валидные URL
self.assertTrue(self.downloader.is_valid_url("http://example.com/page"))
self.assertTrue(self.downloader.is_valid_url("https://example.com/page"))
# Невалидные URL
self.assertFalse(self.downloader.is_valid_url("http://other.com/page")) # другой домен
self.assertFalse(self.downloader.is_valid_url("javascript:void(0)")) # javascript
self.assertFalse(self.downloader.is_valid_url("mailto:test@example.com")) # mailto
self.assertFalse(self.downloader.is_valid_url("#anchor")) # якорь
# После посещения URL должен стать невалидным
test_url = "http://example.com/test"
self.assertTrue(self.downloader.is_valid_url(test_url))
self.downloader.visited_urls.add(test_url)
self.assertFalse(self.downloader.is_valid_url(test_url))
@patch('PyDownloadingIMG.requests.get')
def test_get_all_links(self, mock_get):
"""Тест извлечения ссылок со страницы"""
# Мокаем ответ сервера
mock_response = MagicMock()
mock_response.text = """
<html>
<body>
<a href="/page1">Page 1</a>
<a href="http://example.com/page2">Page 2</a>
<a href="http://other.com/page3">Page 3</a>
<a href="javascript:void(0)">JS Link</a>
</body>
</html>
"""
mock_get.return_value = mock_response
links = self.downloader.get_all_links("http://example.com")
# Должны вернуться только ссылки на тот же домен
expected_links = {
"http://example.com/page1",
"http://example.com/page2"
}
self.assertEqual(links, expected_links)
@patch('PyDownloadingIMG.requests.get')
def test_download_image(self, mock_get):
"""Тест загрузки изображения"""
# Мокаем ответ сервера для изображения
mock_response = MagicMock()
mock_response.iter_content.return_value = [b'test', b'data']
mock_response.raise_for_status.return_value = None
mock_get.return_value = mock_response
# Тестируем загрузку
img_url = "http://example.com/image.jpg"
self.downloader.download_image(img_url)
# Проверяем, что файл создан
expected_file = os.path.join(self.test_dir, "image.jpg")
self.assertTrue(os.path.exists(expected_file))
self.assertIn(img_url, self.downloader.downloaded_images)
# Проверяем, что повторная загрузка не происходит
with patch('builtins.open') as mock_open:
self.downloader.download_image(img_url)
mock_open.assert_not_called()
@patch('PyDownloadingIMG.requests.get')
def test_process_page(self, mock_get):
"""Тест обработки страницы"""
# Мокаем ответ сервера
mock_response = MagicMock()
mock_response.text = """
<html>
<body>
<img src="/image1.jpg">
<img src="http://example.com/image2.jpg">
<a href="/page1">Page 1</a>
</body>
</html>
"""
mock_response.raise_for_status.return_value = None
mock_get.return_value = mock_response
# Мокаем ThreadPoolExecutor и его методы
with patch('PyDownloadingIMG.ThreadPoolExecutor') as mock_executor:
mock_map = MagicMock()
mock_executor.return_value.__enter__.return_value.map = mock_map
new_links = self.downloader.process_page("http://example.com")
# Проверяем, что изображения были переданы в ThreadPoolExecutor
args, _ = mock_map.call_args
actual_image_urls = list(args[1]) # args[0] - функция, args[1] - итерабельный объект с URL
expected_image_urls = [
"http://example.com/image1.jpg",
"http://example.com/image2.jpg"
]
self.assertCountEqual(actual_image_urls, expected_image_urls)
self.assertEqual(new_links, {"http://example.com/page1"})
self.assertIn("http://example.com", self.downloader.visited_urls)
@patch('PyDownloadingIMG.requests.get')
@patch('PyDownloadingIMG.ThreadPoolExecutor')
def test_crawl_website(self, mock_executor, mock_get):
"""Тест обхода сайта"""
# Настраиваем моки
mock_response = MagicMock()
mock_response.text = """
<html>
<body>
<img src="/image1.jpg">
<a href="/page1">Page 1</a>
<a href="/page2">Page 2</a>
</body>
</html>
"""
mock_get.return_value = mock_response
# Мокаем executor
mock_executor.return_value.__enter__.return_value.map.return_value = None
# Запускаем обход
self.downloader.crawl_website()
# Проверяем, что все страницы были посещены
self.assertIn("http://example.com", self.downloader.visited_urls)
self.assertIn("http://example.com/page1", self.downloader.visited_urls)
self.assertIn("http://example.com/page2", self.downloader.visited_urls)
if __name__ == "__main__":
unittest.main()