Add unit tests for the StatsMailer extension (#7013)

This commit is contained in:
M Ikram Ullah Khan 2025-09-01 14:43:57 +05:00 committed by GitHub
parent 3ee4a52aa1
commit 00b2be0943
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 83 additions and 1 deletions

View File

@ -40,7 +40,7 @@ class StatsMailer:
return o
def spider_closed(self, spider: Spider) -> Deferred[None] | None:
spider_stats = self.stats.get_stats(spider)
spider_stats = self.stats.get_stats()
body = "Global stats\n\n"
body += "\n".join(f"{k:<50} : {v}" for k, v in self.stats.get_stats().items())
body += f"\n\n{spider.name} stats\n\n"

View File

@ -0,0 +1,82 @@
from unittest.mock import MagicMock
import pytest
from scrapy import signals
from scrapy.exceptions import NotConfigured
from scrapy.extensions import statsmailer
from scrapy.mail import MailSender
from scrapy.signalmanager import SignalManager
from scrapy.statscollectors import StatsCollector
from scrapy.utils.spider import DefaultSpider
@pytest.fixture
def dummy_stats():
class DummyStats(StatsCollector):
def __init__(self):
# pylint: disable=super-init-not-called
self._stats = {"global_item_scraped_count": 42}
def get_stats(self):
return {"item_scraped_count": 10, **self._stats}
return DummyStats()
def test_from_crawler_without_recipients_raises_notconfigured():
crawler = MagicMock()
crawler.settings.getlist.return_value = []
crawler.stats = MagicMock()
with pytest.raises(NotConfigured):
statsmailer.StatsMailer.from_crawler(crawler)
def test_from_crawler_with_recipients_initializes_extension(dummy_stats, monkeypatch):
crawler = MagicMock()
crawler.settings.getlist.return_value = ["test@example.com"]
crawler.stats = dummy_stats
crawler.signals = SignalManager(crawler)
mailer = MagicMock(spec=MailSender)
monkeypatch.setattr(statsmailer.MailSender, "from_crawler", lambda _: mailer)
ext = statsmailer.StatsMailer.from_crawler(crawler)
assert isinstance(ext, statsmailer.StatsMailer)
assert ext.recipients == ["test@example.com"]
assert ext.mail is mailer
def test_from_crawler_connects_spider_closed_signal(dummy_stats, monkeypatch):
crawler = MagicMock()
crawler.settings.getlist.return_value = ["test@example.com"]
crawler.stats = dummy_stats
crawler.signals = SignalManager(crawler)
mailer = MagicMock(spec=MailSender)
monkeypatch.setattr(statsmailer.MailSender, "from_crawler", lambda _: mailer)
statsmailer.StatsMailer.from_crawler(crawler)
connected = crawler.signals.send_catch_log(
signals.spider_closed, spider=DefaultSpider(name="dummy")
)
assert connected is not None
def test_spider_closed_sends_email(dummy_stats):
recipients = ["test@example.com"]
mail = MagicMock(spec=MailSender)
ext = statsmailer.StatsMailer(dummy_stats, recipients, mail)
spider = DefaultSpider(name="dummy")
ext.spider_closed(spider)
args, kwargs = mail.send.call_args
to, subject, body = args
assert to == recipients
assert "Scrapy stats for: dummy" in subject
assert "global_item_scraped_count" in body
assert "item_scraped_count" in body