diff --git a/.gitignore b/.gitignore
index e3e2ffa97..26401be10 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,9 +23,7 @@ pip-log.txt
 # Unit test / coverage reports
 .coverage*
 .tox
-nosetests.xml
 .stestr/
-.testrepository
 .venv
 .idea
 
diff --git a/.stestr.conf b/.stestr.conf
index 0579b69bc..4487be00b 100644
--- a/.stestr.conf
+++ b/.stestr.conf
@@ -1,4 +1,4 @@
 [DEFAULT]
-test_path=${OS_TEST_PATH:-./watcher/tests}
+test_path=./watcher/tests
 top_dir=./
 
diff --git a/.testr.conf b/.testr.conf
deleted file mode 100644
index 0c9a76ae3..000000000
--- a/.testr.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
-             OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
-             OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \
-             ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./watcher/tests} $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff --git a/lower-constraints.txt b/lower-constraints.txt
index 294b7c4de..1154b27a5 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -146,7 +146,6 @@ stevedore==1.28.0
 taskflow==3.1.0
 Tempita==0.5.2
 tenacity==4.9.0
-testrepository==0.0.20
 testresources==2.0.1
 testscenarios==0.5.0
 testtools==2.3.0
diff --git a/test-requirements.txt b/test-requirements.txt
index 8ef99de59..3a5c09a4c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,27 +2,27 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 
-coverage!=4.4 # Apache-2.0
-doc8 # Apache-2.0
-freezegun # Apache-2.0
+coverage>=4.5.1 # Apache-2.0
+doc8>=0.8.0 # Apache-2.0
+freezegun>=0.3.10 # Apache-2.0
 hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
-mock # BSD
-oslotest # Apache-2.0
-os-testr # Apache-2.0
-testrepository # Apache-2.0/BSD
-testscenarios # Apache-2.0/BSD
-testtools # MIT
+mock>=2.0.0 # BSD
+oslotest>=3.3.0 # Apache-2.0
+os-testr>=1.0.0 # Apache-2.0
+testscenarios>=0.5.0 # Apache-2.0/BSD
+testtools>=2.3.0 # MIT
+stestr>=2.0.0 # Apache-2.0
 
 # Doc requirements
-openstackdocstheme # Apache-2.0
-sphinx!=1.6.6,!=1.6.7 # BSD
-sphinxcontrib-pecanwsme # Apache-2.0
+openstackdocstheme>=1.20.0 # Apache-2.0
+sphinx>=1.6.5,!=1.6.6,!=1.6.7 # BSD
+sphinxcontrib-pecanwsme>=0.8.0 # Apache-2.0
 
 # api-ref
-os-api-ref # Apache-2.0
+os-api-ref>=1.4.0 # Apache-2.0
 
 # releasenotes
-reno # Apache-2.0
+reno>=2.7.0 # Apache-2.0
 
 # bandit
 bandit>=1.1.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index ca9a98929..100803dc4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -31,8 +31,13 @@ commands = {posargs}
 
 [testenv:cover]
 basepython = python3
+setenv =
+    PYTHON=coverage run --source watcher --parallel-mode
 commands =
-    python setup.py testr --coverage --testr-args='{posargs}'
+    stestr run '{posargs}'
+    coverage combine
+    coverage html -d cover
+    coverage xml -o cover/coverage.xml
     coverage report
 
 [testenv:docs]