diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
index 06cd3fe0cd63507e5ab815050c5fea5c4539a7bd..fc2b7ab0db3a2459a89ab4276b98d9cbf9778a94 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
@@ -9,13 +9,13 @@ import itertools
 import mimetypes
 from uuid import uuid4
 from contextlib import contextmanager
+import pytest
 from mock import patch, Mock, call
 
 # Mixed modulestore depends on django, so we'll manually configure some django settings
 # before importing the module
 # TODO remove this import and the configuration -- xmodule should not depend on django!
 from django.conf import settings
-from nose import SkipTest
 import pymongo
 from pytz import UTC
 from shutil import rmtree
@@ -3278,7 +3278,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
         Check that asides could be imported from XML and the modulestores handle asides crud
         """
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
         with MongoContentstoreBuilder().build() as contentstore:
             self.store = MixedModuleStore(
                 contentstore=contentstore,
@@ -3353,7 +3353,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
            lambda self, block: ['test_aside'])
     def test_export_course_with_asides(self, default_store):
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
         with MongoContentstoreBuilder().build() as contentstore:
             self.store = MixedModuleStore(
                 contentstore=contentstore,
@@ -3440,7 +3440,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
            lambda self, block: ['test_aside'])
     def test_export_course_after_creating_new_items_with_asides(self, default_store):  # pylint: disable=too-many-statements
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
         with MongoContentstoreBuilder().build() as contentstore:
             self.store = MixedModuleStore(
                 contentstore=contentstore,
@@ -3577,7 +3577,7 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
         Tests that connected asides could be stored, received and updated along with connected course items
         """
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
 
         self.initdb(default_store)
 
@@ -3641,7 +3641,7 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
         Tests that connected asides will be cloned together with the parent courses
         """
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
 
         with MongoContentstoreBuilder().build() as contentstore:
             # initialize the mixed modulestore
@@ -3689,7 +3689,7 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
         Tests that connected asides will be removed together with the connected items
         """
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
 
         self.initdb(default_store)
 
@@ -3739,7 +3739,7 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
         Tests that public/unpublish doesn't affect connected stored asides
         """
         if default_store == ModuleStoreEnum.Type.mongo:
-            raise SkipTest("asides not supported in old mongo")
+            pytest.skip("asides not supported in old mongo")
 
         self.initdb(default_store)
 
diff --git a/common/test/acceptance/tests/lms/test_problem_types.py b/common/test/acceptance/tests/lms/test_problem_types.py
index 169a3a10d15e6f5d669219534620fae5afc33777..c6951af7199d56f730837647d2cf8a860e9a2f94 100644
--- a/common/test/acceptance/tests/lms/test_problem_types.py
+++ b/common/test/acceptance/tests/lms/test_problem_types.py
@@ -8,7 +8,7 @@ import textwrap
 from abc import ABCMeta, abstractmethod
 
 import ddt
-from nose import SkipTest
+import pytest
 from selenium.webdriver import ActionChains
 
 from capa.tests.response_xml_factory import (
@@ -243,7 +243,7 @@ class ProblemTypeTestMixin(ProblemTypeA11yTestMixin):
         And The "<ProblemType>" problem displays a "blank" answer
         """
         if not self.can_submit_blank:
-            raise SkipTest("Test incompatible with the current problem type")
+            pytest.skip("Test incompatible with the current problem type")
 
         self.problem_page.wait_for(
             lambda: self.problem_page.problem_name == self.problem_name,
@@ -263,7 +263,7 @@ class ProblemTypeTestMixin(ProblemTypeA11yTestMixin):
         Then I can't submit a problem
         """
         if self.can_submit_blank:
-            raise SkipTest("Test incompatible with the current problem type")
+            pytest.skip("Test incompatible with the current problem type")
 
         self.problem_page.wait_for(
             lambda: self.problem_page.problem_name == self.problem_name,
@@ -372,7 +372,7 @@ class ProblemTypeTestMixin(ProblemTypeA11yTestMixin):
 
         # Not all problems have partially correct solutions configured
         if not self.partially_correct:
-            raise SkipTest("Test incompatible with the current problem type")
+            pytest.skip("Test incompatible with the current problem type")
 
         self.problem_page.wait_for(
             lambda: self.problem_page.problem_name == self.problem_name,
@@ -412,7 +412,7 @@ class ProblemNeverShowCorrectnessMixin(object):
 
         # Not all problems have partially correct solutions configured
         if correctness == 'partially-correct' and not self.partially_correct:
-            raise SkipTest("Test incompatible with the current problem type")
+            pytest.skip("Test incompatible with the current problem type")
 
         # Problem progress text depends on points possible
         possible = 'possible (ungraded, results hidden)'
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index b424c3b3771eef78755388f374e861a1931e504e..854087e69b0d2164f023d52ff1374e719d4efea3 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -74,7 +74,7 @@ django-classy-tags==0.8.0  # via django-sekizai
 django-config-models==0.2.0
 django-cors-headers==2.1.0
 django-countries==4.6.1
-django-crum==0.7.2
+django-crum==0.7.3
 django-fernet-fields==0.5
 django-filter==1.0.4
 django-ipware==1.1.0
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index 83de014f667d899e3fa1369309d6af49627c6303..555632684583af3864183328a505d3487bce6245 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -57,12 +57,12 @@ atomicwrites==1.1.5
 attrs==17.4.0
 babel==1.3
 backports.functools-lru-cache==1.5
-beautifulsoup4==4.6.1
+beautifulsoup4==4.6.3
 beautifulsoup==3.2.1
 before-after==1.0.1
 billiard==3.3.0.23
 bleach==1.4
-bok-choy==0.8.1
+bok-choy==0.9.0
 boto3==1.4.8
 boto==2.39.0
 botocore==1.8.17
@@ -93,7 +93,7 @@ django-classy-tags==0.8.0
 django-config-models==0.2.0
 django-cors-headers==2.1.0
 django-countries==4.6.1
-django-crum==0.7.2
+django-crum==0.7.3
 django-debug-toolbar==1.8
 django-fernet-fields==0.5
 django-filter==1.0.4
@@ -157,7 +157,7 @@ event-tracking==0.2.4
 execnet==1.5.0
 extras==1.0.0
 factory_boy==2.8.1
-faker==0.8.17
+faker==0.8.18
 feedparser==5.1.3
 firebase-token-generator==1.3.2
 first==2.0.1
@@ -216,12 +216,10 @@ mongoengine==0.10.0
 more-itertools==4.3.0
 moto==0.3.1
 mysql-python==1.2.5
-needle==0.5.0
 networkx==1.7
 newrelic==4.2.0.100
 nltk==3.3.0
 nodeenv==1.1.1
-nose==1.3.7
 numpy==1.6.2
 oauth2==1.9.0.post1
 oauthlib==2.0.1
diff --git a/requirements/edx/testing.in b/requirements/edx/testing.in
index e2126a4d023877e08105425dc4980a371b37a2c0..2e4139d900311c794a336b0bfb10ffacd6355fa2 100644
--- a/requirements/edx/testing.in
+++ b/requirements/edx/testing.in
@@ -29,7 +29,6 @@ freezegun                 # Allows tests to mock the output of assorted datetime
 httpretty                 # Library for mocking HTTP requests, used in many tests
 isort                     # For checking and fixing the order of imports
 moto==0.3.1               # Lets tests mock AWS access via the boto library
-nose                      # Former test runner, we're still using some utility functions from it
 pa11ycrawler              # Python crawler (using Scrapy) that uses Pa11y to check accessibility of pages as it crawls
 pycodestyle               # Checker for compliance with the Python style guide (PEP 8)
 polib                     # Library for manipulating gettext translation files, used to test paver i18n commands
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index 72cb21a40e86ac7a1365feac343f17336b142804..2f43d638e747cb6b4fb648b2e740d65c8bf03a67 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -54,12 +54,12 @@ atomicwrites==1.1.5       # via pytest
 attrs==17.4.0
 babel==1.3
 backports.functools-lru-cache==1.5  # via astroid, pylint
-beautifulsoup4==4.6.1
+beautifulsoup4==4.6.3
 beautifulsoup==3.2.1
 before-after==1.0.1
 billiard==3.3.0.23
 bleach==1.4
-bok-choy==0.8.1
+bok-choy==0.9.0
 boto3==1.4.8
 boto==2.39.0
 botocore==1.8.17
@@ -90,7 +90,7 @@ django-classy-tags==0.8.0
 django-config-models==0.2.0
 django-cors-headers==2.1.0
 django-countries==4.6.1
-django-crum==0.7.2
+django-crum==0.7.3
 django-fernet-fields==0.5
 django-filter==1.0.4
 django-ipware==1.1.0
@@ -151,7 +151,7 @@ event-tracking==0.2.4
 execnet==1.5.0            # via pytest-xdist
 extras==1.0.0             # via python-subunit, testtools
 factory_boy==2.8.1
-faker==0.8.17             # via factory-boy
+faker==0.8.18             # via factory-boy
 feedparser==5.1.3
 firebase-token-generator==1.3.2
 fixtures==3.0.0           # via testtools
@@ -207,12 +207,10 @@ mongoengine==0.10.0
 more-itertools==4.3.0     # via pytest
 moto==0.3.1
 mysql-python==1.2.5
-needle==0.5.0             # via bok-choy
 networkx==1.7
 newrelic==4.2.0.100
 nltk==3.3.0
 nodeenv==1.1.1
-nose==1.3.7
 numpy==1.6.2
 oauth2==1.9.0.post1
 oauthlib==2.0.1
diff --git a/scripts/thresholds.sh b/scripts/thresholds.sh
index 31f516bdcf2d79de263a3aadf875b1fcb4467d65..c2b8de119772bbec7adf1ef7dc92a162f7a92d98 100755
--- a/scripts/thresholds.sh
+++ b/scripts/thresholds.sh
@@ -2,6 +2,6 @@
 set -e
 
 export LOWER_PYLINT_THRESHOLD=1000
-export UPPER_PYLINT_THRESHOLD=3800
+export UPPER_PYLINT_THRESHOLD=3310
 export ESLINT_THRESHOLD=5590
 export STYLELINT_THRESHOLD=973