jenkins-bot has submitted this change and it was merged.
Change subject: Add orderless page title assert to fix broken test ......................................................................
Add orderless page title assert to fix broken test
Split assertPagelistTitles into assertPageTitlesEqual and assertPageTitlesCountEqual, with semantics similar to assertEqual and assertCountEqual, however the generator is only used until it has more items than the expected number of titles.
Create new test module 'tests' to test features of the test system. It is disabled by default.
Fix pagegenerator tests which misused assertPagelistTitles 'titles' arg.
Change the reflinks xml tests to use assertPageTitlesCountEqual, as the use of preloading means the order can vary.
Improve the xmlreader asserts to be more precise, to assert that there are no order problems in xmlreader, and fix a unicode bug in an expectedFailure test.
Change-Id: I00ceb32ac468b98f418d0fbe7ab1f0748e15b352 --- M tests/__init__.py M tests/aspects.py M tests/http_tests.py M tests/pagegenerators_tests.py M tests/reflinks_tests.py A tests/tests_tests.py M tests/xmlreader_tests.py 7 files changed, 163 insertions(+), 69 deletions(-)
Approvals: XZise: Looks good to me, approved jenkins-bot: Verified
diff --git a/tests/__init__.py b/tests/__init__.py index 2634a8b..f72d451 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -58,6 +58,7 @@
library_test_modules = [ 'deprecation', + 'tests', 'date', 'mediawikiversion', 'ipregex', @@ -97,7 +98,8 @@ ]
disabled_test_modules = [ - 'ui', + 'tests', # tests of the tests package + 'ui', # these tests havent been designed to be run in the test runner. ]
disabled_tests = { diff --git a/tests/aspects.py b/tests/aspects.py index 6915e39..86d1341 100644 --- a/tests/aspects.py +++ b/tests/aspects.py @@ -29,11 +29,11 @@ UITestCase: Not integrated; direct subclass of unittest.TestCase. """ -import collections -import time -import sys -import os import inspect +import itertools +import os +import sys +import time
import pywikibot
@@ -106,6 +106,56 @@ self.assertIn(page.namespace(), namespaces, "%s not in namespace %r" % (page, namespaces))
+ def _get_gen_pages(self, gen, count=None, site=None): + """ + Get pages from gen, asserting they are Page from site. + + Iterates at most two greater than count, including the + Page after count if it exists, and then a Page with title '...' + if additional items are in the iterator. + + @param gen: Page generator + @type gen: generator of Page + @param count: number of pages to get + @type titles: int + @param site: Site of expected pages + @type site: APISite + """ + original_iter = iter(gen) + + gen = itertools.islice(original_iter, 0, count) + + gen_pages = list(gen) + + try: + gen_pages.append(next(original_iter)) + next(original_iter) + if not site: + site = gen_pages[0].site + gen_pages.append(pywikibot.Page(site, '...')) + except StopIteration: + pass + + for page in gen_pages: + self.assertIsInstance(page, pywikibot.Page) + if site: + self.assertEqual(page.site, site) + + return gen_pages + + def _get_gen_titles(self, gen, count, site=None): + gen_pages = self._get_gen_pages(gen, count, site) + gen_titles = [page.title() for page in gen_pages] + return gen_titles + + def _get_canonical_titles(self, titles, site=None): + if site: + titles = [pywikibot.Link(title, site).canonical_title() + for title in titles] + elif not isinstance(titles, list): + titles = list(titles) + return titles + def assertPagesInNamespaces(self, gen, namespaces): """ Assert that generator returns Pages all in namespaces. @@ -147,42 +197,41 @@ else: self.assertEqual(set(page_namespaces), namespaces)
- def assertPagelistTitles(self, gen, titles, site=None): + def assertPageTitlesEqual(self, gen, titles, site=None): """ Test that pages in gen match expected titles.
- If the expected titles is a tuple, assert that the generator yields - pages with the same number and order of titles. + Only iterates to the length of titles plus two.
@param gen: Page generator @type gen: generator of Page @param titles: Expected titles - @type titles: tuple or list + @type titles: iterator + @param site: Site of expected pages + @type site: APISite """ - is_tuple = isinstance(titles, tuple) - if site: - titles = [pywikibot.Link(title, site).canonical_title() - for title in titles] - if is_tuple: - titles = tuple(titles) + titles = self._get_canonical_titles(titles, site) + gen_titles = self._get_gen_titles(gen, len(titles), site) + self.assertEqual(gen_titles, titles)
- if is_tuple: - working_set = collections.deque(titles) + def assertPageTitlesCountEqual(self, gen, titles, site=None): + """ + Test that pages in gen match expected titles, regardless of order.
- for page in gen: - self.assertIsInstance(page, pywikibot.Page) - if site: - self.assertEqual(page.site, site) + Only iterates to the length of titles plus two.
- title = page.title() - self.assertIn(title, titles) - if is_tuple: - self.assertIn(title, working_set) - self.assertEqual(title, working_set[0]) - working_set.popleft() + @param gen: Page generator + @type gen: generator of Page + @param titles: Expected titles + @type titles: iterator + @param site: Site of expected pages + @type site: APISite + """ + titles = self._get_canonical_titles(titles, site) + gen_titles = self._get_gen_titles(gen, len(titles), site) + self.assertCountEqual(gen_titles, titles)
- if is_tuple: - self.assertEqual(working_set, collections.deque([])) + assertPagelistTitles = assertPageTitlesEqual
class TestLoggingMixin(TestCaseBase): diff --git a/tests/http_tests.py b/tests/http_tests.py index 1a23179..4b1a885 100644 --- a/tests/http_tests.py +++ b/tests/http_tests.py @@ -67,22 +67,6 @@ self.assertIn('<html lang="mul"', r)
-class HttpServerProblemTestCase(TestCase): - - """Test HTTP status 502 causes this test class to be skipped.""" - - sites = { - '502': { - 'hostname': 'http://getstatuscode.com/502', - } - } - - def test_502(self): - """Test a HTTP 502 response using http://getstatuscode.com/502.""" - self.fail('The test framework should skip this test.') - pass - - class HttpsCertificateTestCase(TestCase):
"""HTTPS certificate test.""" diff --git a/tests/pagegenerators_tests.py b/tests/pagegenerators_tests.py index 31d0ec3..00eb2fb 100755 --- a/tests/pagegenerators_tests.py +++ b/tests/pagegenerators_tests.py @@ -28,7 +28,6 @@ ) from tests.thread_tests import GeneratorIntersectTestCase
- en_wp_page_titles = ( # just a bunch of randomly selected titles for English Wikipedia tests u"Eastern Sayan", @@ -116,11 +115,11 @@ gen = pagegenerators.PagesFromTitlesGenerator(self.titles, self.site) gen = pagegenerators.RegexFilterPageGenerator(gen, ['/doc', '/meta'], quantifier='all') - self.assertPagelistTitles(gen, ()) + self.assertPagelistTitles(gen, []) gen = pagegenerators.PagesFromTitlesGenerator(self.titles, self.site) gen = pagegenerators.RegexFilterPageGenerator(gen, ['Template', '/meta'], quantifier='all') - self.assertPagelistTitles(gen, ('Template:Template/Meta')) + self.assertPagelistTitles(gen, ('Template:Template/Meta', )) gen = pagegenerators.PagesFromTitlesGenerator(self.titles, self.site) gen = pagegenerators.RegexFilterPageGenerator(gen, ['template', '/meta'], quantifier='any') diff --git a/tests/reflinks_tests.py b/tests/reflinks_tests.py index d5dda0a..34499ba 100644 --- a/tests/reflinks_tests.py +++ b/tests/reflinks_tests.py @@ -133,7 +133,13 @@
class TestReferencesBotConstructor(TestCase):
- """Test reflinks with non-write patching (if the testpage exists).""" + """ + Test reflinks with run() removed. + + These tests cant verify the order of the pages in the XML + as the constructor is given a preloading generator. + See APISite.preloadpages for details. + """
family = 'wikipedia' code = 'en' @@ -159,34 +165,31 @@ def test_xml_simple(self): main('-xml:' + os.path.join(_xml_data_dir, 'dummy-reflinks.xml')) gen = self.constructor_args[0] - pages = list(gen) - self.assertPagelistTitles(pages, (u'Fake page', u'Talk:Fake page'), - site=self.get_site()) + self.assertPageTitlesCountEqual(gen, [u'Fake page', u'Talk:Fake page'], + site=self.get_site())
def test_xml_one_namespace(self): main('-xml:' + os.path.join(_xml_data_dir, 'dummy-reflinks.xml'), '-namespace:1') gen = self.constructor_args[0] pages = list(gen) - self.assertPagelistTitles(pages, (u'Talk:Fake page', ), + self.assertPagelistTitles(pages, [u'Talk:Fake page'], site=self.get_site())
def test_xml_multiple_namespace_ids(self): main('-xml:' + os.path.join(_xml_data_dir, 'dummy-reflinks.xml'), '-namespace:0', '-namespace:1', '-xmlstart:Fake page') gen = self.constructor_args[0] - pages = list(gen) - self.assertPagelistTitles(pages, (u'Fake page', u'Talk:Fake page'), - site=self.get_site()) + self.assertPageTitlesCountEqual(gen, [u'Fake page', u'Talk:Fake page'], + site=self.get_site())
@unittest.expectedFailure def test_xml_multiple_namespace_ids_2(self): main('-xml:' + os.path.join(_xml_data_dir, 'dummy-reflinks.xml'), '-namespace:0,1', '-xmlstart:Fake page') gen = self.constructor_args[0] - pages = list(gen) - self.assertPagelistTitles(pages, (u'Fake page', u'Talk:Fake page'), - site=self.get_site()) + self.assertPageTitlesCountEqual(gen, [u'Fake page', u'Talk:Fake page'], + site=self.get_site())
@unittest.expectedFailure def test_xml_start_prefix(self): @@ -194,7 +197,7 @@ '-namespace:1', '-xmlstart:Fake') gen = self.constructor_args[0] pages = list(gen) - self.assertPagelistTitles(pages, (u'Talk:Fake page', ), + self.assertPagelistTitles(pages, [u'Talk:Fake page'], site=self.get_site())
@unittest.expectedFailure @@ -203,7 +206,7 @@ '-namespace:1', '-xmlstart:Fake_page') gen = self.constructor_args[0] pages = list(gen) - self.assertPagelistTitles(pages, (u'Talk:Fake page', ), + self.assertPagelistTitles(pages, [u'Talk:Fake page'], site=self.get_site())
def test_xml_namespace_name(self): @@ -211,7 +214,7 @@ '-namespace:Talk', '-xmlstart:Fake page') gen = self.constructor_args[0] pages = list(gen) - self.assertPagelistTitles(pages, (u'Talk:Fake page', ), + self.assertPagelistTitles(pages, [u'Talk:Fake page'], site=self.get_site())
diff --git a/tests/tests_tests.py b/tests/tests_tests.py new file mode 100755 index 0000000..6ac9c69 --- /dev/null +++ b/tests/tests_tests.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""Tests for the tests package.""" +# +# (C) Pywikibot team, 2014 +# +# Distributed under the terms of the MIT license. +__version__ = '$Id$' + +import pywikibot + +from tests.aspects import unittest, TestCase +from tests.utils import allowed_failure + + +class HttpServerProblemTestCase(TestCase): + + """Test HTTP status 502 causes this test class to be skipped.""" + + sites = { + '502': { + 'hostname': 'http://getstatuscode.com/502', + } + } + + def test_502(self): + """Test a HTTP 502 response using http://getstatuscode.com/502.""" + self.fail('The test framework should skip this test.') + pass + + +class TestPageAssert(TestCase): + + """Test page assertion methods.""" + + family = 'wikipedia' + code = 'en' + + dry = True + + @allowed_failure + def test_assertPageTitlesEqual(self): + """Test assertPageTitlesEqual shows the second page title and '...'.""" + pages = [pywikibot.Page(self.site, 'Foo'), + pywikibot.Page(self.site, 'Bar'), + pywikibot.Page(self.site, 'Baz')] + self.assertPageTitlesEqual(pages, + ['Foo'], + self.site) + + +if __name__ == "__main__": + try: + unittest.main() + except SystemExit: + pass diff --git a/tests/xmlreader_tests.py b/tests/xmlreader_tests.py index 3681e19..85dbbe8 100644 --- a/tests/xmlreader_tests.py +++ b/tests/xmlreader_tests.py @@ -13,7 +13,6 @@
from tests import _data_dir from tests.aspects import unittest, TestCase -from tests.utils import allowed_failure
_xml_data_dir = os.path.join(_data_dir, 'xml')
@@ -90,34 +89,36 @@ def test_pair(self): entries = self._get_entries('pair-0.10.xml', allrevisions=True) self.assertEqual(4, len(entries)) - self.assertTrue(all(entry.title.endswith(u"Çullu, Agdam") - for entry in entries)) self.assertTrue(all(entry.username == 'Carlossuarez46' for entry in entries)) self.assertTrue(all(entry.isredirect is False for entry in entries))
- articles = [entry for entry in entries if entry.ns == "0"] - talks = [entry for entry in entries if entry.ns == "1"] + articles = entries[0:2] + talks = entries[2:4]
self.assertEqual(2, len(articles)) self.assertTrue(all(entry.id == "19252820" for entry in articles)) + self.assertTrue(all(entry.title == u"Çullu, Agdam" + for entry in articles)) self.assertTrue(all(u'Çullu, Quzanlı' in entry.text for entry in articles)) self.assertEqual(articles[0].text, u'#REDIRECT [[Çullu, Quzanlı]]')
self.assertEqual(2, len(talks)) self.assertTrue(all(entry.id == "19252824" for entry in talks)) + self.assertTrue(all(entry.title == u"Talk:Çullu, Agdam" + for entry in talks)) self.assertEqual(talks[1].text, '{{DisambigProject}}') self.assertEqual(talks[1].comment, 'proj')
- @allowed_failure def test_edit_summary_decoding(self): """Test edit summaries are decoded.""" entries = self._get_entries('pair-0.10.xml', allrevisions=True) articles = [entry for entry in entries if entry.ns == "0"]
+ # It does not decode the edit summary self.assertEqual(articles[0].comment, - 'moved [[Çullu, Agdam]] to [[Çullu, Quzanlı]]: dab') + u'moved [[Çullu, Agdam]] to [[Çullu, Quzanlı]]: dab')
if __name__ == '__main__':
pywikibot-commits@lists.wikimedia.org