From d32487f2edad0120c7eb4efc86ff53caa78ef114 Mon Sep 17 00:00:00 2001 From: Henry Walshaw Date: Mon, 8 Jul 2019 13:49:56 +1000 Subject: [PATCH] Separate extensions as their own files Give each extension its own test file. Primarily this is done to make it easier to add some fixtures and extend the geo tests. --- tests/test_extension.py | 300 ---------------------- tests/test_extensions/__init__.py | 0 tests/test_extensions/test_dc.py | 31 +++ tests/test_extensions/test_geo.py | 29 +++ tests/test_extensions/test_media.py | 83 ++++++ tests/test_extensions/test_podcast.py | 96 +++++++ tests/test_extensions/test_syndication.py | 40 +++ tests/test_extensions/test_torrent.py | 38 +++ 8 files changed, 317 insertions(+), 300 deletions(-) delete mode 100644 tests/test_extension.py create mode 100644 tests/test_extensions/__init__.py create mode 100644 tests/test_extensions/test_dc.py create mode 100644 tests/test_extensions/test_geo.py create mode 100644 tests/test_extensions/test_media.py create mode 100644 tests/test_extensions/test_podcast.py create mode 100644 tests/test_extensions/test_syndication.py create mode 100644 tests/test_extensions/test_torrent.py diff --git a/tests/test_extension.py b/tests/test_extension.py deleted file mode 100644 index db85c08..0000000 --- a/tests/test_extension.py +++ /dev/null @@ -1,300 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -Tests for extensions -""" - -import unittest - -from lxml import etree - -from feedgen.feed import FeedGenerator - - -class TestExtensionSyndication(unittest.TestCase): - - SYN_NS = {'sy': 'http://purl.org/rss/1.0/modules/syndication/'} - - def setUp(self): - self.fg = FeedGenerator() - self.fg.load_extension('syndication') - self.fg.title('title') - self.fg.link(href='http://example.com', rel='self') - self.fg.description('description') - - def test_update_period(self): - for period_type in ('hourly', 'daily', 'weekly', 'monthly', 'yearly'): - self.fg.syndication.update_period(period_type) - root = etree.fromstring(self.fg.rss_str()) - a = root.xpath('/rss/channel/sy:UpdatePeriod', - namespaces=self.SYN_NS) - assert a[0].text == period_type - - def test_update_frequency(self): - for frequency in (1, 100, 2000, 100000): - self.fg.syndication.update_frequency(frequency) - root = etree.fromstring(self.fg.rss_str()) - a = root.xpath('/rss/channel/sy:UpdateFrequency', - namespaces=self.SYN_NS) - assert a[0].text == str(frequency) - - def test_update_base(self): - base = '2000-01-01T12:00+00:00' - self.fg.syndication.update_base(base) - root = etree.fromstring(self.fg.rss_str()) - a = root.xpath('/rss/channel/sy:UpdateBase', namespaces=self.SYN_NS) - assert a[0].text == base - - -class TestExtensionPodcast(unittest.TestCase): - - def setUp(self): - self.fg = FeedGenerator() - self.fg.load_extension('podcast') - self.fg.title('title') - self.fg.link(href='http://example.com', rel='self') - self.fg.description('description') - - def test_category_new(self): - self.fg.podcast.itunes_category([{'cat': 'Technology', - 'sub': 'Podcasting'}]) - self.fg.podcast.itunes_explicit('no') - self.fg.podcast.itunes_complete('no') - self.fg.podcast.itunes_new_feed_url('http://example.com/new-feed.rss') - self.fg.podcast.itunes_owner('John Doe', 'john@example.com') - ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} - root = etree.fromstring(self.fg.rss_str()) - cat = root.xpath('/rss/channel/itunes:category/@text', namespaces=ns) - scat = root.xpath('/rss/channel/itunes:category/itunes:category/@text', - namespaces=ns) - assert cat[0] == 'Technology' - assert scat[0] == 'Podcasting' - - def test_category(self): - self.fg.podcast.itunes_category('Technology', 'Podcasting') - self.fg.podcast.itunes_explicit('no') - self.fg.podcast.itunes_complete('no') - self.fg.podcast.itunes_new_feed_url('http://example.com/new-feed.rss') - self.fg.podcast.itunes_owner('John Doe', 'john@example.com') - ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} - root = etree.fromstring(self.fg.rss_str()) - cat = root.xpath('/rss/channel/itunes:category/@text', namespaces=ns) - scat = root.xpath('/rss/channel/itunes:category/itunes:category/@text', - namespaces=ns) - assert cat[0] == 'Technology' - assert scat[0] == 'Podcasting' - - def test_podcastItems(self): - fg = self.fg - fg.podcast.itunes_author('Lars Kiesow') - fg.podcast.itunes_block('x') - fg.podcast.itunes_complete(False) - fg.podcast.itunes_explicit('no') - fg.podcast.itunes_image('x.png') - fg.podcast.itunes_subtitle('x') - fg.podcast.itunes_summary('x') - assert fg.podcast.itunes_author() == 'Lars Kiesow' - assert fg.podcast.itunes_block() == 'x' - assert fg.podcast.itunes_complete() == 'no' - assert fg.podcast.itunes_explicit() == 'no' - assert fg.podcast.itunes_image() == 'x.png' - assert fg.podcast.itunes_subtitle() == 'x' - assert fg.podcast.itunes_summary() == 'x' - - # Check that we have the item in the resulting XML - ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} - root = etree.fromstring(self.fg.rss_str()) - author = root.xpath('/rss/channel/itunes:author/text()', namespaces=ns) - assert author == ['Lars Kiesow'] - - def test_podcastEntryItems(self): - fe = self.fg.add_item() - fe.title('y') - fe.podcast.itunes_author('Lars Kiesow') - fe.podcast.itunes_block('x') - fe.podcast.itunes_duration('00:01:30') - fe.podcast.itunes_explicit('no') - fe.podcast.itunes_image('x.png') - fe.podcast.itunes_is_closed_captioned('yes') - fe.podcast.itunes_order(1) - fe.podcast.itunes_subtitle('x') - fe.podcast.itunes_summary('x') - assert fe.podcast.itunes_author() == 'Lars Kiesow' - assert fe.podcast.itunes_block() == 'x' - assert fe.podcast.itunes_duration() == '00:01:30' - assert fe.podcast.itunes_explicit() == 'no' - assert fe.podcast.itunes_image() == 'x.png' - assert fe.podcast.itunes_is_closed_captioned() - assert fe.podcast.itunes_order() == 1 - assert fe.podcast.itunes_subtitle() == 'x' - assert fe.podcast.itunes_summary() == 'x' - - # Check that we have the item in the resulting XML - ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} - root = etree.fromstring(self.fg.rss_str()) - author = root.xpath('/rss/channel/item/itunes:author/text()', - namespaces=ns) - assert author == ['Lars Kiesow'] - - -class TestExtensionGeo(unittest.TestCase): - - def setUp(self): - self.fg = FeedGenerator() - self.fg.load_extension('geo') - self.fg.title('title') - self.fg.link(href='http://example.com', rel='self') - self.fg.description('description') - - def test_geoEntryItems(self): - fe = self.fg.add_item() - fe.title('y') - fe.geo.point('42.36 -71.05') - - assert fe.geo.point() == '42.36 -71.05' - - # Check that we have the item in the resulting XML - ns = {'georss': 'http://www.georss.org/georss'} - root = etree.fromstring(self.fg.rss_str()) - point = root.xpath('/rss/channel/item/georss:point/text()', - namespaces=ns) - assert point == ['42.36 -71.05'] - - -class TestExtensionDc(unittest.TestCase): - - def setUp(self): - self.fg = FeedGenerator() - self.fg.load_extension('dc') - self.fg.title('title') - self.fg.link(href='http://example.com', rel='self') - self.fg.description('description') - - def test_entryLoadExtension(self): - fe = self.fg.add_item() - try: - fe.load_extension('dc') - except ImportError: - pass # Extension already loaded - - def test_elements(self): - for method in dir(self.fg.dc): - if method.startswith('dc_'): - m = getattr(self.fg.dc, method) - m(method) - assert m() == [method] - - self.fg.id('123') - assert self.fg.atom_str() - assert self.fg.rss_str() - - -class TestExtensionTorrent(unittest.TestCase): - - def setUp(self): - self.fg = FeedGenerator() - self.fg.load_extension('torrent') - self.fg.title('title') - self.fg.link(href='http://example.com', rel='self') - self.fg.description('description') - - def test_podcastEntryItems(self): - fe = self.fg.add_item() - fe.title('y') - fe.torrent.filename('file.xy') - fe.torrent.infohash('123') - fe.torrent.contentlength('23') - fe.torrent.seeds('1') - fe.torrent.peers('2') - fe.torrent.verified('1') - assert fe.torrent.filename() == 'file.xy' - assert fe.torrent.infohash() == '123' - assert fe.torrent.contentlength() == '23' - assert fe.torrent.seeds() == '1' - assert fe.torrent.peers() == '2' - assert fe.torrent.verified() == '1' - - # Check that we have the item in the resulting XML - ns = {'torrent': 'http://xmlns.ezrss.it/0.1/dtd/'} - root = etree.fromstring(self.fg.rss_str()) - filename = root.xpath('/rss/channel/item/torrent:filename/text()', - namespaces=ns) - assert filename == ['file.xy'] - - -class TestExtensionMedia(unittest.TestCase): - - def setUp(self): - self.fg = FeedGenerator() - self.fg.load_extension('media') - self.fg.id('id') - self.fg.title('title') - self.fg.link(href='http://example.com', rel='self') - self.fg.description('description') - - def test_media_content(self): - fe = self.fg.add_item() - fe.id('id') - fe.title('title') - fe.content('content') - fe.media.content(url='file1.xy') - fe.media.content(url='file2.xy') - fe.media.content(url='file1.xy', group=2) - fe.media.content(url='file2.xy', group=2) - fe.media.content(url='file.xy', group=None) - - ns = {'media': 'http://search.yahoo.com/mrss/', - 'a': 'http://www.w3.org/2005/Atom'} - # Check that we have the item in the resulting RSS - root = etree.fromstring(self.fg.rss_str()) - url = root.xpath('/rss/channel/item/media:group/media:content[1]/@url', - namespaces=ns) - assert url == ['file1.xy', 'file1.xy'] - - # There is one without a group - url = root.xpath('/rss/channel/item/media:content[1]/@url', - namespaces=ns) - assert url == ['file.xy'] - - # Check that we have the item in the resulting Atom feed - root = etree.fromstring(self.fg.atom_str()) - url = root.xpath('/a:feed/a:entry/media:group/media:content[1]/@url', - namespaces=ns) - assert url == ['file1.xy', 'file1.xy'] - - fe.media.content(content=[], replace=True) - assert fe.media.content() == [] - - def test_media_thumbnail(self): - fe = self.fg.add_item() - fe.id('id') - fe.title('title') - fe.content('content') - fe.media.thumbnail(url='file1.xy') - fe.media.thumbnail(url='file2.xy') - fe.media.thumbnail(url='file1.xy', group=2) - fe.media.thumbnail(url='file2.xy', group=2) - fe.media.thumbnail(url='file.xy', group=None) - - ns = {'media': 'http://search.yahoo.com/mrss/', - 'a': 'http://www.w3.org/2005/Atom'} - # Check that we have the item in the resulting RSS - root = etree.fromstring(self.fg.rss_str()) - url = root.xpath( - '/rss/channel/item/media:group/media:thumbnail[1]/@url', - namespaces=ns) - assert url == ['file1.xy', 'file1.xy'] - - # There is one without a group - url = root.xpath('/rss/channel/item/media:thumbnail[1]/@url', - namespaces=ns) - assert url == ['file.xy'] - - # Check that we have the item in the resulting Atom feed - root = etree.fromstring(self.fg.atom_str()) - url = root.xpath('/a:feed/a:entry/media:group/media:thumbnail[1]/@url', - namespaces=ns) - assert url == ['file1.xy', 'file1.xy'] - - fe.media.thumbnail(thumbnail=[], replace=True) - assert fe.media.thumbnail() == [] diff --git a/tests/test_extensions/__init__.py b/tests/test_extensions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_extensions/test_dc.py b/tests/test_extensions/test_dc.py new file mode 100644 index 0000000..1623804 --- /dev/null +++ b/tests/test_extensions/test_dc.py @@ -0,0 +1,31 @@ +import unittest + +from feedgen.feed import FeedGenerator + + +class TestExtensionDc(unittest.TestCase): + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('dc') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_entryLoadExtension(self): + fe = self.fg.add_item() + try: + fe.load_extension('dc') + except ImportError: + pass # Extension already loaded + + def test_elements(self): + for method in dir(self.fg.dc): + if method.startswith('dc_'): + m = getattr(self.fg.dc, method) + m(method) + assert m() == [method] + + self.fg.id('123') + assert self.fg.atom_str() + assert self.fg.rss_str() diff --git a/tests/test_extensions/test_geo.py b/tests/test_extensions/test_geo.py new file mode 100644 index 0000000..6665a74 --- /dev/null +++ b/tests/test_extensions/test_geo.py @@ -0,0 +1,29 @@ +import unittest + +from lxml import etree + +from feedgen.feed import FeedGenerator + + +class TestExtensionGeo(unittest.TestCase): + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('geo') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_geoEntryItems(self): + fe = self.fg.add_item() + fe.title('y') + fe.geo.point('42.36 -71.05') + + assert fe.geo.point() == '42.36 -71.05' + + # Check that we have the item in the resulting XML + ns = {'georss': 'http://www.georss.org/georss'} + root = etree.fromstring(self.fg.rss_str()) + point = root.xpath('/rss/channel/item/georss:point/text()', + namespaces=ns) + assert point == ['42.36 -71.05'] diff --git a/tests/test_extensions/test_media.py b/tests/test_extensions/test_media.py new file mode 100644 index 0000000..7fd9e40 --- /dev/null +++ b/tests/test_extensions/test_media.py @@ -0,0 +1,83 @@ +import unittest + +from lxml import etree + +from feedgen.feed import FeedGenerator + + +class TestExtensionMedia(unittest.TestCase): + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('media') + self.fg.id('id') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_media_content(self): + fe = self.fg.add_item() + fe.id('id') + fe.title('title') + fe.content('content') + fe.media.content(url='file1.xy') + fe.media.content(url='file2.xy') + fe.media.content(url='file1.xy', group=2) + fe.media.content(url='file2.xy', group=2) + fe.media.content(url='file.xy', group=None) + + ns = {'media': 'http://search.yahoo.com/mrss/', + 'a': 'http://www.w3.org/2005/Atom'} + # Check that we have the item in the resulting RSS + root = etree.fromstring(self.fg.rss_str()) + url = root.xpath('/rss/channel/item/media:group/media:content[1]/@url', + namespaces=ns) + assert url == ['file1.xy', 'file1.xy'] + + # There is one without a group + url = root.xpath('/rss/channel/item/media:content[1]/@url', + namespaces=ns) + assert url == ['file.xy'] + + # Check that we have the item in the resulting Atom feed + root = etree.fromstring(self.fg.atom_str()) + url = root.xpath('/a:feed/a:entry/media:group/media:content[1]/@url', + namespaces=ns) + assert url == ['file1.xy', 'file1.xy'] + + fe.media.content(content=[], replace=True) + assert fe.media.content() == [] + + def test_media_thumbnail(self): + fe = self.fg.add_item() + fe.id('id') + fe.title('title') + fe.content('content') + fe.media.thumbnail(url='file1.xy') + fe.media.thumbnail(url='file2.xy') + fe.media.thumbnail(url='file1.xy', group=2) + fe.media.thumbnail(url='file2.xy', group=2) + fe.media.thumbnail(url='file.xy', group=None) + + ns = {'media': 'http://search.yahoo.com/mrss/', + 'a': 'http://www.w3.org/2005/Atom'} + # Check that we have the item in the resulting RSS + root = etree.fromstring(self.fg.rss_str()) + url = root.xpath( + '/rss/channel/item/media:group/media:thumbnail[1]/@url', + namespaces=ns) + assert url == ['file1.xy', 'file1.xy'] + + # There is one without a group + url = root.xpath('/rss/channel/item/media:thumbnail[1]/@url', + namespaces=ns) + assert url == ['file.xy'] + + # Check that we have the item in the resulting Atom feed + root = etree.fromstring(self.fg.atom_str()) + url = root.xpath('/a:feed/a:entry/media:group/media:thumbnail[1]/@url', + namespaces=ns) + assert url == ['file1.xy', 'file1.xy'] + + fe.media.thumbnail(thumbnail=[], replace=True) + assert fe.media.thumbnail() == [] diff --git a/tests/test_extensions/test_podcast.py b/tests/test_extensions/test_podcast.py new file mode 100644 index 0000000..a41c96c --- /dev/null +++ b/tests/test_extensions/test_podcast.py @@ -0,0 +1,96 @@ +import unittest + +from lxml import etree + +from feedgen.feed import FeedGenerator + + +class TestExtensionPodcast(unittest.TestCase): + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('podcast') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_category_new(self): + self.fg.podcast.itunes_category([{'cat': 'Technology', + 'sub': 'Podcasting'}]) + self.fg.podcast.itunes_explicit('no') + self.fg.podcast.itunes_complete('no') + self.fg.podcast.itunes_new_feed_url('http://example.com/new-feed.rss') + self.fg.podcast.itunes_owner('John Doe', 'john@example.com') + ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} + root = etree.fromstring(self.fg.rss_str()) + cat = root.xpath('/rss/channel/itunes:category/@text', namespaces=ns) + scat = root.xpath('/rss/channel/itunes:category/itunes:category/@text', + namespaces=ns) + assert cat[0] == 'Technology' + assert scat[0] == 'Podcasting' + + def test_category(self): + self.fg.podcast.itunes_category('Technology', 'Podcasting') + self.fg.podcast.itunes_explicit('no') + self.fg.podcast.itunes_complete('no') + self.fg.podcast.itunes_new_feed_url('http://example.com/new-feed.rss') + self.fg.podcast.itunes_owner('John Doe', 'john@example.com') + ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} + root = etree.fromstring(self.fg.rss_str()) + cat = root.xpath('/rss/channel/itunes:category/@text', namespaces=ns) + scat = root.xpath('/rss/channel/itunes:category/itunes:category/@text', + namespaces=ns) + assert cat[0] == 'Technology' + assert scat[0] == 'Podcasting' + + def test_podcastItems(self): + fg = self.fg + fg.podcast.itunes_author('Lars Kiesow') + fg.podcast.itunes_block('x') + fg.podcast.itunes_complete(False) + fg.podcast.itunes_explicit('no') + fg.podcast.itunes_image('x.png') + fg.podcast.itunes_subtitle('x') + fg.podcast.itunes_summary('x') + assert fg.podcast.itunes_author() == 'Lars Kiesow' + assert fg.podcast.itunes_block() == 'x' + assert fg.podcast.itunes_complete() == 'no' + assert fg.podcast.itunes_explicit() == 'no' + assert fg.podcast.itunes_image() == 'x.png' + assert fg.podcast.itunes_subtitle() == 'x' + assert fg.podcast.itunes_summary() == 'x' + + # Check that we have the item in the resulting XML + ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} + root = etree.fromstring(self.fg.rss_str()) + author = root.xpath('/rss/channel/itunes:author/text()', namespaces=ns) + assert author == ['Lars Kiesow'] + + def test_podcastEntryItems(self): + fe = self.fg.add_item() + fe.title('y') + fe.podcast.itunes_author('Lars Kiesow') + fe.podcast.itunes_block('x') + fe.podcast.itunes_duration('00:01:30') + fe.podcast.itunes_explicit('no') + fe.podcast.itunes_image('x.png') + fe.podcast.itunes_is_closed_captioned('yes') + fe.podcast.itunes_order(1) + fe.podcast.itunes_subtitle('x') + fe.podcast.itunes_summary('x') + assert fe.podcast.itunes_author() == 'Lars Kiesow' + assert fe.podcast.itunes_block() == 'x' + assert fe.podcast.itunes_duration() == '00:01:30' + assert fe.podcast.itunes_explicit() == 'no' + assert fe.podcast.itunes_image() == 'x.png' + assert fe.podcast.itunes_is_closed_captioned() + assert fe.podcast.itunes_order() == 1 + assert fe.podcast.itunes_subtitle() == 'x' + assert fe.podcast.itunes_summary() == 'x' + + # Check that we have the item in the resulting XML + ns = {'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd'} + root = etree.fromstring(self.fg.rss_str()) + author = root.xpath('/rss/channel/item/itunes:author/text()', + namespaces=ns) + assert author == ['Lars Kiesow'] diff --git a/tests/test_extensions/test_syndication.py b/tests/test_extensions/test_syndication.py new file mode 100644 index 0000000..7a187d7 --- /dev/null +++ b/tests/test_extensions/test_syndication.py @@ -0,0 +1,40 @@ +import unittest + +from lxml import etree + +from feedgen.feed import FeedGenerator + + +class TestExtensionSyndication(unittest.TestCase): + + SYN_NS = {'sy': 'http://purl.org/rss/1.0/modules/syndication/'} + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('syndication') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_update_period(self): + for period_type in ('hourly', 'daily', 'weekly', 'monthly', 'yearly'): + self.fg.syndication.update_period(period_type) + root = etree.fromstring(self.fg.rss_str()) + a = root.xpath('/rss/channel/sy:UpdatePeriod', + namespaces=self.SYN_NS) + assert a[0].text == period_type + + def test_update_frequency(self): + for frequency in (1, 100, 2000, 100000): + self.fg.syndication.update_frequency(frequency) + root = etree.fromstring(self.fg.rss_str()) + a = root.xpath('/rss/channel/sy:UpdateFrequency', + namespaces=self.SYN_NS) + assert a[0].text == str(frequency) + + def test_update_base(self): + base = '2000-01-01T12:00+00:00' + self.fg.syndication.update_base(base) + root = etree.fromstring(self.fg.rss_str()) + a = root.xpath('/rss/channel/sy:UpdateBase', namespaces=self.SYN_NS) + assert a[0].text == base diff --git a/tests/test_extensions/test_torrent.py b/tests/test_extensions/test_torrent.py new file mode 100644 index 0000000..e996fde --- /dev/null +++ b/tests/test_extensions/test_torrent.py @@ -0,0 +1,38 @@ +import unittest + +from lxml import etree + +from feedgen.feed import FeedGenerator + + +class TestExtensionTorrent(unittest.TestCase): + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('torrent') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_podcastEntryItems(self): + fe = self.fg.add_item() + fe.title('y') + fe.torrent.filename('file.xy') + fe.torrent.infohash('123') + fe.torrent.contentlength('23') + fe.torrent.seeds('1') + fe.torrent.peers('2') + fe.torrent.verified('1') + assert fe.torrent.filename() == 'file.xy' + assert fe.torrent.infohash() == '123' + assert fe.torrent.contentlength() == '23' + assert fe.torrent.seeds() == '1' + assert fe.torrent.peers() == '2' + assert fe.torrent.verified() == '1' + + # Check that we have the item in the resulting XML + ns = {'torrent': 'http://xmlns.ezrss.it/0.1/dtd/'} + root = etree.fromstring(self.fg.rss_str()) + filename = root.xpath('/rss/channel/item/torrent:filename/text()', + namespaces=ns) + assert filename == ['file.xy']