jenkins-bot has submitted this change and it was merged.
Change subject: Integrate DrySite into test metaclass ......................................................................
Integrate DrySite into test metaclass
pywikibot.Site enhanced to allow the interface parameter to be a class, which is used for the new Site object.
Test class attribute dry = True uses a DrySite object that prevents Request.submit from accessing the server.
Many tests converted to dry tests, allowing them to be run by jenkins before code review.
Change-Id: I64232a8a5b3401b4ee19e97f112a23c28fc6ff92 --- M pywikibot/__init__.py M pywikibot/site.py M tests/README.rst M tests/api_tests.py M tests/aspects.py M tests/dry_api_tests.py M tests/dry_site_tests.py M tests/script_tests.py M tests/site_tests.py M tests/textlib_tests.py M tests/utils.py M tests/wikibase_tests.py M tox.ini 13 files changed, 292 insertions(+), 139 deletions(-)
Approvals: XZise: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py index d70dc86..46b1c6e 100644 --- a/pywikibot/__init__.py +++ b/pywikibot/__init__.py @@ -510,8 +510,9 @@ @type user: unicode @param sysop: sysop user to use on this site (override config.sysopnames) @type sysop: unicode - @param interface: site interface (override config.site_interface) - @type interface: string + @param interface: site class or name of class in pywikibot.site + (override config.site_interface) + @type interface: subclass of L{pywikibot.site.BaseSite} or string @param url: Instead of code and fam, does try to get a Site based on the URL. Still requires that the family supporting that URL exists. @type url: string @@ -556,16 +557,22 @@ sysop = sysop or config.sysopnames[family_name].get(code) \ or config.sysopnames[family_name].get('*')
- try: - tmp = __import__('pywikibot.site', fromlist=[interface]) - __Site = getattr(tmp, interface) - except ImportError: - raise ValueError("Invalid interface name '%(interface)s'" % locals()) - key = '%s:%s:%s:%s' % (interface, fam, code, user) - if key not in _sites or not isinstance(_sites[key], __Site): - _sites[key] = __Site(code=code, fam=fam, user=user, sysop=sysop) - debug(u"Instantiating Site object '%(site)s'" - % {'site': _sites[key]}, _logger) + if not isinstance(interface, type): + # If it isnt a class, assume it is a string + try: + tmp = __import__('pywikibot.site', fromlist=[interface]) + interface = getattr(tmp, interface) + except ImportError: + raise ValueError("Invalid interface name '%(interface)s'" % locals()) + + if not issubclass(interface, pywikibot.site.BaseSite): + warning('Site called with interface=%s' % interface.__name__) + + key = '%s:%s:%s:%s' % (interface.__name__, fam, code, user) + if key not in _sites or not isinstance(_sites[key], interface): + _sites[key] = interface(code=code, fam=fam, user=user, sysop=sysop) + debug(u"Instantiated %s object '%s'" + % (interface.__name__, _sites[key]), _logger) return _sites[key]
diff --git a/pywikibot/site.py b/pywikibot/site.py index 642731c..4efece2 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -1477,7 +1477,7 @@ if sysop and 'sysop' not in self.userinfo['groups']: return False
- if not self.userinfo['name']: + if 'name' not in self.userinfo or not self.userinfo['name']: return False
if self.userinfo['name'] != self._username[sysop]: diff --git a/tests/README.rst b/tests/README.rst index 742018e..e5e289d 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -122,6 +122,8 @@ ----------------------
- 'net = False' : test class does not use a site +- 'dry = True' : test class can use a fake site object - 'user = True' : test class needs to login to site +- 'sysop = True' : test class needs to login to site as a sysop - 'write = True' : test class needs to write to a site
diff --git a/tests/api_tests.py b/tests/api_tests.py index 9d4de2f..96afc5a 100644 --- a/tests/api_tests.py +++ b/tests/api_tests.py @@ -10,20 +10,25 @@ import datetime import pywikibot import pywikibot.data.api as api -from tests.aspects import unittest, TestCase, DefaultSiteTestCase +from tests.aspects import ( + unittest, + TestCase, + DefaultSiteTestCase, + DefaultDrySiteTestCase, +)
-class TestApiFunctions(DefaultSiteTestCase): +class TestApiFunctions(DefaultDrySiteTestCase):
"""API Request object test class.""" - - cached = True
def testObjectCreation(self): """Test api.Request() constructor.""" mysite = self.get_site() req = api.Request(site=mysite, action="test", foo="", bar="test") self.assertTrue(req) + self.assertEqual(req.site, mysite) + req = api.Request(action="test", foo="", bar="test") self.assertEqual(req.site, mysite) self.assertIn("foo", req._params) self.assertEqual(req["bar"], ["test"]) @@ -45,7 +50,7 @@ family = 'wikipedia' code = 'en'
- cached = True + dry = True
def setUp(self): super(TestPageGenerator, self).setUp() @@ -75,6 +80,11 @@ } }
+ # On a dry site, the namespace objects only have canonical names. + # Add custom_name for this site namespace, to match the live site. + if 'Wikipedia' not in self.site._namespaces: + self.site._namespaces[4].custom_name = 'Wikipedia' + def testGeneratorResults(self): """Test that PageGenerator yields pages with expected attributes.""" titles = ["Broadcaster.com", "Broadcaster (definition)", @@ -88,7 +98,7 @@ self.assertIn(page.title(), titles)
def test_initial_limit(self): - self.assertEqual(self.gen.limit, None) # limit is initaly None + self.assertEqual(self.gen.limit, None) # limit is initally None
def test_limit_as_number(self): for i in range(-2, 4): diff --git a/tests/aspects.py b/tests/aspects.py index 3089fc3..615afdf 100644 --- a/tests/aspects.py +++ b/tests/aspects.py @@ -38,6 +38,7 @@ from pywikibot import config, Site from pywikibot.site import BaseSite from pywikibot.family import WikimediaFamily +from pywikibot.data.api import Request as _original_Request
import tests from tests import unittest, patch_request, unpatch_request @@ -135,6 +136,46 @@ super(ForceCacheMixin, self).tearDown()
unpatch_request() + + +class SiteNotPermitted(pywikibot.site.BaseSite): + + """Site interface to prevent sites being loaded.""" + + def __init__(self, code, fam=None, user=None, sysop=None): + raise pywikibot.SiteDefinitionError( + 'Loading site %s:%s during dry test not permitted' + % (fam, code)) + + +class DisconnectedSiteMixin(TestCaseBase): + + """Test cases using a disconnected Site object. + + Do not use this for mock Site objects. + + Never set a class or instance variable called 'site' + As it will prevent tests from executing when invoked as: + $ nosetests -a '!site' -v + """ + + def setUp(self): + """Set up test.""" + self.old_config_interface = config.site_interface + # TODO: put a dummy subclass into config.site_interface + # as the default, to show a useful error message. + config.site_interface = SiteNotPermitted + + pywikibot.data.api.Request = tests.utils.DryRequest + + super(DisconnectedSiteMixin, self).setUp() + + def tearDown(self): + """Tear down test.""" + super(DisconnectedSiteMixin, self).tearDown() + + config.site_interface = self.old_config_interface + pywikibot.data.api.Request = _original_Request
class CacheInfoMixin(TestCaseBase): @@ -332,6 +373,9 @@ } }
+ if 'dry' in dct and dct['dry'] is True: + dct['net'] = False + if (('sites' not in dct and 'site' not in dct) or ('site' in dct and not dct['site'])): # Prevent use of pywikibot.Site @@ -356,6 +400,12 @@ return super(MetaTestCaseClass, cls).__new__(cls, name, bases, dct)
# The following section is only processed if the test uses sites. + + if 'dry' in dct and dct['dry']: + bases = tuple([DisconnectedSiteMixin] + list(bases)) + del dct['net'] + else: + dct['net'] = True
if 'cacheinfo' in dct and dct['cacheinfo']: bases = tuple([CacheInfoMixin] + list(bases)) @@ -425,18 +475,24 @@ if not cls.sites: cls.sites = {}
+ # If the test is not cached, create new Site objects for this class + if not hasattr(cls, 'cached') or not cls.cached: + orig_sites = pywikibot._sites + pywikibot._sites = {} + + interface = None # defaults to 'APISite' + if hasattr(cls, 'dry') and cls.dry: + # Delay load to avoid cyclic import + from tests.utils import DrySite + interface = DrySite + for data in cls.sites.values(): if 'site' not in data: - # If the test is not cached, fetch a new Site for this class - if not hasattr(cls, 'cached') or not cls.cached: - orig_sites = pywikibot._sites - pywikibot._sites = {} - site = Site(data['code'], data['family']) - pywikibot._sites = orig_sites - else: - site = Site(data['code'], data['family']) + data['site'] = Site(data['code'], data['family'], + interface=interface)
- data['site'] = site + if not hasattr(cls, 'cached') or not cls.cached: + pywikibot._sites = orig_sites
if len(cls.sites) == 1: key = next(iter(cls.sites.keys())) @@ -530,6 +586,13 @@ code = config.mylang
+class DefaultDrySiteTestCase(DefaultSiteTestCase): + + """Run tests using the config specified site in offline mode.""" + + dry = True + + class WikimediaSiteTestCase(TestCase):
"""Test class uses only WMF sites.""" diff --git a/tests/dry_api_tests.py b/tests/dry_api_tests.py index 39645d9..38ced9e 100644 --- a/tests/dry_api_tests.py +++ b/tests/dry_api_tests.py @@ -1,17 +1,5 @@ # -*- coding: utf-8 -*- -""" -API tests which do not interact with a site. - -Some of these tests are not 'net = False' (and not run by jenkins), as they -instantiate a Request, and the Request constructor will call pywikibot.Site() -when a site parameter is not provided to __init__. - -The test framework yet doesn't have the ability to allow instantiation of a -real Site without also allowing the Site object to be used. - -While those tests are 'net = False', they do not initiate any network requests, -and they _should_ be 'dry'. -""" +"""API tests which do not interact with a site.""" # # (C) Pywikibot team, 2012-2014 # @@ -33,7 +21,7 @@
from tests import _data_dir from tests.utils import DummySiteinfo -from tests.aspects import unittest, TestCase, DefaultSiteTestCase +from tests.aspects import unittest, TestCase, DefaultDrySiteTestCase
class DryCachedRequestTests(TestCase): @@ -50,6 +38,8 @@ 'code': 'de', }, } + + dry = True
def setUp(self): super(DryCachedRequestTests, self).setUp() @@ -216,7 +206,7 @@ self.assertNotEqual(body.find(file_content), -1)
-class MimeTests(DefaultSiteTestCase): +class MimeTests(DefaultDrySiteTestCase):
"""Test MIME request handling with a real site."""
@@ -227,7 +217,7 @@ self.assertEqual(req.mime, True)
-class QueryGenTests(DefaultSiteTestCase): +class QueryGenTests(DefaultDrySiteTestCase):
"""Test QueryGenerator with a real site."""
diff --git a/tests/dry_site_tests.py b/tests/dry_site_tests.py index 0cd724c..773888f 100644 --- a/tests/dry_site_tests.py +++ b/tests/dry_site_tests.py @@ -14,33 +14,21 @@ from pywikibot.comms.http import user_agent from pywikibot.exceptions import UnknownSite
-from tests.utils import DummySiteinfo -from tests.aspects import unittest, TestCase, DeprecationTestCase +from tests.aspects import ( + unittest, TestCase, + DefaultDrySiteTestCase, + DeprecationTestCase, +)
-class DrySite(pywikibot.site.APISite): - - """Fake APISite object.""" - - _loginstatus = pywikibot.site.LoginStatus.NOT_ATTEMPTED - - @property - def userinfo(self): - return self._userinfo - - @property - def siteinfo(self): - return DummySiteinfo({}) - - -class TestDrySite(TestCase): +class TestDrySite(DefaultDrySiteTestCase):
"""Tests against a fake Site object."""
- net = False + dry = True
def test_logged_in(self): - x = DrySite('en', 'wikipedia') + x = self.get_site()
x._userinfo = {'name': None, 'groups': []} x._username = ['normal_user', 'sysop_user'] @@ -58,7 +46,7 @@ self.assertFalse(x.logged_in(False))
def test_user_agent(self): - x = DrySite('en', 'wikipedia') + x = self.get_site()
x._userinfo = {'name': 'foo'} x._username = ('foo', None) @@ -104,7 +92,7 @@ x._username = (None, None)
self.assertEqual('Foo', user_agent(x, format_string='Foo {username}')) - self.assertEqual('Foo (wikipedia:en)', + self.assertEqual('Foo (' + x.family.name + ':' + x.code + ')', user_agent(x, format_string='Foo ({script_comments})'))
diff --git a/tests/script_tests.py b/tests/script_tests.py index 0cb3958..b46e647 100644 --- a/tests/script_tests.py +++ b/tests/script_tests.py @@ -412,8 +412,6 @@
__metaclass__ = TestScriptMeta
- site = True - def setUp(self): super(TestScript, self).setUp() """Prepare the environment for running the pwb.py script.""" diff --git a/tests/site_tests.py b/tests/site_tests.py index 1e35899..deb2d8c 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -94,7 +94,7 @@ }, }
- cached = True + dry = True
def test_properties(self, key): """Test cases for BaseSite properties.""" diff --git a/tests/textlib_tests.py b/tests/textlib_tests.py index a549035..3d7e6c1 100644 --- a/tests/textlib_tests.py +++ b/tests/textlib_tests.py @@ -18,7 +18,7 @@ import pywikibot.textlib as textlib from pywikibot import config
-from tests.aspects import unittest, TestCase +from tests.aspects import unittest, TestCase, DefaultDrySiteTestCase
files = {} dirname = os.path.join(os.path.dirname(__file__), "pages") @@ -96,7 +96,7 @@ self.assertNotContains("enwiki_help_editing", u"Helpful tips", "section header must contain a link")
-class TestFormatFunctions(TestCase): +class TestFormatInterwiki(TestCase):
"""Test format functions."""
@@ -104,13 +104,6 @@ code = 'en'
cached = True - - @classmethod - def setUpClass(cls): - super(TestFormatFunctions, cls).setUpClass() - cls.site = cls.get_site() - cls.catresult = ('[[Category:Cat1]]%(LS)s[[Category:Cat2]]%(LS)s' - % {'LS': config.LS})
def test_interwiki_format(self): interwikis = { @@ -120,6 +113,16 @@ self.assertEqual('[[de:German]]%(LS)s[[fr:French]]%(LS)s' % {'LS': config.LS}, textlib.interwikiFormat(interwikis, self.site)) + + +class TestFormatCategory(DefaultDrySiteTestCase): + + """Test category formatting.""" + + dry = True + + catresult = ('[[Category:Cat1]]%(LS)s[[Category:Cat2]]%(LS)s' + % {'LS': config.LS})
def test_category_format_raw(self): self.assertEqual(self.catresult, @@ -144,7 +147,7 @@ textlib.categoryFormat(data, self.site))
-class TestCategoryRearrangement(TestCase): +class TestCategoryRearrangement(DefaultDrySiteTestCase):
""" Ensure that sorting keys are not being lost. @@ -153,28 +156,22 @@ with both a newline and an empty string as separators. """
- family = 'wikipedia' - code = 'en' + dry = True
- cached = True - - @classmethod - def setUpClass(cls): - super(TestCategoryRearrangement, cls).setUpClass() - cls.site = cls.get_site() - cls.old = ('[[Category:Cat1]]%(LS)s[[Category:Cat2|]]%(LS)s' - '[[Category:Cat1| ]]%(LS)s[[Category:Cat2|key]]' - % {'LS': config.LS}) - cls.cats = textlib.getCategoryLinks(cls.old, site=cls.site) + old = ('[[Category:Cat1]]%(LS)s[[Category:Cat2|]]%(LS)s' + '[[Category:Cat1| ]]%(LS)s[[Category:Cat2|key]]' + % {'LS': config.LS})
def test_standard_links(self): - new = textlib.replaceCategoryLinks(self.old, self.cats, site=self.site) + cats = textlib.getCategoryLinks(self.old, site=self.site) + new = textlib.replaceCategoryLinks(self.old, cats, site=self.site) self.assertEqual(self.old, new)
def test_adjoining_links(self): + cats_std = textlib.getCategoryLinks(self.old, site=self.site) old = self.old.replace(config.LS, '') cats = textlib.getCategoryLinks(old, site=self.site) - self.assertEqual(self.cats, cats) + self.assertEqual(cats_std, cats) sep = config.LS config.line_separator = '' # use an empty separator temporarily new = textlib.replaceCategoryLinks(old, cats, site=self.site) diff --git a/tests/utils.py b/tests/utils.py index ac24c5d..05eecd4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +"""Test utilities.""" # # (C) Pywikibot team, 2013-2014 # @@ -8,8 +9,12 @@ __version__ = '$Id$' # import pywikibot +from pywikibot.site import Namespace +from pywikibot.data.api import CachedRequest +from pywikibot.data.api import Request as _original_Request + from tests import aspects -from tests import unittest # flake8: noqa +from tests import unittest # noqa
BaseTestCase = aspects.TestCase NoSiteTestCase = aspects.TestCase @@ -32,6 +37,8 @@
class DummySiteinfo(): + + """Dummy class to use instead of L{pywikibot.site.Siteinfo}."""
def __init__(self, cache): self._cache = dict((key, (item, False)) for key, item in cache.items()) @@ -68,3 +75,84 @@
def get_requested_time(self, key): return False + + +class DryRequest(CachedRequest): + + """Dummy class to use instead of L{pywikibot.data.api.Request}.""" + + def __init__(self, *args, **kwargs): + _original_Request.__init__(self, *args, **kwargs) + + def _expired(self, dt): + """Never invalidate cached data.""" + return False + + def _write_cache(self, data): + """Never write data.""" + return + + def submit(self): + raise Exception(u'DryRequest rejecting request: %r' + % self._params) + + +class DrySite(pywikibot.site.APISite): + + """Dummy class to use instead of L{pywikibot.site.APISite}.""" + + _loginstatus = pywikibot.site.LoginStatus.NOT_ATTEMPTED + + def __init__(self, code, fam, user, sysop): + """Constructor.""" + super(DrySite, self).__init__(code, fam, user, sysop) + self._userinfo = pywikibot.tools.EMPTY_DEFAULT + self._siteinfo = DummySiteinfo({}) + self._siteinfo._cache['lang'] = (code, True) + self._namespaces = Namespace.builtin_namespaces() + + @property + def userinfo(self): + return self._userinfo + + def version(self): + return self.family.version(self.code) + + def case(self): + if self.family.name == 'wiktionary': + return 'case-sensitive' + else: + return 'first-letter' + + def image_repository(self): + """Return Site object for image repository e.g. commons.""" + code, fam = self.shared_image_repository() + if bool(code or fam): + return pywikibot.Site(code, fam, self.username(), + interface=self.__class__) + + def data_repository(self): + """Return Site object for data repository e.g. Wikidata.""" + code, fam = self.shared_data_repository() + if bool(code or fam): + return pywikibot.Site(code, fam, self.username(), + interface=DryDataSite) + + +class DryDataSite(DrySite, pywikibot.site.DataSite): + + """Dummy class to use instead of L{pywikibot.site.DataSite}.""" + + def __init__(self, code, fam, user, sysop): + """Constructor.""" + super(DryDataSite, self).__init__(code, fam, user, sysop) + + self._namespaces[0].defaultcontentmodel = 'wikibase-item' + + self._namespaces.update( + { + 120: Namespace(id=120, + case='first-letter', + canonical_name='Property', + defaultcontentmodel='wikibase-property') + }) diff --git a/tests/wikibase_tests.py b/tests/wikibase_tests.py index d78bf9b..05f47c5 100644 --- a/tests/wikibase_tests.py +++ b/tests/wikibase_tests.py @@ -66,13 +66,26 @@ claim.setTarget(pywikibot.ItemPage(repo, 'q1')) self.assertEqual(claim._formatValue(), {'entity-type': 'item', 'numeric-id': 1})
- # test WbTime + def test_cmp(self): + """ Test WikibasePage.__cmp__. """ + self.assertEqual(pywikibot.ItemPage.fromPage(self.mainpage), + pywikibot.ItemPage(self.get_repo(), 'q5296')) + + +class TestWikibaseTypes(WikidataTestCase): + + """Test Wikibase data types.""" + + dry = True + + def test_WbTime(self): + repo = self.get_repo() t = pywikibot.WbTime(site=repo, year=2010, hour=12, minute=43) self.assertEqual(t.toTimestr(), '+00000002010-01-01T12:43:00Z') self.assertRaises(ValueError, pywikibot.WbTime, site=repo, precision=15) self.assertRaises(ValueError, pywikibot.WbTime, site=repo, precision='invalid_precision')
- # test WbQuantity + def test_WbQuantity(self): q = pywikibot.WbQuantity(amount=1234, error=1) self.assertEqual(q.toWikibase(), {'amount': 1234, 'lowerBound': 1233, @@ -114,14 +127,22 @@ self.assertRaises(NotImplementedError, pywikibot.WbQuantity, amount=789, unit='invalid_unit')
- # test WikibasePage.__cmp__ - self.assertEqual(pywikibot.ItemPage.fromPage(self.mainpage), - pywikibot.ItemPage(repo, 'q5296'))
- def testItemPageExtensionability(self): +class TestItemPageExtensibility(TestCase): + + """Test ItemPage extensibility.""" + + family = 'wikipedia' + code = 'en' + + dry = True + + def test_ItemPage_extensibility(self): class MyItemPage(pywikibot.ItemPage): pass - self.assertIsInstance(MyItemPage.fromPage(self.mainpage), MyItemPage) + page = pywikibot.Page(self.site, 'foo') + self.assertIsInstance(MyItemPage.fromPage(page, lazy_load=True), + MyItemPage)
class TestItemLoad(WikidataTestCase): @@ -593,6 +614,8 @@ family = 'wikipedia' code = 'en'
+ dry = True + def setUp(self): super(TestWriteNormalizeLang, self).setUp() self.site = self.get_site() @@ -757,65 +780,48 @@ 'Invalid:Q1')
-class TestAlternateNamespaces(TestCase): +class TestAlternateNamespaces(WikidataTestCase):
"""Test cases to test namespaces of Wikibase entities."""
- net = False + dry = True
- def setUp(self): - super(TestAlternateNamespaces, self).setUp() + @classmethod + def setUpClass(cls): + super(TestAlternateNamespaces, cls).setUpClass()
- class DrySite(pywikibot.site.DataSite): - _namespaces = { - 90: Namespace(id=90, - case='first-letter', - canonical_name='Item', - defaultcontentmodel='wikibase-item'), - 92: Namespace(id=92, - case='first-letter', - canonical_name='Prop', - defaultcontentmodel='wikibase-property') - } - - __init__ = lambda *args: None - code = 'test' - family = lambda: None - family.name = 'test' - _logged_in_as = None - _siteinfo = {'case': 'first-letter'} - _item_namespace = None - _property_namespace = None - - def encoding(self): - return 'utf-8' - - def encodings(self): - return [] - - self.site = DrySite('test', 'mock', None, None) + cls.get_repo()._namespaces = { + 90: Namespace(id=90, + case='first-letter', + canonical_name='Item', + defaultcontentmodel='wikibase-item'), + 92: Namespace(id=92, + case='first-letter', + canonical_name='Prop', + defaultcontentmodel='wikibase-property') + }
def test_alternate_item_namespace(self): - item = pywikibot.ItemPage(self.site, 'Q60') + item = pywikibot.ItemPage(self.repo, 'Q60') self.assertEqual(item.namespace(), 90) self.assertEqual(item.id, 'Q60') self.assertEqual(item.title(), 'Item:Q60') self.assertEqual(item._defined_by(), {'ids': 'Q60'})
- item = pywikibot.ItemPage(self.site, 'Item:Q60') + item = pywikibot.ItemPage(self.repo, 'Item:Q60') self.assertEqual(item.namespace(), 90) self.assertEqual(item.id, 'Q60') self.assertEqual(item.title(), 'Item:Q60') self.assertEqual(item._defined_by(), {'ids': 'Q60'})
def test_alternate_property_namespace(self): - prop = pywikibot.PropertyPage(self.site, 'P21') + prop = pywikibot.PropertyPage(self.repo, 'P21') self.assertEqual(prop.namespace(), 92) self.assertEqual(prop.id, 'P21') self.assertEqual(prop.title(), 'Prop:P21') self.assertEqual(prop._defined_by(), {'ids': 'P21'})
- prop = pywikibot.PropertyPage(self.site, 'Prop:P21') + prop = pywikibot.PropertyPage(self.repo, 'Prop:P21') self.assertEqual(prop.namespace(), 92) self.assertEqual(prop.id, 'P21') self.assertEqual(prop.title(), 'Prop:P21') @@ -867,6 +873,8 @@ }, }
+ dry = True + def test_not_supported_family(self, key): """Test that family without a data repository causes error.""" site = self.get_site(key) @@ -883,6 +891,8 @@
"""Test cases to test toJSON() functions."""
+ dry = True + @classmethod def setUpClass(cls): if not sys.version_info >= (2, 7): diff --git a/tox.ini b/tox.ini index 1e394e9..e13d4d9 100644 --- a/tox.ini +++ b/tox.ini @@ -108,7 +108,7 @@
[testenv:nose] setenv = PYWIKIBOT2_NO_USER_CONFIG=1 -commands = nosetests --with-doctest --with-doctest-ignore-unicode -v -a "!site,!net" tests pywikibot --ignore-files=gui.py --ignore-files=botirc.py +commands = nosetests --with-doctest --with-doctest-ignore-unicode -v -a "!net" tests pywikibot --ignore-files=gui.py --ignore-files=botirc.py deps = nose doctest-ignore-unicode @@ -116,7 +116,7 @@ [testenv:nose34] basepython = python3 setenv = PYWIKIBOT2_NO_USER_CONFIG=1 -commands = nosetests --with-doctest --with-doctest-ignore-unicode -v -a "!site,!net" tests pywikibot --ignore-files=gui.py --ignore-files=botirc.py +commands = nosetests --with-doctest --with-doctest-ignore-unicode -v -a "!net" tests pywikibot --ignore-files=gui.py --ignore-files=botirc.py deps = nose doctest-ignore-unicode
pywikibot-commits@lists.wikimedia.org