You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by di...@apache.org on 2022/11/04 19:44:12 UTC

[allura] 16/20: [#8455] remove @with_nose_compatability

This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a commit to branch pytest-finalize
in repository https://gitbox.apache.org/repos/asf/allura.git

commit af18fb3153e7754ebda6870557fb09952c178d2d
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Tue Nov 1 15:28:04 2022 +0000

    [#8455] remove @with_nose_compatability
---
 Allura/allura/tests/functional/test_admin.py       |  9 ----
 Allura/allura/tests/functional/test_auth.py        | 10 -----
 Allura/allura/tests/functional/test_discuss.py     |  4 --
 Allura/allura/tests/functional/test_feeds.py       |  2 -
 Allura/allura/tests/functional/test_gravatar.py    |  2 -
 Allura/allura/tests/functional/test_home.py        |  2 -
 Allura/allura/tests/functional/test_nav.py         |  2 -
 .../allura/tests/functional/test_neighborhood.py   |  4 --
 Allura/allura/tests/functional/test_newforge.py    |  2 -
 .../tests/functional/test_personal_dashboard.py    |  4 --
 Allura/allura/tests/functional/test_rest.py        |  5 ---
 Allura/allura/tests/functional/test_root.py        |  3 --
 Allura/allura/tests/functional/test_search.py      |  2 -
 Allura/allura/tests/functional/test_site_admin.py  |  7 ----
 Allura/allura/tests/functional/test_static.py      |  2 -
 Allura/allura/tests/functional/test_subscriber.py  |  2 -
 Allura/allura/tests/functional/test_tool_list.py   |  2 -
 .../allura/tests/functional/test_trovecategory.py  |  3 --
 .../allura/tests/functional/test_user_profile.py   |  3 --
 Allura/allura/tests/model/test_auth.py             |  2 -
 Allura/allura/tests/model/test_filesystem.py       |  2 -
 Allura/allura/tests/model/test_notification.py     |  5 ---
 Allura/allura/tests/model/test_repo.py             |  5 ---
 Allura/allura/tests/model/test_timeline.py         |  2 -
 .../tests/scripts/test_create_sitemap_files.py     |  2 -
 .../allura/tests/scripts/test_delete_projects.py   |  2 -
 Allura/allura/tests/scripts/test_misc_scripts.py   |  2 -
 Allura/allura/tests/scripts/test_reindexes.py      |  3 --
 .../tests/templates/jinja_master/test_lib.py       |  2 -
 Allura/allura/tests/test_commands.py               |  7 ----
 Allura/allura/tests/test_decorators.py             |  3 --
 Allura/allura/tests/test_diff.py                   |  2 -
 Allura/allura/tests/test_dispatch.py               |  2 -
 Allura/allura/tests/test_globals.py                |  7 ----
 Allura/allura/tests/test_helpers.py                |  5 ---
 Allura/allura/tests/test_mail_util.py              |  6 ---
 Allura/allura/tests/test_markdown.py               |  6 ---
 Allura/allura/tests/test_middlewares.py            |  2 -
 Allura/allura/tests/test_multifactor.py            | 11 -----
 Allura/allura/tests/test_plugin.py                 |  8 ----
 Allura/allura/tests/test_scripttask.py             |  2 -
 Allura/allura/tests/test_security.py               |  2 -
 Allura/allura/tests/test_tasks.py                  |  9 ----
 Allura/allura/tests/test_utils.py                  | 11 -----
 Allura/allura/tests/test_validators.py             | 12 ------
 Allura/allura/tests/test_webhooks.py               |  8 ----
 .../test_discussion_moderation_controller.py       |  4 --
 Allura/allura/tests/unit/phone/test_nexmo.py       |  2 -
 .../allura/tests/unit/phone/test_phone_service.py  |  2 -
 Allura/allura/tests/unit/spam/test_akismet.py      |  2 -
 Allura/allura/tests/unit/spam/test_spam_filter.py  |  4 --
 .../allura/tests/unit/spam/test_stopforumspam.py   |  2 -
 Allura/allura/tests/unit/test_app.py               |  5 ---
 Allura/allura/tests/unit/test_artifact.py          |  2 -
 Allura/allura/tests/unit/test_discuss.py           |  2 -
 Allura/allura/tests/unit/test_helpers/test_ago.py  |  2 -
 .../tests/unit/test_helpers/test_set_context.py    |  7 ----
 .../allura/tests/unit/test_ldap_auth_provider.py   |  2 -
 Allura/allura/tests/unit/test_mixins.py            |  2 -
 .../allura/tests/unit/test_package_path_loader.py  |  2 -
 Allura/allura/tests/unit/test_post_model.py        |  2 -
 Allura/allura/tests/unit/test_project.py           |  2 -
 Allura/allura/tests/unit/test_repo.py              |  8 ----
 Allura/allura/tests/unit/test_session.py           |  5 ---
 Allura/allura/tests/unit/test_sitemapentry.py      |  2 -
 Allura/allura/tests/unit/test_solr.py              |  4 --
 AlluraTest/alluratest/controller.py                |  5 ---
 AlluraTest/alluratest/pytest_helpers.py            | 49 ----------------------
 AlluraTest/alluratest/test_syntax.py               |  2 +-
 69 files changed, 1 insertion(+), 318 deletions(-)

diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 20fc7a554..11ac71129 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -30,7 +30,6 @@ import mock
 
 import allura
 from allura.tests import TestController
-from alluratest.pytest_helpers import with_nose_compatibility
 from allura.tests import decorators as td
 from allura.tests.decorators import audits
 from alluratest.controller import TestRestApiBase, setup_trove_categories
@@ -46,7 +45,6 @@ from forgewiki.wiki_main import ForgeWikiApp
 log = logging.getLogger(__name__)
 
 
-@with_nose_compatibility
 class TestProjectAdmin(TestController):
 
     def test_admin_controller(self):
@@ -959,7 +957,6 @@ class TestProjectAdmin(TestController):
         r.mustcontain('Neighborhood Invitation(s) for test')
 
 
-@with_nose_compatibility
 class TestExport(TestController):
 
     def setup_method(self, method):
@@ -1086,7 +1083,6 @@ class TestExport(TestController):
         assert 'Check All</label>' in r
 
 
-@with_nose_compatibility
 class TestRestExport(TestRestApiBase):
 
     @mock.patch('allura.model.project.MonQTask')
@@ -1154,7 +1150,6 @@ class TestRestExport(TestRestApiBase):
             ['tickets', 'discussion'], 'test.zip', send_email=False, with_attachments=False)
 
 
-@with_nose_compatibility
 class TestRestInstallTool(TestRestApiBase):
 
     def test_missing_mount_info(self):
@@ -1328,7 +1323,6 @@ class TestRestInstallTool(TestRestApiBase):
             get_labels() == ['t1', 'Admin', 'Search', 'Activity', 'A Subproject', 'ta', 'tb', 'tc'])
 
 
-@with_nose_compatibility
 class TestRestAdminOptions(TestRestApiBase):
     def test_no_mount_point(self):
         r = self.api_get('/rest/p/test/admin/admin_options/', status=400)
@@ -1344,7 +1338,6 @@ class TestRestAdminOptions(TestRestApiBase):
         assert r.json['options'] is not None
 
 
-@with_nose_compatibility
 class TestRestMountOrder(TestRestApiBase):
     def test_no_kw(self):
         r = self.api_post('/rest/p/test/admin/mount_order/', status=400)
@@ -1394,7 +1387,6 @@ class TestRestMountOrder(TestRestApiBase):
         assert b > a
 
 
-@with_nose_compatibility
 class TestRestToolGrouping(TestRestApiBase):
     def test_invalid_grouping_threshold(self):
         for invalid_value in ('100', 'asdf'):
@@ -1421,7 +1413,6 @@ class TestRestToolGrouping(TestRestApiBase):
         assert 'wiki' in [tool['mount_point'] for tool in result2.json['menu']]
 
 
-@with_nose_compatibility
 class TestInstallableTools(TestRestApiBase):
     def test_installable_tools_response(self):
         r = self.api_get('/rest/p/test/admin/installable_tools', status=200)
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index c016a39b1..c1030a3cb 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -38,7 +38,6 @@ from tg import tmpl_context as c, app_globals as g
 from allura.tests import TestController
 from allura.tests import decorators as td
 from allura.tests.decorators import audits, out_audits, assert_logmsg
-from alluratest.pytest_helpers import with_nose_compatibility
 from alluratest.controller import setup_trove_categories, TestRestApiBase, oauth1_webtest
 from allura import model as M
 from allura.model.oauth import dummy_oauths
@@ -51,7 +50,6 @@ def unentity(s):
     return s.replace('&quot;', '"').replace('&#34;', '"')
 
 
-@with_nose_compatibility
 class TestAuth(TestController):
     def test_login(self):
         self.app.get('/auth/')
@@ -1134,7 +1132,6 @@ class TestAuth(TestController):
         assert r.content_length != 777
 
 
-@with_nose_compatibility
 class TestAuthRest(TestRestApiBase):
 
     def test_tools_list_anon(self):
@@ -1174,7 +1171,6 @@ class TestAuthRest(TestRestApiBase):
         }
 
 
-@with_nose_compatibility
 class TestPreferences(TestController):
     @td.with_user_project('test-admin')
     def test_personal_data(self):
@@ -1558,7 +1554,6 @@ class TestPreferences(TestController):
             self.app.get('/auth/not_page', status=404)
 
 
-@with_nose_compatibility
 class TestPasswordReset(TestController):
     test_primary_email = 'testprimaryaddr@mail.com'
 
@@ -1810,7 +1805,6 @@ To update your password on %s, please visit the following URL:
         assert 'Log Out' in r, r
 
 
-@with_nose_compatibility
 class TestOAuth(TestController):
     def test_register_deregister_app(self):
         # register
@@ -2145,7 +2139,6 @@ class TestOAuthAccessToken(TestController):
         self.test_access_token_ok(signature_type='query')
 
 
-@with_nose_compatibility
 class TestDisableAccount(TestController):
     def test_not_authenticated(self):
         r = self.app.get(
@@ -2190,7 +2183,6 @@ class TestDisableAccount(TestController):
         assert user.disabled == True
 
 
-@with_nose_compatibility
 class TestPasswordExpire(TestController):
     def login(self, username='test-user', pwd='foo', query_string=''):
         extra = {'username': '*anonymous', 'REMOTE_ADDR': '127.0.0.1'}
@@ -2386,7 +2378,6 @@ class TestPasswordExpire(TestController):
             assert r.location == 'http://localhost/p/test/tickets/?milestone=1.0&page=2'
 
 
-@with_nose_compatibility
 class TestCSRFProtection(TestController):
     def test_blocks_invalid(self):
         # so test-admin isn't automatically logged in for all requests
@@ -2421,7 +2412,6 @@ class TestCSRFProtection(TestController):
         assert r.form['_session_id'].value
 
 
-@with_nose_compatibility
 class TestTwoFactor(TestController):
 
     sample_key = b'\x00K\xda\xbfv\xc2B\xaa\x1a\xbe\xa5\x96b\xb2\xa0Z:\xc9\xcf\x8a'
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 3c0ed26ef..8035fb93f 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -25,10 +25,8 @@ from allura.tests import TestController
 from allura import model as M
 from allura.lib import helpers as h
 from tg import config
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestDiscussBase(TestController):
 
     def _thread_link(self):
@@ -44,7 +42,6 @@ class TestDiscussBase(TestController):
         return thread_link.split('/')[-2]
 
 
-@with_nose_compatibility
 class TestDiscuss(TestDiscussBase):
 
     def _is_subscribed(self, user, thread):
@@ -399,7 +396,6 @@ class TestDiscuss(TestDiscussBase):
         r = self.app.get(post_link, status=404)
 
 
-@with_nose_compatibility
 class TestAttachment(TestDiscussBase):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/functional/test_feeds.py b/Allura/allura/tests/functional/test_feeds.py
index e795f95a9..d3d2eaa1f 100644
--- a/Allura/allura/tests/functional/test_feeds.py
+++ b/Allura/allura/tests/functional/test_feeds.py
@@ -20,10 +20,8 @@ from formencode.variabledecode import variable_encode
 from allura.tests import TestController
 from allura.tests import decorators as td
 from allura.lib import helpers as h
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestFeeds(TestController):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/functional/test_gravatar.py b/Allura/allura/tests/functional/test_gravatar.py
index b42f64a71..7f8364518 100644
--- a/Allura/allura/tests/functional/test_gravatar.py
+++ b/Allura/allura/tests/functional/test_gravatar.py
@@ -22,10 +22,8 @@ from mock import patch
 
 from allura.tests import TestController
 import allura.lib.gravatar as gravatar
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestGravatar(TestController):
 
     def test_id(self):
diff --git a/Allura/allura/tests/functional/test_home.py b/Allura/allura/tests/functional/test_home.py
index 81c11a16a..6b62fe97b 100644
--- a/Allura/allura/tests/functional/test_home.py
+++ b/Allura/allura/tests/functional/test_home.py
@@ -26,10 +26,8 @@ import allura
 from allura.tests import TestController
 from allura.tests import decorators as td
 from allura import model as M
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestProjectHome(TestController):
 
     @td.with_wiki
diff --git a/Allura/allura/tests/functional/test_nav.py b/Allura/allura/tests/functional/test_nav.py
index e7113cc77..376fad571 100644
--- a/Allura/allura/tests/functional/test_nav.py
+++ b/Allura/allura/tests/functional/test_nav.py
@@ -22,10 +22,8 @@ from tg import app_globals as g
 
 from allura.tests import TestController
 from allura.lib import helpers as h
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestNavigation(TestController):
     """
     Test div-logo and nav-left:
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index 7261e0ce0..636830de4 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -36,10 +36,8 @@ from allura.tests import decorators as td
 from allura.lib import helpers as h
 from allura.lib import utils
 from alluratest.controller import setup_trove_categories
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestNeighborhood(TestController):
 
     def setup_method(self, method):
@@ -978,7 +976,6 @@ class TestNeighborhood(TestController):
         self.app.get('/p/_nav.json')
 
 
-@with_nose_compatibility
 class TestPhoneVerificationOnProjectRegistration(TestController):
     def test_phone_verification_fragment_renders(self):
         self.app.get('/p/phone_verification_fragment', status=200)
@@ -1114,7 +1111,6 @@ class TestPhoneVerificationOnProjectRegistration(TestController):
             assert iframe.get('src') == '/p/phone_verification_fragment'
 
 
-@with_nose_compatibility
 class TestProjectImport(TestController):
 
     def test_not_found(self):
diff --git a/Allura/allura/tests/functional/test_newforge.py b/Allura/allura/tests/functional/test_newforge.py
index 83470c1e4..9dfabe614 100644
--- a/Allura/allura/tests/functional/test_newforge.py
+++ b/Allura/allura/tests/functional/test_newforge.py
@@ -21,10 +21,8 @@ from six.moves.urllib.parse import quote
 from allura.tests import TestController
 from allura.tests import decorators as td
 from allura import model as M
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestNewForgeController(TestController):
 
     @td.with_wiki
diff --git a/Allura/allura/tests/functional/test_personal_dashboard.py b/Allura/allura/tests/functional/test_personal_dashboard.py
index 06c73dea7..8cdae92ab 100644
--- a/Allura/allura/tests/functional/test_personal_dashboard.py
+++ b/Allura/allura/tests/functional/test_personal_dashboard.py
@@ -29,10 +29,8 @@ from allura.tests import TestController
 from allura.tests import decorators as td
 from alluratest.controller import setup_global_objects, setup_unit_test
 from forgetracker.tests.functional.test_root import TrackerTestController
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestPersonalDashboard(TestController):
 
     def test_dashboard(self):
@@ -69,7 +67,6 @@ class TestPersonalDashboard(TestController):
                 assert 'Section f' not in r.text
 
 
-@with_nose_compatibility
 class TestTicketsSection(TrackerTestController):
 
     @td.with_tracker
@@ -85,7 +82,6 @@ class TestTicketsSection(TrackerTestController):
         assert 'foo' in str(ticket_rows)
 
 
-@with_nose_compatibility
 class TestMergeRequestsSection(TestController):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 26d3b5620..265cfcd12 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -30,10 +30,8 @@ from alluratest.controller import TestRestApiBase
 from allura.lib import helpers as h
 from allura.lib.exceptions import Invalid
 from allura import model as M
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestRestHome(TestRestApiBase):
 
     def _patch_token(self, OAuthAccessToken):
@@ -416,7 +414,6 @@ class TestRestHome(TestRestApiBase):
         assert r.json == {}
 
 
-@with_nose_compatibility
 class TestRestNbhdAddProject(TestRestApiBase):
 
     def setup_method(self, method):
@@ -559,7 +556,6 @@ class TestRestNbhdAddProject(TestRestApiBase):
         }
 
 
-@with_nose_compatibility
 class TestDoap(TestRestApiBase):
     validate_skip = True
     ns = '{http://usefulinc.com/ns/doap#}'
@@ -625,7 +621,6 @@ class TestDoap(TestRestApiBase):
         assert ('Tickets', 'http://localhost/p/test/private-bugs/') not in tools
 
 
-@with_nose_compatibility
 class TestUserProfile(TestRestApiBase):
     @td.with_user_project('test-admin')
     def test_profile_data(self):
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index ff196261e..6b5f56ca3 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -40,10 +40,8 @@ from allura.tests import TestController
 from allura import model as M
 from allura.lib import helpers as h
 from alluratest.controller import setup_trove_categories
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestRootController(TestController):
 
     def setup_method(self, method):
@@ -215,7 +213,6 @@ class TestRootController(TestController):
                in resp.headers.getall('Content-Security-Policy')[0]
 
 
-@with_nose_compatibility
 class TestRootWithSSLPattern(TestController):
     def setup_method(self, method):
         with td.patch_middleware_config({'force_ssl.pattern': '^/auth'}):
diff --git a/Allura/allura/tests/functional/test_search.py b/Allura/allura/tests/functional/test_search.py
index a24bc0497..3a1a72b44 100644
--- a/Allura/allura/tests/functional/test_search.py
+++ b/Allura/allura/tests/functional/test_search.py
@@ -24,10 +24,8 @@ from allura.tests import TestController
 from allura.tests.decorators import with_tool
 
 from forgewiki.model import Page
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestSearch(TestController):
 
     @patch('allura.lib.search.search')
diff --git a/Allura/allura/tests/functional/test_site_admin.py b/Allura/allura/tests/functional/test_site_admin.py
index 788fb4fed..f4cb04855 100644
--- a/Allura/allura/tests/functional/test_site_admin.py
+++ b/Allura/allura/tests/functional/test_site_admin.py
@@ -31,10 +31,8 @@ from allura.tests import decorators as td
 from allura.lib import helpers as h
 from allura.lib.decorators import task
 from allura.lib.plugin import LocalAuthenticationProvider
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestSiteAdmin(TestController):
 
     def test_access(self):
@@ -184,7 +182,6 @@ class TestSiteAdmin(TestController):
         assert json.loads(r.text)['doc'] == 'test_task doc string'
 
 
-@with_nose_compatibility
 class TestSiteAdminNotifications(TestController):
 
     def test_site_notifications_access(self):
@@ -338,7 +335,6 @@ class TestSiteAdminNotifications(TestController):
         assert M.notification.SiteNotification.query.get(_id=bson.ObjectId(note._id)) is None
 
 
-@with_nose_compatibility
 class TestProjectsSearch(TestController):
 
     TEST_HIT = MagicMock(hits=1, docs=[{
@@ -393,7 +389,6 @@ class TestProjectsSearch(TestController):
         assert ths == ['Short name', 'Full name', 'Registered', 'Deleted?', 'url', 'Details']
 
 
-@with_nose_compatibility
 class TestUsersSearch(TestController):
 
     TEST_HIT = MagicMock(hits=1, docs=[{
@@ -449,7 +444,6 @@ class TestUsersSearch(TestController):
                            'Status', 'url', 'Details']
 
 
-@with_nose_compatibility
 class TestUserDetails(TestController):
 
     def test_404(self):
@@ -745,7 +739,6 @@ To update your password on %s, please visit the following URL:
         assert hash in r.text
 
 
-@with_nose_compatibility
 class TestDeleteProjects(TestController):
 
     def confirm_form(self, r):
diff --git a/Allura/allura/tests/functional/test_static.py b/Allura/allura/tests/functional/test_static.py
index 38e4ba760..4d530a57a 100644
--- a/Allura/allura/tests/functional/test_static.py
+++ b/Allura/allura/tests/functional/test_static.py
@@ -17,10 +17,8 @@
 
 
 from allura.tests import TestController
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestStaticFilesMiddleware(TestController):
 
     # this tests StaticFilesMiddleware
diff --git a/Allura/allura/tests/functional/test_subscriber.py b/Allura/allura/tests/functional/test_subscriber.py
index 32333f92d..93b822e60 100644
--- a/Allura/allura/tests/functional/test_subscriber.py
+++ b/Allura/allura/tests/functional/test_subscriber.py
@@ -19,10 +19,8 @@ from allura.tests import TestController
 from allura.tests import decorators as td
 from allura.model.notification import Mailbox
 from allura import model as M
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestSubscriber(TestController):
 
     @td.with_user_project('test-admin')
diff --git a/Allura/allura/tests/functional/test_tool_list.py b/Allura/allura/tests/functional/test_tool_list.py
index 3562463b4..7f43bea5e 100644
--- a/Allura/allura/tests/functional/test_tool_list.py
+++ b/Allura/allura/tests/functional/test_tool_list.py
@@ -17,10 +17,8 @@
 
 from allura.tests import TestController
 from allura.tests import decorators as td
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestToolListController(TestController):
 
     @td.with_wiki
diff --git a/Allura/allura/tests/functional/test_trovecategory.py b/Allura/allura/tests/functional/test_trovecategory.py
index ae9057dd3..5067d586d 100644
--- a/Allura/allura/tests/functional/test_trovecategory.py
+++ b/Allura/allura/tests/functional/test_trovecategory.py
@@ -25,10 +25,8 @@ from allura.lib import helpers as h
 from allura.tests import TestController
 from alluratest.controller import setup_trove_categories
 from allura.tests import decorators as td
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestTroveCategory(TestController):
     @mock.patch('allura.model.project.g.post_event')
     def test_events(self, post_event):
@@ -82,7 +80,6 @@ class TestTroveCategory(TestController):
             check_access(username='root', status=200)
 
 
-@with_nose_compatibility
 class TestTroveCategoryController(TestController):
     def create_some_cats(self):
         root_parent = M.TroveCategory(fullname="Root", trove_cat_id=1, trove_parent_id=0)
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 2a5e8674d..0b93bdd42 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -22,7 +22,6 @@ from alluratest.controller import TestRestApiBase
 from allura.model import Project, User
 from allura.tests import decorators as td
 from allura.tests import TestController
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 class TestUserProfileSections(TestController):
@@ -65,7 +64,6 @@ class TestUserProfileSections(TestController):
         assert 'Section f' not in r.text
 
 
-@with_nose_compatibility
 class TestUserProfile(TestController):
 
     @td.with_user_project('test-admin')
@@ -278,7 +276,6 @@ class TestUserProfile(TestController):
         assert 'content="noindex, follow"' not in r.text
 
 
-@with_nose_compatibility
 class TestUserProfileHasAccessAPI(TestRestApiBase):
 
     @td.with_user_project('test-admin')
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 7b6364938..2e77f7486 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -34,7 +34,6 @@ from allura.lib import helpers as h
 from allura.lib import plugin
 from allura.tests import decorators as td
 from alluratest.controller import setup_basic_test, setup_global_objects, setup_functional_test, setup_unit_test
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 class TestAuth:
@@ -423,7 +422,6 @@ class TestAuth:
         assert details[1].ua == 'TestBrowser/57'
 
 
-@with_nose_compatibility
 class TestAuditLog:
 
     @classmethod
diff --git a/Allura/allura/tests/model/test_filesystem.py b/Allura/allura/tests/model/test_filesystem.py
index 5625df27d..70ccdedb4 100644
--- a/Allura/allura/tests/model/test_filesystem.py
+++ b/Allura/allura/tests/model/test_filesystem.py
@@ -27,7 +27,6 @@ from webob import Request, Response
 
 from allura import model as M
 from alluratest.controller import setup_unit_test
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 class File(M.File):
@@ -37,7 +36,6 @@ class File(M.File):
 Mapper.compile_all()
 
 
-@with_nose_compatibility
 class TestFile(TestCase):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/model/test_notification.py b/Allura/allura/tests/model/test_notification.py
index 774c8dae7..3a2ba9cf8 100644
--- a/Allura/allura/tests/model/test_notification.py
+++ b/Allura/allura/tests/model/test_notification.py
@@ -30,10 +30,8 @@ from allura.model.notification import MailFooter
 from allura.lib import helpers as h
 from allura.tests import decorators as td
 from forgewiki import model as WM
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestNotification(unittest.TestCase):
 
     def setup_method(self, method):
@@ -165,7 +163,6 @@ class TestNotification(unittest.TestCase):
         )
 
 
-@with_nose_compatibility
 class TestPostNotifications(unittest.TestCase):
 
     def setup_method(self, method):
@@ -304,7 +301,6 @@ class TestPostNotifications(unittest.TestCase):
         return M.Notification.post(self.pg, 'metadata')
 
 
-@with_nose_compatibility
 class TestSubscriptionTypes(unittest.TestCase):
 
     def setup_method(self, method):
@@ -478,7 +474,6 @@ class TestSubscriptionTypes(unittest.TestCase):
         assert count == 1
 
 
-@with_nose_compatibility
 class TestSiteNotification(unittest.TestCase):
     def setup_method(self, method):
         self.note = M.SiteNotification(
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index b5fffdaa1..9b89a6805 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -28,10 +28,8 @@ from tg import config
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura import model as M
 from allura.lib import helpers as h
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestGitLikeTree:
     def test_set_blob(self):
         tree = M.GitLikeTree()
@@ -129,7 +127,6 @@ class RepoTestBase(unittest.TestCase):
         ]
 
 
-@with_nose_compatibility
 class TestLastCommit(unittest.TestCase):
     def setup_method(self, method):
         setup_basic_test()
@@ -402,7 +399,6 @@ class TestLastCommit(unittest.TestCase):
         self.assertEqual(lcd.by_name['file2'], commit3._id)
 
 
-@with_nose_compatibility
 class TestModelCache(unittest.TestCase):
     def setup_method(self, method):
         self.cache = M.repository.ModelCache()
@@ -681,7 +677,6 @@ class TestModelCache(unittest.TestCase):
         session.return_value.expunge.assert_called_once_with(tree1)
 
 
-@with_nose_compatibility
 class TestMergeRequest:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/model/test_timeline.py b/Allura/allura/tests/model/test_timeline.py
index f5af23bb1..ad1b252af 100644
--- a/Allura/allura/tests/model/test_timeline.py
+++ b/Allura/allura/tests/model/test_timeline.py
@@ -18,10 +18,8 @@
 from allura import model as M
 from allura.tests import decorators as td
 from alluratest.controller import setup_basic_test, setup_global_objects
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestActivityObject_Functional:
     # NOTE not for unit tests, this class sets up all the junk
 
diff --git a/Allura/allura/tests/scripts/test_create_sitemap_files.py b/Allura/allura/tests/scripts/test_create_sitemap_files.py
index 906ff600b..8097f169e 100644
--- a/Allura/allura/tests/scripts/test_create_sitemap_files.py
+++ b/Allura/allura/tests/scripts/test_create_sitemap_files.py
@@ -26,10 +26,8 @@ from alluratest.controller import setup_basic_test
 from allura import model as M
 from allura.lib import helpers as h
 from allura.scripts.create_sitemap_files import CreateSitemapFiles
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestCreateSitemapFiles:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/scripts/test_delete_projects.py b/Allura/allura/tests/scripts/test_delete_projects.py
index 12d6d69b5..0716cc700 100644
--- a/Allura/allura/tests/scripts/test_delete_projects.py
+++ b/Allura/allura/tests/scripts/test_delete_projects.py
@@ -24,10 +24,8 @@ from allura.tests.decorators import audits, out_audits, with_user_project
 from allura import model as M
 from allura.scripts import delete_projects
 from allura.lib import plugin
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestDeleteProjects(TestController):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/scripts/test_misc_scripts.py b/Allura/allura/tests/scripts/test_misc_scripts.py
index 174bf9c52..2ec6c2583 100644
--- a/Allura/allura/tests/scripts/test_misc_scripts.py
+++ b/Allura/allura/tests/scripts/test_misc_scripts.py
@@ -21,10 +21,8 @@ from allura.scripts.clear_old_notifications import ClearOldNotifications
 from alluratest.controller import setup_basic_test
 from allura import model as M
 from ming.odm import session
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestClearOldNotifications:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/scripts/test_reindexes.py b/Allura/allura/tests/scripts/test_reindexes.py
index e1f995078..ff6339093 100644
--- a/Allura/allura/tests/scripts/test_reindexes.py
+++ b/Allura/allura/tests/scripts/test_reindexes.py
@@ -21,10 +21,8 @@ from allura.scripts.reindex_users import ReindexUsers
 from allura.tests.decorators import assert_logmsg_and_no_warnings_or_errors
 from alluratest.controller import setup_basic_test
 from allura import model as M
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestReindexProjects:
 
     def setup_method(self, method):
@@ -49,7 +47,6 @@ class TestReindexProjects:
         assert M.MonQTask.query.find({'task_name': 'allura.tasks.index_tasks.add_projects'}).count() == 1
 
 
-@with_nose_compatibility
 class TestReindexUsers:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/templates/jinja_master/test_lib.py b/Allura/allura/tests/templates/jinja_master/test_lib.py
index 84108aaa5..4f294e3c7 100644
--- a/Allura/allura/tests/templates/jinja_master/test_lib.py
+++ b/Allura/allura/tests/templates/jinja_master/test_lib.py
@@ -20,7 +20,6 @@ from mock import Mock
 
 from allura.config.app_cfg import AlluraJinjaRenderer
 from alluratest.controller import setup_basic_test
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 def strip_space(s):
@@ -33,7 +32,6 @@ class TemplateTest:
         self.jinja2_env = AlluraJinjaRenderer.create(config, g)['jinja'].jinja2_env
 
 
-@with_nose_compatibility
 class TestRelatedArtifacts(TemplateTest):
 
     def _render_related_artifacts(self, artifact):
diff --git a/Allura/allura/tests/test_commands.py b/Allura/allura/tests/test_commands.py
index 9e13f60cb..fadd8ad09 100644
--- a/Allura/allura/tests/test_commands.py
+++ b/Allura/allura/tests/test_commands.py
@@ -33,7 +33,6 @@ from allura.command import base, script, set_neighborhood_features, \
 from allura import model as M
 from allura.lib.exceptions import InvalidNBFeatureValueError
 from allura.tests import decorators as td
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 test_config = pkg_resources.resource_filename(
@@ -182,7 +181,6 @@ def test_update_neighborhood():
     assert nb.has_home_tool is False
 
 
-@with_nose_compatibility
 class TestEnsureIndexCommand:
 
     def test_run(self):
@@ -269,7 +267,6 @@ class TestEnsureIndexCommand:
         ]
 
 
-@with_nose_compatibility
 class TestTaskCommand:
 
     def teardown_method(self, method):
@@ -336,7 +333,6 @@ class TestTaskCommand:
         assert M.MonQTask.query.find().count() == 0
 
 
-@with_nose_compatibility
 class TestTaskdCleanupCommand:
 
     def setup_method(self, method):
@@ -451,7 +447,6 @@ def test_status_log_retries():
     assert cmd._taskd_status.mock_calls == expected_calls
 
 
-@with_nose_compatibility
 class TestShowModels:
 
     def test_show_models(self):
@@ -463,7 +458,6 @@ class TestShowModels:
          - <FieldProperty content>
         ''' in output.captured
 
-@with_nose_compatibility
 class TestReindexAsTask:
 
     cmd = 'allura.command.show_models.ReindexCommand'
@@ -498,7 +492,6 @@ class TestReindexAsTask:
             M.MonQTask.query.remove()
 
 
-@with_nose_compatibility
 class TestReindexCommand:
 
     @patch('allura.command.show_models.g')
diff --git a/Allura/allura/tests/test_decorators.py b/Allura/allura/tests/test_decorators.py
index 2ef77cd8c..80c3bd46e 100644
--- a/Allura/allura/tests/test_decorators.py
+++ b/Allura/allura/tests/test_decorators.py
@@ -20,12 +20,10 @@ from mock import patch
 import random
 import gc
 
-from alluratest.pytest_helpers import with_nose_compatibility
 from allura.lib.decorators import task, memoize
 from alluratest.controller import setup_basic_test, setup_global_objects
 
 
-@with_nose_compatibility
 class TestTask(TestCase):
 
     def setup_method(self, method):
@@ -63,7 +61,6 @@ class TestTask(TestCase):
         func.post('test', foo=2, delay=1)
 
 
-@with_nose_compatibility
 class TestMemoize:
 
     def test_function(self):
diff --git a/Allura/allura/tests/test_diff.py b/Allura/allura/tests/test_diff.py
index 1485bc1a8..e70b7d6d0 100644
--- a/Allura/allura/tests/test_diff.py
+++ b/Allura/allura/tests/test_diff.py
@@ -18,10 +18,8 @@
 import unittest
 
 from allura.lib.diff import HtmlSideBySideDiff
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestHtmlSideBySideDiff(unittest.TestCase):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/test_dispatch.py b/Allura/allura/tests/test_dispatch.py
index 983ffac72..5e48ec2fd 100644
--- a/Allura/allura/tests/test_dispatch.py
+++ b/Allura/allura/tests/test_dispatch.py
@@ -16,12 +16,10 @@
 #       under the License.
 
 from allura.tests import TestController
-from alluratest.pytest_helpers import with_nose_compatibility
 
 app = None
 
 
-@with_nose_compatibility
 class TestDispatch(TestController):
 
     validate_skip = True
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 29b318027..01a48daf1 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -43,7 +43,6 @@ from allura import model as M
 from allura.lib import helpers as h
 from allura.lib.app_globals import ForgeMarkdown
 from allura.tests import decorators as td
-from alluratest.pytest_helpers import with_nose_compatibility
 
 from forgewiki import model as WM
 from forgeblog import model as BM
@@ -77,7 +76,6 @@ def get_projects_property_in_the_same_order(names, prop):
     return [projects_dict[name] for name in names]
 
 
-@with_nose_compatibility
 class Test():
 
     @classmethod
@@ -787,7 +785,6 @@ class Test():
             assert 'src="/p/test/screenshot/test_file.jpg/thumb"' in r
 
 
-@with_nose_compatibility
 class TestCachedMarkdown(unittest.TestCase):
 
     def setup_method(self, method):
@@ -905,7 +902,6 @@ class TestCachedMarkdown(unittest.TestCase):
         self.assertEqual(required_keys, keys)
 
 
-@with_nose_compatibility
 class TestEmojis(unittest.TestCase):
 
     def test_markdown_emoji_atomic(self):
@@ -941,7 +937,6 @@ class TestEmojis(unittest.TestCase):
         assert 'More emojis \U0001F44D\U0001F42B\U0001F552 wow!' in output
 
 
-@with_nose_compatibility
 class TestUserMentions(unittest.TestCase):
 
     def test_markdown_user_mention_default(self):
@@ -983,7 +978,6 @@ class TestUserMentions(unittest.TestCase):
         assert 'class="user-mention"' in output
 
 
-@with_nose_compatibility
 class TestHandlePaging(unittest.TestCase):
 
     def setup_method(self, method):
@@ -1044,7 +1038,6 @@ class TestHandlePaging(unittest.TestCase):
         self.assertEqual(g.handle_paging(10, 'asdf', 30), (10, 0, 0))
 
 
-@with_nose_compatibility
 class TestIconRender:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 46703b142..571d33fea 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -37,7 +37,6 @@ from allura.lib.search import inject_user
 from allura.lib.security import has_access
 from allura.lib.security import Credentials
 from allura.tests import decorators as td
-from alluratest.pytest_helpers import with_nose_compatibility
 from alluratest.controller import setup_basic_test
 import six
 
@@ -47,7 +46,6 @@ def setup_module():
     setup_basic_test()
 
 
-@with_nose_compatibility
 class TestMakeSafePathPortion(TestCase):
 
     def setup_method(self, method):
@@ -454,7 +452,6 @@ back\\\-slash escaped
         r'tab before \(stuff\)'
 
 
-@with_nose_compatibility
 class TestUrlOpen(TestCase):
 
     @patch('six.moves.urllib.request.urlopen')
@@ -531,7 +528,6 @@ def test_login_overlay():
             raise HTTPUnauthorized()
 
 
-@with_nose_compatibility
 class TestIterEntryPoints(TestCase):
 
     def _make_ep(self, name, cls):
@@ -636,7 +632,6 @@ def test_slugify():
     assert h.slugify('Foo.Bar', True)[0] == 'Foo.Bar'
 
 
-@with_nose_compatibility
 class TestRateLimit(TestCase):
     rate_limits = '{"60": 1, "120": 3, "900": 5, "1800": 7, "3600": 10, "7200": 15, "86400": 20, "604800": 50, "2592000": 200}'
     key_comment = 'allura.rate_limits_per_user'
diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py
index acc4c22dd..872117cf5 100644
--- a/Allura/allura/tests/test_mail_util.py
+++ b/Allura/allura/tests/test_mail_util.py
@@ -37,7 +37,6 @@ from allura.lib.mail_util import (
     _parse_message_id,
 )
 from allura.lib.exceptions import AddressException
-from alluratest.pytest_helpers import with_nose_compatibility
 from allura.tests import decorators as td
 
 
@@ -46,7 +45,6 @@ config = ConfigProxy(
     return_path='forgemail.return_path')
 
 
-@with_nose_compatibility
 class TestReactor(unittest.TestCase):
 
     def setup_method(self, method):
@@ -211,7 +209,6 @@ Content-Type: text/html; charset="utf-8"
             assert isinstance(part['payload'], str), type(part['payload'])
 
 
-@with_nose_compatibility
 class TestHeader:
 
     def test_bytestring(self):
@@ -233,7 +230,6 @@ class TestHeader:
                      '=?utf-8?b?ItGC0LXRgdC90Y/RgtGB0Y8i?= <da...@b.com>')
 
 
-@with_nose_compatibility
 class TestIsAutoreply:
 
     def setup_method(self, method):
@@ -280,7 +276,6 @@ class TestIsAutoreply:
         assert is_autoreply(self.msg)
 
 
-@with_nose_compatibility
 class TestIdentifySender:
 
     @mock.patch('allura.model.EmailAddress')
@@ -330,7 +325,6 @@ def test_parse_message_id():
     ]
 
 
-@with_nose_compatibility
 class TestMailServer:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/test_markdown.py b/Allura/allura/tests/test_markdown.py
index 6878143f1..992eec8b0 100644
--- a/Allura/allura/tests/test_markdown.py
+++ b/Allura/allura/tests/test_markdown.py
@@ -19,10 +19,8 @@ import unittest
 import mock
 
 from allura.lib import markdown_extensions as mde
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestTracRef1(unittest.TestCase):
 
     @mock.patch('allura.lib.markdown_extensions.M.Shortlink.lookup')
@@ -49,7 +47,6 @@ class TestTracRef1(unittest.TestCase):
                          '[r123](/p/project/tool/artifact)')
 
 
-@with_nose_compatibility
 class TestTracRef2(unittest.TestCase):
 
     @mock.patch('allura.lib.markdown_extensions.M.Shortlink.lookup')
@@ -79,7 +76,6 @@ class TestTracRef2(unittest.TestCase):
                          '[comment:13:ticket:100](/p/project/tool/artifact/)')
 
 
-@with_nose_compatibility
 class TestTracRef3(unittest.TestCase):
 
     def test_no_app_context(self):
@@ -98,7 +94,6 @@ class TestTracRef3(unittest.TestCase):
                          '[source:file.py#L456](/p/project/tool/HEAD/tree/file.py#l456)')
 
 
-@with_nose_compatibility
 class TestPatternReplacingProcessor(unittest.TestCase):
 
     @mock.patch('allura.lib.markdown_extensions.M.Shortlink.lookup')
@@ -113,7 +108,6 @@ class TestPatternReplacingProcessor(unittest.TestCase):
             '[ticket:100](/p/project/tool/artifact)'])
 
 
-@with_nose_compatibility
 class TestCommitMessageExtension(unittest.TestCase):
 
     @mock.patch('allura.lib.markdown_extensions.TracRef2.get_comment_slug')
diff --git a/Allura/allura/tests/test_middlewares.py b/Allura/allura/tests/test_middlewares.py
index 2435ba8d3..5a2e5c1b2 100644
--- a/Allura/allura/tests/test_middlewares.py
+++ b/Allura/allura/tests/test_middlewares.py
@@ -17,10 +17,8 @@
 
 from mock import MagicMock, patch
 from allura.lib.custom_middleware import CORSMiddleware
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestCORSMiddleware:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/test_multifactor.py b/Allura/allura/tests/test_multifactor.py
index 3ce6fdb31..42b8c6ce9 100644
--- a/Allura/allura/tests/test_multifactor.py
+++ b/Allura/allura/tests/test_multifactor.py
@@ -32,10 +32,8 @@ from allura.lib.multifactor import GoogleAuthenticatorFile, TotpService, Mongodb
 from allura.lib.multifactor import GoogleAuthenticatorPamFilesystemTotpService
 from allura.lib.multifactor import RecoveryCodeService, MongodbRecoveryCodeService
 from allura.lib.multifactor import GoogleAuthenticatorPamFilesystemRecoveryCodeService
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestGoogleAuthenticatorFile:
     sample = textwrap.dedent('''\
         7CL3WL756ISQCU5HRVNAODC44Q
@@ -82,7 +80,6 @@ class GenericTotpService(TotpService):
         pass
 
 
-@with_nose_compatibility
 class TestTotpService:
 
     sample_key = b'\x00K\xda\xbfv\xc2B\xaa\x1a\xbe\xa5\x96b\xb2\xa0Z:\xc9\xcf\x8a'
@@ -127,7 +124,6 @@ class TestTotpService:
         assert srv.get_qr_code(totp, user)
 
 
-@with_nose_compatibility
 class TestAnyTotpServiceImplementation:
 
     __test__ = False
@@ -175,7 +171,6 @@ class TestAnyTotpServiceImplementation:
             srv.verify(totp, '283397', user)
 
 
-@with_nose_compatibility
 class TestMongodbTotpService(TestAnyTotpServiceImplementation):
 
     __test__ = True
@@ -188,7 +183,6 @@ class TestMongodbTotpService(TestAnyTotpServiceImplementation):
         ming.configure(**config)
 
 
-@with_nose_compatibility
 class TestGoogleAuthenticatorPamFilesystemMixin:
 
     def setup_method(self, method):
@@ -200,7 +194,6 @@ class TestGoogleAuthenticatorPamFilesystemMixin:
             shutil.rmtree(self.totp_basedir)
 
 
-@with_nose_compatibility
 class TestGoogleAuthenticatorPamFilesystemTotpService(TestAnyTotpServiceImplementation,
                                                       TestGoogleAuthenticatorPamFilesystemMixin):
 
@@ -214,7 +207,6 @@ class TestGoogleAuthenticatorPamFilesystemTotpService(TestAnyTotpServiceImplemen
         super().test_rate_limiting()
 
 
-@with_nose_compatibility
 class TestRecoveryCodeService:
 
     def test_generate_one_code(self):
@@ -237,7 +229,6 @@ class TestRecoveryCodeService:
         assert len(recovery.saved_codes) == asint(config.get('auth.multifactor.recovery_code.count', 10))
 
 
-@with_nose_compatibility
 class TestAnyRecoveryCodeServiceImplementation:
 
     __test__ = False
@@ -305,7 +296,6 @@ class TestAnyRecoveryCodeServiceImplementation:
             recovery.verify_and_remove_code(user, '22222')
 
 
-@with_nose_compatibility
 class TestMongodbRecoveryCodeService(TestAnyRecoveryCodeServiceImplementation):
 
     __test__ = True
@@ -319,7 +309,6 @@ class TestMongodbRecoveryCodeService(TestAnyRecoveryCodeServiceImplementation):
         ming.configure(**config)
 
 
-@with_nose_compatibility
 class TestGoogleAuthenticatorPamFilesystemRecoveryCodeService(TestAnyRecoveryCodeServiceImplementation,
                                                               TestGoogleAuthenticatorPamFilesystemMixin):
 
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index 49206ba64..c6c78fc77 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -37,14 +37,12 @@ from allura.lib.exceptions import ProjectConflict, ProjectShortnameInvalid
 from allura.tests.decorators import audits
 from allura.tests.exclude_from_rewrite_hook import ThemeProviderTestApp
 from alluratest.controller import setup_basic_test, setup_global_objects
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 def setup_module(module):
     setup_basic_test()
 
 
-@with_nose_compatibility
 class TestProjectRegistrationProvider:
 
     def setup_method(self, method):
@@ -82,7 +80,6 @@ class TestProjectRegistrationProvider:
         pytest.raises(ProjectConflict, v, 'thisislegit', neighborhood=nbhd)
 
 
-@with_nose_compatibility
 class TestProjectRegistrationProviderParseProjectFromUrl:
 
     def setup_method(self, method):
@@ -157,7 +154,6 @@ class UserMock:
         return self._projects
 
 
-@with_nose_compatibility
 class TestProjectRegistrationProviderPhoneVerification:
 
     def setup_method(self, method):
@@ -275,7 +271,6 @@ class TestProjectRegistrationProviderPhoneVerification:
             assert 5 == g.phone_service.verify.call_count
 
 
-@with_nose_compatibility
 class TestThemeProvider:
 
     @patch('allura.app.g')
@@ -301,7 +296,6 @@ class TestThemeProvider:
         g.theme_href.assert_called_with('images/testapp_24.png')
 
 
-@with_nose_compatibility
 class TestThemeProvider_notifications:
 
     Provider = ThemeProvider
@@ -623,7 +617,6 @@ class TestThemeProvider_notifications:
         assert get_note[1] == 'testid-2-False'
 
 
-@with_nose_compatibility
 class TestLocalAuthenticationProvider:
 
     def setup_method(self, method):
@@ -738,7 +731,6 @@ class TestLocalAuthenticationProvider:
         assert detail.ua == 'mybrowser'
 
 
-@with_nose_compatibility
 class TestAuthenticationProvider:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/test_scripttask.py b/Allura/allura/tests/test_scripttask.py
index ae284a1e9..9992498a5 100644
--- a/Allura/allura/tests/test_scripttask.py
+++ b/Allura/allura/tests/test_scripttask.py
@@ -19,10 +19,8 @@ import unittest
 import mock
 
 from allura.scripts.scripttask import ScriptTask
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestScriptTask(unittest.TestCase):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/test_security.py b/Allura/allura/tests/test_security.py
index fea9bc54d..7a27b9302 100644
--- a/Allura/allura/tests/test_security.py
+++ b/Allura/allura/tests/test_security.py
@@ -28,7 +28,6 @@ from forgewiki import model as WM
 from allura.lib.security import HIBPClientError, HIBPClient
 from mock import Mock, patch
 from requests.exceptions import Timeout
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 def _allow(obj, role, perm):
@@ -55,7 +54,6 @@ def test_check_breached_password(r_get):
         HIBPClient.check_breached_password('qwerty')
 
 
-@with_nose_compatibility
 class TestSecurity(TestController):
 
     validate_skip = True
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 80fffbb8c..3acd939b9 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -47,12 +47,10 @@ from allura.tasks import repo_tasks
 from allura.tasks import export_tasks
 from allura.tasks import admin_tasks
 from allura.tests import decorators as td
-from alluratest.pytest_helpers import with_nose_compatibility
 from allura.tests.exclude_from_rewrite_hook import raise_compound_exception
 from allura.lib.decorators import event_handler, task
 
 
-@with_nose_compatibility
 class TestRepoTasks(unittest.TestCase):
 
     def setup_method(self, method):
@@ -101,7 +99,6 @@ def _task_that_creates_event(event_name,):
     assert not M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=[event_name])
 
 
-@with_nose_compatibility
 class TestEventTasks(unittest.TestCase):
 
     def setup_method(self, method):
@@ -160,7 +157,6 @@ class TestEventTasks(unittest.TestCase):
             assert ('assert %d' % x) in t.result
 
 
-@with_nose_compatibility
 class TestIndexTasks(unittest.TestCase):
 
     def setup_method(self, method):
@@ -246,7 +242,6 @@ class TestIndexTasks(unittest.TestCase):
         solr.delete.assert_called_once_with(q=solr_query)
 
 
-@with_nose_compatibility
 class TestMailTasks(unittest.TestCase):
 
     def setup_method(self, method):
@@ -543,7 +538,6 @@ class TestMailTasks(unittest.TestCase):
             assert hm.call_count == 0
 
 
-@with_nose_compatibility
 class TestUserNotificationTasks(TestController):
     def setup_method(self, method):
         super().setup_method(method)
@@ -575,7 +569,6 @@ class TestUserNotificationTasks(TestController):
         assert 'auth/subscriptions#notifications' in text
 
 
-@with_nose_compatibility
 class TestNotificationTasks(unittest.TestCase):
 
     def setup_method(self, method):
@@ -611,7 +604,6 @@ class _TestArtifact(M.Artifact):
             text=self.text)
 
 
-@with_nose_compatibility
 class TestExportTasks(unittest.TestCase):
 
     def setup_method(self, method):
@@ -666,7 +658,6 @@ class TestExportTasks(unittest.TestCase):
         assert c.project.bulk_export_status() == 'busy'
 
 
-@with_nose_compatibility
 class TestAdminTasks(unittest.TestCase):
 
     def test_install_app_docstring(self):
diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py
index 5afc2c9b8..d9f5229a9 100644
--- a/Allura/allura/tests/test_utils.py
+++ b/Allura/allura/tests/test_utils.py
@@ -39,11 +39,9 @@ from alluratest.controller import setup_unit_test
 from allura import model as M
 from allura.lib import utils
 from allura.lib import helpers as h
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 @patch.dict('allura.lib.utils.tg.config', clear=True, foo='bar', baz='true')
-@with_nose_compatibility
 class TestConfigProxy(unittest.TestCase):
 
     def setup_method(self, method):
@@ -64,7 +62,6 @@ class TestConfigProxy(unittest.TestCase):
         self.assertEqual(self.cp.get_bool("fake"), False)
 
 
-@with_nose_compatibility
 class TestChunkedIterator(unittest.TestCase):
 
     def setup_method(self, method):
@@ -96,7 +93,6 @@ class TestChunkedIterator(unittest.TestCase):
         assert chunks[1][0].username == 'sample-user-3'
 
 
-@with_nose_compatibility
 class TestChunkedList(unittest.TestCase):
 
     def test_chunked_list(self):
@@ -107,7 +103,6 @@ class TestChunkedList(unittest.TestCase):
         self.assertEqual([el for sublist in chunks for el in sublist], l)
 
 
-@with_nose_compatibility
 class TestAntispam(unittest.TestCase):
 
     def setup_method(self, method):
@@ -174,7 +169,6 @@ class TestAntispam(unittest.TestCase):
         return encrypted_form
 
 
-@with_nose_compatibility
 class TestTruthyCallable(unittest.TestCase):
 
     def test_everything(self):
@@ -196,7 +190,6 @@ class TestTruthyCallable(unittest.TestCase):
         assert false_predicate == f
 
 
-@with_nose_compatibility
 class TestCaseInsensitiveDict(unittest.TestCase):
 
     def test_everything(self):
@@ -216,7 +209,6 @@ class TestCaseInsensitiveDict(unittest.TestCase):
         assert d == utils.CaseInsensitiveDict(Foo=1, bar=2)
 
 
-@with_nose_compatibility
 class TestLineAnchorCodeHtmlFormatter(unittest.TestCase):
 
     def test_render(self):
@@ -237,7 +229,6 @@ class TestLineAnchorCodeHtmlFormatter(unittest.TestCase):
             assert '<span class="linenos">1</span>' in hl_code
 
 
-@with_nose_compatibility
 class TestIsTextFile(unittest.TestCase):
 
     def test_is_text_file(self):
@@ -248,7 +239,6 @@ class TestIsTextFile(unittest.TestCase):
         assert not utils.is_text_file(open(bin_file, 'rb').read())
 
 
-@with_nose_compatibility
 class TestCodeStats(unittest.TestCase):
 
     def setup_method(self, method):
@@ -273,7 +263,6 @@ class TestCodeStats(unittest.TestCase):
         assert stats['code_size'] == len(blob.text)
 
 
-@with_nose_compatibility
 class TestHTMLSanitizer(unittest.TestCase):
 
     def walker_from_text(self, text):
diff --git a/Allura/allura/tests/test_validators.py b/Allura/allura/tests/test_validators.py
index a9c011368..fb3dbb008 100644
--- a/Allura/allura/tests/test_validators.py
+++ b/Allura/allura/tests/test_validators.py
@@ -24,7 +24,6 @@ from allura.lib import validators as v
 from allura.lib.decorators import task
 from alluratest.controller import setup_basic_test
 from allura.websetup.bootstrap import create_user
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 def _setup_method():
@@ -36,7 +35,6 @@ def dummy_task(*args, **kw):
     pass
 
 
-@with_nose_compatibility
 class TestJsonConverter(unittest.TestCase):
     val = v.JsonConverter
 
@@ -53,7 +51,6 @@ class TestJsonConverter(unittest.TestCase):
             self.val.to_python('3')
 
 
-@with_nose_compatibility
 class TestJsonFile(unittest.TestCase):
 
     def setup_method(self, method):
@@ -74,7 +71,6 @@ class TestJsonFile(unittest.TestCase):
             self.val.to_python(self.FieldStorage('{'))
 
 
-@with_nose_compatibility
 class TestUserMapFile(unittest.TestCase):
     val = v.UserMapJsonFile()
 
@@ -100,7 +96,6 @@ class TestUserMapFile(unittest.TestCase):
             self.FieldStorage('{"user_old": "user_new"}')))
 
 
-@with_nose_compatibility
 class TestUserValidator(unittest.TestCase):
     val = v.UserValidator
 
@@ -117,7 +112,6 @@ class TestUserValidator(unittest.TestCase):
         self.assertEqual(str(cm.exception), "Invalid username")
 
 
-@with_nose_compatibility
 class TestAnonymousValidator(unittest.TestCase):
     val = v.AnonymousValidator
 
@@ -137,7 +131,6 @@ class TestAnonymousValidator(unittest.TestCase):
         self.assertEqual(str(cm.exception), "Log in to Mark as Private")
 
 
-@with_nose_compatibility
 class TestMountPointValidator(unittest.TestCase):
 
     def setup_method(self, method):
@@ -201,7 +194,6 @@ class TestMountPointValidator(unittest.TestCase):
         self.assertEqual('wiki-0', val.to_python(None))
 
 
-@with_nose_compatibility
 class TestTaskValidator(unittest.TestCase):
     val = v.TaskValidator
 
@@ -235,7 +227,6 @@ class TestTaskValidator(unittest.TestCase):
                          '"allura.tests.test_validators._setup_method" is not a task.')
 
 
-@with_nose_compatibility
 class TestPathValidator(unittest.TestCase):
     val = v.PathValidator(strip=True, if_missing={}, if_empty={})
 
@@ -287,7 +278,6 @@ class TestPathValidator(unittest.TestCase):
         self.assertEqual({}, self.val.to_python(''))
 
 
-@with_nose_compatibility
 class TestUrlValidator(unittest.TestCase):
     val = v.URL
 
@@ -309,7 +299,6 @@ class TestUrlValidator(unittest.TestCase):
         self.assertEqual(str(cm.exception), 'That is not a valid URL')
 
 
-@with_nose_compatibility
 class TestNonHttpUrlValidator(unittest.TestCase):
     val = v.NonHttpUrl
 
@@ -331,7 +320,6 @@ class TestNonHttpUrlValidator(unittest.TestCase):
         self.assertEqual(str(cm.exception), 'You must start your URL with a scheme')
 
 
-@with_nose_compatibility
 class TestIconValidator(unittest.TestCase):
     val = v.IconValidator
 
diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py
index 4494d9a6b..d0785343a 100644
--- a/Allura/allura/tests/test_webhooks.py
+++ b/Allura/allura/tests/test_webhooks.py
@@ -43,7 +43,6 @@ from alluratest.controller import (
     TestRestApiBase,
 )
 import six
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 # important to be distinct from 'test' and 'test2' which ForgeGit and
@@ -54,7 +53,6 @@ with_git = td.with_tool(test_project_with_repo, 'git', 'src', 'Git')
 with_git2 = td.with_tool(test_project_with_repo, 'git', 'src2', 'Git2')
 
 
-@with_nose_compatibility
 class TestWebhookBase:
     def setup_method(self, method):
         setup_basic_test()
@@ -86,7 +84,6 @@ class TestWebhookBase:
         return [repo_init]
 
 
-@with_nose_compatibility
 class TestValidators(TestWebhookBase):
     @with_git2
     def test_webhook_validator(self):
@@ -124,7 +121,6 @@ class TestValidators(TestWebhookBase):
         assert v.to_python(str(wh._id)) == wh
 
 
-@with_nose_compatibility
 class TestWebhookController(TestController):
 
     def setup_method(self, method):
@@ -417,7 +413,6 @@ class TestWebhookController(TestController):
         return [text(tds[0]), text(tds[1]), link(tds[2]), delete_btn(tds[3])]
 
 
-@with_nose_compatibility
 class TestSendWebhookHelper(TestWebhookBase):
     def setup_method(self, method):
         super().setup_method(method)
@@ -522,7 +517,6 @@ class TestSendWebhookHelper(TestWebhookBase):
                     requests.post.return_value.headers))
 
 
-@with_nose_compatibility
 class TestRepoPushWebhookSender(TestWebhookBase):
     @patch('allura.webhooks.send_webhook', autospec=True)
     def test_send(self, send_webhook):
@@ -629,7 +623,6 @@ class TestRepoPushWebhookSender(TestWebhookBase):
         assert sender._convert_id('a433fa9:13') == 'r13'
 
 
-@with_nose_compatibility
 class TestModels(TestWebhookBase):
     def test_webhook_url(self):
         assert (self.wh.url() ==
@@ -671,7 +664,6 @@ class TestModels(TestWebhookBase):
         assert self.wh.__json__() == expected
 
 
-@with_nose_compatibility
 class TestWebhookRestController(TestRestApiBase):
     def setup_method(self, method):
         super().setup_method(method)
diff --git a/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py b/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
index 133301f23..f689fa5f7 100644
--- a/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
+++ b/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
@@ -23,10 +23,8 @@ from allura.tests.unit.factories import create_post, create_discussion
 from allura import model
 from allura.controllers.discuss import ModerationController
 from allura.tests.unit import patches
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestWhenModerating(WithDatabase):
     patches = [patches.fake_app_patch,
                patches.fake_user_patch,
@@ -74,7 +72,6 @@ class TestWhenModerating(WithDatabase):
         return model.Post.query.get(slug='mypost', deleted=False)
 
 
-@with_nose_compatibility
 class TestIndexWithNoPosts(WithDatabase):
     patches = [patches.fake_app_patch]
 
@@ -84,7 +81,6 @@ class TestIndexWithNoPosts(WithDatabase):
         assert template_variables['posts'].all() == []
 
 
-@with_nose_compatibility
 class TestIndexWithAPostInTheDiscussion(WithDatabase):
     patches = [patches.fake_app_patch]
 
diff --git a/Allura/allura/tests/unit/phone/test_nexmo.py b/Allura/allura/tests/unit/phone/test_nexmo.py
index 1b6139fa8..f2e99dacd 100644
--- a/Allura/allura/tests/unit/phone/test_nexmo.py
+++ b/Allura/allura/tests/unit/phone/test_nexmo.py
@@ -17,12 +17,10 @@
 
 import json
 from mock import patch
-from alluratest.pytest_helpers import with_nose_compatibility
 
 from allura.lib.phone.nexmo import NexmoPhoneService
 
 
-@with_nose_compatibility
 class TestPhoneService:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/phone/test_phone_service.py b/Allura/allura/tests/unit/phone/test_phone_service.py
index 739594475..faceb374c 100644
--- a/Allura/allura/tests/unit/phone/test_phone_service.py
+++ b/Allura/allura/tests/unit/phone/test_phone_service.py
@@ -16,7 +16,6 @@
 #       under the License.
 
 from allura.lib.phone import PhoneService
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 class MockPhoneService(PhoneService):
@@ -28,7 +27,6 @@ class MockPhoneService(PhoneService):
         return {'status': 'ok'}
 
 
-@with_nose_compatibility
 class TestPhoneService:
 
     def test_verify(self):
diff --git a/Allura/allura/tests/unit/spam/test_akismet.py b/Allura/allura/tests/unit/spam/test_akismet.py
index 384ce1b32..268545dd9 100644
--- a/Allura/allura/tests/unit/spam/test_akismet.py
+++ b/Allura/allura/tests/unit/spam/test_akismet.py
@@ -26,11 +26,9 @@ from datetime import datetime
 from bson import ObjectId
 
 from allura.lib.spam.akismetfilter import AKISMET_AVAILABLE, AkismetSpamFilter
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 @unittest.skipIf(not AKISMET_AVAILABLE, "Akismet not available")
-@with_nose_compatibility
 class TestAkismet(unittest.TestCase):
 
     @mock.patch('allura.lib.spam.akismetfilter.akismet')
diff --git a/Allura/allura/tests/unit/spam/test_spam_filter.py b/Allura/allura/tests/unit/spam/test_spam_filter.py
index 93b01b984..ad32d690a 100644
--- a/Allura/allura/tests/unit/spam/test_spam_filter.py
+++ b/Allura/allura/tests/unit/spam/test_spam_filter.py
@@ -25,7 +25,6 @@ from allura import model as M
 from allura.model.artifact import SpamCheckResult
 from alluratest.controller import setup_basic_test
 from forgewiki import model as WM
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 class MockFilter(SpamFilter):
@@ -46,7 +45,6 @@ class MockFilter2(SpamFilter):
         return True
 
 
-@with_nose_compatibility
 class TestSpamFilter(unittest.TestCase):
 
     def test_check(self):
@@ -75,7 +73,6 @@ class TestSpamFilter(unittest.TestCase):
         self.assertTrue(log.exception.called)
 
 
-@with_nose_compatibility
 class TestSpamFilterFunctional:
 
     def setup_method(self, method):
@@ -95,7 +92,6 @@ class TestSpamFilterFunctional:
         assert results[0].user.username == 'test-user'
 
 
-@with_nose_compatibility
 class TestChainedSpamFilter:
 
     def test(self):
diff --git a/Allura/allura/tests/unit/spam/test_stopforumspam.py b/Allura/allura/tests/unit/spam/test_stopforumspam.py
index 296f63a2c..bb827183e 100644
--- a/Allura/allura/tests/unit/spam/test_stopforumspam.py
+++ b/Allura/allura/tests/unit/spam/test_stopforumspam.py
@@ -21,10 +21,8 @@ import mock
 from bson import ObjectId
 
 from allura.lib.spam.stopforumspamfilter import StopForumSpamSpamFilter
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestStopForumSpam:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/test_app.py b/Allura/allura/tests/unit/test_app.py
index 65d000fae..e7d0fbd79 100644
--- a/Allura/allura/tests/unit/test_app.py
+++ b/Allura/allura/tests/unit/test_app.py
@@ -22,10 +22,8 @@ from allura import model
 from allura.tests.unit import WithDatabase
 from allura.tests.unit.patches import fake_app_patch
 from allura.tests.unit.factories import create_project, create_app_config
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestApplication(TestCase):
 
     def test_validate_mount_point(self):
@@ -54,7 +52,6 @@ class TestApplication(TestCase):
         self.assertEqual(f('does_not_exist'), '')
 
 
-@with_nose_compatibility
 class TestInstall(WithDatabase):
     patches = [fake_app_patch]
 
@@ -67,7 +64,6 @@ class TestInstall(WithDatabase):
         return model.Discussion.query.find().count()
 
 
-@with_nose_compatibility
 class TestDefaultDiscussion(WithDatabase):
     patches = [fake_app_patch]
 
@@ -88,7 +84,6 @@ class TestDefaultDiscussion(WithDatabase):
         assert self.discussion.shortname == 'my_mounted_app'
 
 
-@with_nose_compatibility
 class TestAppDefaults(WithDatabase):
     patches = [fake_app_patch]
 
diff --git a/Allura/allura/tests/unit/test_artifact.py b/Allura/allura/tests/unit/test_artifact.py
index 1cbe17f47..895eb74ec 100644
--- a/Allura/allura/tests/unit/test_artifact.py
+++ b/Allura/allura/tests/unit/test_artifact.py
@@ -18,10 +18,8 @@
 import unittest
 
 from allura import model as M
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestArtifact(unittest.TestCase):
 
     def test_translate_query(self):
diff --git a/Allura/allura/tests/unit/test_discuss.py b/Allura/allura/tests/unit/test_discuss.py
index 6078dff49..6f8eba841 100644
--- a/Allura/allura/tests/unit/test_discuss.py
+++ b/Allura/allura/tests/unit/test_discuss.py
@@ -18,10 +18,8 @@
 from allura import model as M
 from allura.tests.unit import WithDatabase
 from allura.tests.unit.patches import fake_app_patch
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestThread(WithDatabase):
     patches = [fake_app_patch]
 
diff --git a/Allura/allura/tests/unit/test_helpers/test_ago.py b/Allura/allura/tests/unit/test_helpers/test_ago.py
index ee4d0925f..8e6406e9a 100644
--- a/Allura/allura/tests/unit/test_helpers/test_ago.py
+++ b/Allura/allura/tests/unit/test_helpers/test_ago.py
@@ -20,10 +20,8 @@ from datetime import datetime
 from mock import patch
 
 from allura.lib import helpers
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestAgo:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/test_helpers/test_set_context.py b/Allura/allura/tests/unit/test_helpers/test_set_context.py
index 68b8898e4..171cf4425 100644
--- a/Allura/allura/tests/unit/test_helpers/test_set_context.py
+++ b/Allura/allura/tests/unit/test_helpers/test_set_context.py
@@ -26,10 +26,8 @@ from allura.tests.unit import patches
 from allura.tests.unit.factories import (create_project,
                                          create_app_config,
                                          create_neighborhood)
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestWhenProjectIsFoundAndAppIsNot(WithDatabase):
 
     def setup_method(self, method):
@@ -44,7 +42,6 @@ class TestWhenProjectIsFoundAndAppIsNot(WithDatabase):
         assert c.app is None, c.app
 
 
-@with_nose_compatibility
 class TestWhenProjectIsFoundInNeighborhood(WithDatabase):
 
     def setup_method(self, method):
@@ -59,7 +56,6 @@ class TestWhenProjectIsFoundInNeighborhood(WithDatabase):
         assert c.app is None
 
 
-@with_nose_compatibility
 class TestWhenAppIsFoundByID(WithDatabase):
     patches = [patches.project_app_loading_patch]
 
@@ -77,7 +73,6 @@ class TestWhenAppIsFoundByID(WithDatabase):
         self.project_app_instance_function.assert_called_with(self.app_config)
 
 
-@with_nose_compatibility
 class TestWhenAppIsFoundByMountPoint(WithDatabase):
     patches = [patches.project_app_loading_patch]
 
@@ -96,7 +91,6 @@ class TestWhenAppIsFoundByMountPoint(WithDatabase):
             'my_mounted_app')
 
 
-@with_nose_compatibility
 class TestWhenProjectIsNotFound(WithDatabase):
 
     def test_that_it_raises_an_exception(self):
@@ -114,7 +108,6 @@ class TestWhenProjectIsNotFound(WithDatabase):
                       neighborhood=None)
 
 
-@with_nose_compatibility
 class TestWhenNeighborhoodIsNotFound(WithDatabase):
 
     def test_that_it_raises_an_exception(self):
diff --git a/Allura/allura/tests/unit/test_ldap_auth_provider.py b/Allura/allura/tests/unit/test_ldap_auth_provider.py
index c66da2b24..a480be211 100644
--- a/Allura/allura/tests/unit/test_ldap_auth_provider.py
+++ b/Allura/allura/tests/unit/test_ldap_auth_provider.py
@@ -31,10 +31,8 @@ from allura.lib import plugin
 from allura.lib import helpers as h
 from allura import model as M
 import six
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestLdapAuthenticationProvider:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/test_mixins.py b/Allura/allura/tests/unit/test_mixins.py
index 775ff0358..ac29a59d5 100644
--- a/Allura/allura/tests/unit/test_mixins.py
+++ b/Allura/allura/tests/unit/test_mixins.py
@@ -17,10 +17,8 @@
 
 from mock import Mock
 from allura.model import VotableArtifact
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestVotableArtifact:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/test_package_path_loader.py b/Allura/allura/tests/unit/test_package_path_loader.py
index 5e3702715..44bb6fbfe 100644
--- a/Allura/allura/tests/unit/test_package_path_loader.py
+++ b/Allura/allura/tests/unit/test_package_path_loader.py
@@ -25,10 +25,8 @@ import pytest
 from tg import config
 
 from allura.lib.package_path_loader import PackagePathLoader
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestPackagePathLoader(TestCase):
 
     @mock.patch('pkg_resources.resource_filename')
diff --git a/Allura/allura/tests/unit/test_post_model.py b/Allura/allura/tests/unit/test_post_model.py
index eca936d1e..7cbcf4682 100644
--- a/Allura/allura/tests/unit/test_post_model.py
+++ b/Allura/allura/tests/unit/test_post_model.py
@@ -22,10 +22,8 @@ from allura import model as M
 from allura.tests.unit import WithDatabase
 from allura.tests.unit import patches
 from allura.tests.unit.factories import create_post
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestPostModel(WithDatabase):
     patches = [patches.fake_app_patch,
                patches.disable_notifications_patch]
diff --git a/Allura/allura/tests/unit/test_project.py b/Allura/allura/tests/unit/test_project.py
index 2fb093643..37af31d18 100644
--- a/Allura/allura/tests/unit/test_project.py
+++ b/Allura/allura/tests/unit/test_project.py
@@ -23,10 +23,8 @@ from tg import config
 from allura import model as M
 from allura.lib import helpers as h
 from allura.app import SitemapEntry
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestProject(unittest.TestCase):
 
     def test_grouped_navbar_entries(self):
diff --git a/Allura/allura/tests/unit/test_repo.py b/Allura/allura/tests/unit/test_repo.py
index f67e69a96..47945e24f 100644
--- a/Allura/allura/tests/unit/test_repo.py
+++ b/Allura/allura/tests/unit/test_repo.py
@@ -29,10 +29,8 @@ from allura.model.repository import zipdir, prefix_paths_union
 from allura.model.repo_refresh import (
     _group_commits,
 )
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestTopoSort(unittest.TestCase):
 
     def test_commit_dates_out_of_order(self):
@@ -85,7 +83,6 @@ def blob(name, id):
     return b
 
 
-@with_nose_compatibility
 class TestTree(unittest.TestCase):
 
     @patch('allura.model.repository.Tree.__getitem__')
@@ -103,7 +100,6 @@ class TestTree(unittest.TestCase):
         getitem().__getitem__().__getitem__.assert_called_with('file.txt')
 
 
-@with_nose_compatibility
 class TestBlob(unittest.TestCase):
 
     def test_pypeline_view(self):
@@ -144,7 +140,6 @@ class TestBlob(unittest.TestCase):
         assert blob.has_html_view == True
 
 
-@with_nose_compatibility
 class TestCommit(unittest.TestCase):
 
     def test_activity_extras(self):
@@ -246,7 +241,6 @@ class TestCommit(unittest.TestCase):
         commit.get_tree.assert_called_with(create=True)
 
 
-@with_nose_compatibility
 class TestZipDir(unittest.TestCase):
 
     @patch('allura.model.repository.Popen')
@@ -290,7 +284,6 @@ class TestZipDir(unittest.TestCase):
         self.assertTrue("STDERR: 2" in emsg)
 
 
-@with_nose_compatibility
 class TestPrefixPathsUnion(unittest.TestCase):
 
     def test_disjoint(self):
@@ -309,7 +302,6 @@ class TestPrefixPathsUnion(unittest.TestCase):
         self.assertEqual(prefix_paths_union(a, b), {'a2'})
 
 
-@with_nose_compatibility
 class TestGroupCommits:
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/test_session.py b/Allura/allura/tests/unit/test_session.py
index d7899302f..e2042c039 100644
--- a/Allura/allura/tests/unit/test_session.py
+++ b/Allura/allura/tests/unit/test_session.py
@@ -28,7 +28,6 @@ from allura.model.session import (
     ArtifactSessionExtension,
     substitute_extensions,
 )
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
 def test_extensions_cm():
@@ -75,7 +74,6 @@ def test_extensions_cm_flush_raises():
     assert session._kwargs['extensions'] == []
 
 
-@with_nose_compatibility
 class TestSessionExtension(TestCase):
 
     def _mock_indexable(self, **kw):
@@ -85,7 +83,6 @@ class TestSessionExtension(TestCase):
         return m
 
 
-@with_nose_compatibility
 class TestIndexerSessionExtension(TestSessionExtension):
 
     def setup_method(self, method):
@@ -124,7 +121,6 @@ class TestIndexerSessionExtension(TestSessionExtension):
         assert self.tasks['add'].post.call_count == 0
 
 
-@with_nose_compatibility
 class TestArtifactSessionExtension(TestSessionExtension):
 
     def setup_method(self, method):
@@ -154,7 +150,6 @@ class TestArtifactSessionExtension(TestSessionExtension):
         assert index_tasks.add_artifacts.post.call_count == 0
 
 
-@with_nose_compatibility
 class TestBatchIndexer(TestCase):
 
     def setup_method(self, method):
diff --git a/Allura/allura/tests/unit/test_sitemapentry.py b/Allura/allura/tests/unit/test_sitemapentry.py
index ea38b10b7..bdd6399d1 100644
--- a/Allura/allura/tests/unit/test_sitemapentry.py
+++ b/Allura/allura/tests/unit/test_sitemapentry.py
@@ -19,10 +19,8 @@ import unittest
 from mock import Mock
 
 from allura.app import SitemapEntry
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestSitemapEntry(unittest.TestCase):
 
     def test_matches_url(self):
diff --git a/Allura/allura/tests/unit/test_solr.py b/Allura/allura/tests/unit/test_solr.py
index 8d15e65ad..c24bfdb35 100644
--- a/Allura/allura/tests/unit/test_solr.py
+++ b/Allura/allura/tests/unit/test_solr.py
@@ -25,10 +25,8 @@ from allura.tests import decorators as td
 from alluratest.controller import setup_basic_test
 from allura.lib.solr import Solr, escape_solr_arg
 from allura.lib.search import search_app, SearchIndexable
-from alluratest.pytest_helpers import with_nose_compatibility
 
 
-@with_nose_compatibility
 class TestSolr(unittest.TestCase):
 
     def setup_method(self, method):
@@ -122,7 +120,6 @@ class TestSolr(unittest.TestCase):
             'username_s:admin1 || username_s:root', fq=fq, ignore_errors=False)
 
 
-@with_nose_compatibility
 class TestSearchIndexable(unittest.TestCase):
 
     def setup_method(self, method):
@@ -147,7 +144,6 @@ class TestSearchIndexable(unittest.TestCase):
         assert self.obj.solarize() == dict(text='<script>a(1)</script>')
 
 
-@with_nose_compatibility
 class TestSearch_app(unittest.TestCase):
 
     def setup_method(self, method):
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index 207946075..f110c7a57 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -19,7 +19,6 @@
 from __future__ import annotations
 
 import os
-from alluratest.pytest_helpers import with_nose_compatibility
 import six.moves.urllib.request
 import six.moves.urllib.parse
 import six.moves.urllib.error
@@ -163,14 +162,12 @@ def setup_trove_categories():
         create_trove_categories.run([''])
 
 
-@with_nose_compatibility
 class TestController:
 
     application_under_test = 'main'
     validate_skip = False
 
     def setup_method(self, method=None):
-        """Method called by nose before running each test"""
         pkg = self.__module__.split('.')[0]
         self.app = ValidatingTestApp(
             setup_functional_test(app_name=self.application_under_test, current_pkg=pkg))
@@ -182,7 +179,6 @@ class TestController:
             self.smtp_mock.start()
 
     def teardown_method(self, method=None):
-        """Method called by nose after running each test"""
         if asbool(tg.config.get('smtp.mock')):
             self.smtp_mock.stop()
 
@@ -212,7 +208,6 @@ class TestController:
                 return f
 
 
-@with_nose_compatibility
 class TestRestApiBase(TestController):
 
     def setup_method(self, method):
diff --git a/AlluraTest/alluratest/pytest_helpers.py b/AlluraTest/alluratest/pytest_helpers.py
deleted file mode 100644
index 832cfa796..000000000
--- a/AlluraTest/alluratest/pytest_helpers.py
+++ /dev/null
@@ -1,49 +0,0 @@
-
-IS_NOSE = None
-
-
-def is_called_by_nose():
-    global IS_NOSE
-    if IS_NOSE is None:
-        import inspect
-        stack = inspect.stack()
-        IS_NOSE = any(x[0].f_globals['__name__'].startswith('nose.') for x in stack)
-    return IS_NOSE
-
-
-def with_nose_compatibility(test_class):
-
-    if not is_called_by_nose():
-        return test_class
-
-    def setUp_(self):
-        setup_method = hasattr(self, 'setup_method')
-        if setup_method:
-            self.setup_method(None)
-    if hasattr(test_class, 'setup_method'):
-        test_class.setUp = setUp_
-
-    def tearDown_(self):
-        teardown_method = hasattr(self, 'teardown_method')
-        if teardown_method:
-            self.teardown_method(None)
-    if hasattr(test_class, 'teardown_method'):
-        test_class.tearDown = tearDown_
-
-    @classmethod
-    def setUpClass_(cls):
-        setup_class = hasattr(cls, 'setup_class')
-        if setup_class:
-            cls.setup_class()
-    if hasattr(test_class, 'setup_class'):
-        test_class.setUpClass = setUpClass_
-
-    @classmethod
-    def tearDownClass_(cls):
-        teardown_class = hasattr(cls, 'teardown_class')
-        if teardown_class:
-            cls.teardown_class()
-    if hasattr(test_class, 'teardown_class'):
-        test_class.tearDownClass = tearDownClass_
-
-    return test_class
diff --git a/AlluraTest/alluratest/test_syntax.py b/AlluraTest/alluratest/test_syntax.py
index 658d676fc..0d93f4c0d 100644
--- a/AlluraTest/alluratest/test_syntax.py
+++ b/AlluraTest/alluratest/test_syntax.py
@@ -27,7 +27,7 @@ toplevel_dir = os.path.abspath(os.path.dirname(__file__) + "/../..")
 
 def run(cmd):
     proc = Popen(cmd, shell=True, cwd=toplevel_dir, stdout=PIPE, stderr=PIPE)
-    # must capture & reprint stdount, so that nosetests can capture it
+    # must capture & reprint stdount, so that pytest can capture it
     (stdout, stderr) = proc.communicate()
     sys.stdout.write(stdout.decode('utf-8'))
     sys.stderr.write(stderr.decode('utf-8'))