Update sitemap tests

- add [sitemap] env to tox.ini
- add pytest and pytest-cov config to tox.ini
- create sitemap/test-requirements.txt
- move tests from test_items.py to test_sitemap_file.py
- fix broken sitemap tests
- add newton to list of old releases in sitemap_file.py
- ignore flake8 H101 as it returns false positives for Sphinx conf.py
- fix minor style issues

Change-Id: I22c018149b2eefde6ca5c38c22ac06886fe9a7a8
This commit is contained in:
Brian Moss 2017-04-06 14:40:51 +10:00
parent efdab278fc
commit 031f06f271
9 changed files with 76 additions and 55 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ eggs
sdist
# Unit test / coverage reports
.cache
.coverage
.tox
.testrepository

View File

@ -69,7 +69,7 @@ class ExportSitemap(object):
def spider_opened(self, spider):
output = open(os.path.join(os.getcwd(), 'sitemap_%s.xml'
% spider.domain), 'w')
% spider.domain), 'w')
self.files[spider] = output
self.exporter = SitemapItemExporter(output, item_element='url',
root_element='urlset')
@ -80,7 +80,7 @@ class ExportSitemap(object):
output = self.files.pop(spider)
output.close()
tree = lxml.etree.parse(os.path.join(os.getcwd(), "sitemap_%s.xml"
% spider.domain))
% spider.domain))
with open(os.path.join(os.getcwd(), "sitemap_%s.xml" % spider.domain),
'w') as pretty:
pretty.write(lxml.etree.tostring(tree, pretty_print=True))

View File

@ -41,7 +41,8 @@ class SitemapSpider(spiders.CrawlSpider):
'juno',
'kilo',
'liberty',
'mitaka'
'mitaka',
'newton'
]])
rules = [

View File

@ -0,0 +1,8 @@
# Hacking already pins down pep8, pyflakes and flake8
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
pytest>=3.0.7 # MIT
pytest-cov>=2.4.0 # BSD
# mock object framework
mock>=2.0 # BSD

View File

@ -1,37 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from sitemap.generator import items
import unittest
class TestSitemapItem(unittest.TestCase):
def test_class_type(self):
self.assertTrue(type(items.SitemapItem) is items.scrapy.item.ItemMeta)
def test_class_supports_fields(self):
with mock.patch.object(items.scrapy.item, 'Field'):
a = items.SitemapItem()
supported_fields = ['loc', 'lastmod', 'priority', 'changefreq']
for field in supported_fields:
a[field] = field
not_supported_fields = ['some', 'random', 'fields']
for field in not_supported_fields:
with self.assertRaises(KeyError):
a[field] = field
if __name__ == '__main__':
unittest.main()

View File

@ -78,26 +78,22 @@ class TestExportSitemap(unittest.TestCase):
def test_spider_opened_calls_open(self):
with mock.patch.object(pipelines, 'open',
return_value=None) as mocked_open:
with mock.patch.object(pipelines,
'SitemapItemExporter'):
with mock.patch.object(pipelines, 'SitemapItemExporter'):
self.export_sitemap.spider_opened(self.spider)
self.assertTrue(mocked_open.called)
def test_spider_opened_assigns_spider(self):
prev_len = len(self.export_sitemap.files)
with mock.patch.object(pipelines, 'open',
return_value=None):
with mock.patch.object(pipelines,
'SitemapItemExporter'):
with mock.patch.object(pipelines, 'open', return_value=None):
with mock.patch.object(pipelines, 'SitemapItemExporter'):
self.export_sitemap.spider_opened(self.spider)
after_len = len(self.export_sitemap.files)
self.assertTrue(after_len - prev_len, 1)
def test_spider_opened_instantiates_exporter(self):
with mock.patch.object(pipelines, 'open',
return_value=None):
with mock.patch.object(pipelines, 'open', return_value=None):
with mock.patch.object(pipelines,
'SitemapItemExporter') as mocked_exporter:
self.export_sitemap.spider_opened(self.spider)
@ -105,8 +101,7 @@ class TestExportSitemap(unittest.TestCase):
self.assertTrue(mocked_exporter.called)
def test_spider_opened_exporter_starts_exporting(self):
with mock.patch.object(pipelines, 'open',
return_value=None):
with mock.patch.object(pipelines, 'open', return_value=None):
with mock.patch.object(pipelines.SitemapItemExporter,
'start_exporting') as mocked_start:
self.export_sitemap.spider_opened(self.spider)

View File

@ -11,10 +11,30 @@
# under the License.
import mock
import scrapy
from sitemap.generator.spiders import sitemap_file
import unittest
class TestSitemapItem(unittest.TestCase):
def test_class_type(self):
self.assertTrue(type(sitemap_file.SitemapItem) is scrapy.item.ItemMeta)
def test_class_supports_fields(self):
with mock.patch.object(scrapy.item, 'Field'):
a = sitemap_file.SitemapItem()
supported_fields = ['loc', 'lastmod', 'priority', 'changefreq']
for field in supported_fields:
a[field] = field
not_supported_fields = ['some', 'random', 'fields']
for field in not_supported_fields:
with self.assertRaises(KeyError):
a[field] = field
class TestSitemapSpider(unittest.TestCase):
def setUp(self):
@ -38,7 +58,7 @@ class TestSitemapSpider(unittest.TestCase):
def test_parse_items_inits_sitemap(self):
response = mock.MagicMock()
with mock.patch.object(sitemap_file.items,
with mock.patch.object(sitemap_file,
'SitemapItem') as mocked_sitemap_item:
with mock.patch.object(sitemap_file, 'time'):
self.spider.parse_item(response)
@ -47,7 +67,7 @@ class TestSitemapSpider(unittest.TestCase):
def test_parse_items_gets_path(self):
response = mock.MagicMock()
with mock.patch.object(sitemap_file.items, 'SitemapItem'):
with mock.patch.object(sitemap_file, 'SitemapItem'):
with mock.patch.object(sitemap_file.urlparse,
'urlsplit') as mocked_urlsplit:
with mock.patch.object(sitemap_file, 'time'):
@ -60,7 +80,7 @@ class TestSitemapSpider(unittest.TestCase):
path = sitemap_file.urlparse.SplitResult(
scheme='https',
netloc='docs.openstack.com',
path='/kilo',
path='/mitaka',
query='',
fragment=''
)
@ -77,7 +97,7 @@ class TestSitemapSpider(unittest.TestCase):
path = sitemap_file.urlparse.SplitResult(
scheme='https',
netloc='docs.openstack.com',
path='/mitaka',
path='/ocata',
query='',
fragment=''
)
@ -94,7 +114,7 @@ class TestSitemapSpider(unittest.TestCase):
path = sitemap_file.urlparse.SplitResult(
scheme='https',
netloc='docs.openstack.com',
path='/mitaka',
path='/ocata',
query='',
fragment=''
)

33
tox.ini
View File

@ -32,6 +32,12 @@ commands = pylint os_doc_tools cleanup
[testenv:releasenotes]
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[testenv:sitemap]
deps = -r{toxinidir}/sitemap/test-requirements.txt
-r{toxinidir}/sitemap/requirements.txt
commands = flake8 sitemap
pytest sitemap
[testenv:venv]
commands = {posargs}
@ -44,3 +50,30 @@ builtins = _
exclude=.venv,.git,.tox,dist,*lib/python*,*egg,build,*autogenerate_config_docs/venv,*autogenerate_config_docs/sources
# 28 is currently the most complex thing we have
max-complexity=29
ignore = H101
[pytest]
norecursedirs =
.git
.tox
doc
python_files=
*.py
addopts =
-v
--ignore=setup.py
--doctest-modules
--tb short
--cov=sitemap/
--cov-report term-missing
--cov-config tox.ini
[report]
# pytest-cov configuration
omit = *test_*.py
exclude_lines =
# Regexes for lines to exclude from consideration
pragma: no cover
# Have to re-enable the standard pragma
if __name__ == .__main__.:
# Don't include __main__ statements in coverage report