diff --git a/.travis.yml b/.travis.yml
index d9c1719274f89d4b5afca43c125aa589294a1f47..a97d33b2b92f15a19491f7e8c264fc90317860d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ python:
  - "pypy3.5"
 script:
  - python -m compile_definitions
- - python setup.py nosetests --tests tests
+ - nose2 tests
  - python -m stress_tests
 install:
  - pip install -r requirements.txt
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 628273b0efce63d793123ae4fcbcfea86998baf1..eeb1c53fb483d5347650458cc11a51a1c9ffa760 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 * more extensive testing (CPython3.8, nightly)
 * fixed a bug wherein future_to_notify_on_dead was set_result multiple times
+* switched to nose2 for tests
 
 # v0.103:
 
diff --git a/Vagrantfile b/Vagrantfile
index 80e0876c693a09e3edaacafb916aa774373ba5f1..0e7b13d024f486304b56ed2e7fe8a11e4d0b4555 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -30,7 +30,7 @@ Vagrant.configure("2") do |config|
     sudo python -m pip install -r /vagrant/requirements.txt
     sudo python -m pip install nose coverage mock yapf
     sudo pip3 install -r /vagrant/requirements.txt
-    sudo pip3 install nose coverage mock yapf
+    sudo pip3 install nose2[coverage_plugin] coverage mock yapf nose2
     
     sudo pip3 install -r /vagrant/stress_tests/requirements.txt
     
diff --git a/setup.cfg b/setup.cfg
index 34988c5d85bb6775b2e56933a244adfcd86ada2d..7a8ef6b1e579cd2712f18ac44c73d4fdc9c9d92a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -29,11 +29,6 @@ max-line-length=80
 [bdist_wheel]
 universal=1
 
-[nosetests]
-verbosity=3
-detailed-errors=1
-with-coverage=1
-
 [isort]
 add_imports =
     from __future__ import absolute_import
diff --git a/setup.py b/setup.py
index a9b0eee30c2fcd9557119c97aa1b77f7539643ec..3a2d02482b30353ba7a76a0d1eb01057b0828f50 100644
--- a/setup.py
+++ b/setup.py
@@ -12,8 +12,8 @@ setup(keywords=['amqp', 'rabbitmq', 'client', 'network', 'ha', 'high availabilit
 Also, handles your reconnects and transactionality THE RIGHT WAY, though somewhat opinionated''',
       install_requires=['six', 'monotonic', 'futures', 'typing'],
       # per coverage version for codeclimate-reporter
-      tests_require=["nose", 'coverage>=4.0,<4.4'],
-      test_suite='nose.collector'
+      tests_require=["nose2", 'coverage>=4.0,<4.4', "nose2[coverage_plugin]"],
+      test_suite='nose2.collector.collector'
       )
 
 
diff --git a/tests/Dockerfile b/tests/Dockerfile
index 903742f976fe3fe19337193913a69f68f9288318..d202d3786f705f29d4dae19a1dd919d178ccf3f4 100644
--- a/tests/Dockerfile
+++ b/tests/Dockerfile
@@ -6,7 +6,7 @@ ADD requirements.txt /tmp/requirements.txt
 ADD stress_tests/requirements.txt /tmp/requirements2.txt
 RUN pip install -r /tmp/requirements.txt && \
     pip install -r /tmp/requirements2.txt && \
-    pip install nose mock coverage
+    pip install nose2 mock coverage nose2[coverage_plugin]
 
 ADD . /coolamqp
 WORKDIR /coolamqp
diff --git a/unittest.cfg b/unittest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..84743c4d941883b3d937ca5205dd980c16fc76de
--- /dev/null
+++ b/unittest.cfg
@@ -0,0 +1,2 @@
+[coverage]
+always-on = True