diff --git a/meta/conf/distro/include/ptest-packagelists.inc b/meta/conf/distro/include/ptest-packagelists.inc
index bef45bb4d5..50b971bace 100644
--- a/meta/conf/distro/include/ptest-packagelists.inc
+++ b/meta/conf/distro/include/ptest-packagelists.inc
@@ -154,6 +154,7 @@ PTESTS_SLOW = "\
     python3-click \
     python3-cryptography \
     python3-numpy \
+    python3-uvloop \
     python3-xmltodict \
     strace \
     tar \
diff --git a/meta/recipes-devtools/python/python3-uvloop/run-ptest b/meta/recipes-devtools/python/python3-uvloop/run-ptest
new file mode 100755
index 0000000000..db86664f9a
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-uvloop/run-ptest
@@ -0,0 +1,25 @@
+#!/bin/sh
+# test_process_streams_redirect: replaces the stdout/stderr fds, which
+# conflicts with pytest's output capture.
+# test_process_preexec_fn_{1,2}, Test_UV_DNS test_getaddrinfo_{8,9}: libuv
+# 1.53.0 spawns with posix_spawn(), so preexec_fn never runs, and an empty
+# host gives EAI_NODATA.
+# test_getaddrinfo_{1,2,3,5,6,11}, Test_AIO_DNS test_getaddrinfo_{8,9}: each
+# DNS lookup waits for the resolver timeout without network access.
+# --deselect matches a node id prefix, so -k handles 1, 2 and 11.
+pytest --automake \
+    -k "not (test_getaddrinfo_1 or test_getaddrinfo_2) or test_getaddrinfo_10 or test_getaddrinfo_12 or test_getaddrinfo_13 or test_getaddrinfo_14 or test_getaddrinfo_15 or test_getaddrinfo_16 or test_getaddrinfo_17 or test_getaddrinfo_18 or test_getaddrinfo_19 or test_getaddrinfo_20 or test_getaddrinfo_21 or test_getaddrinfo_22" \
+    --deselect=tests/test_process.py::Test_UV_Process::test_process_streams_redirect \
+    --deselect=tests/test_process.py::Test_AIO_Process::test_process_streams_redirect \
+    --deselect=tests/test_process.py::Test_UV_Process::test_process_preexec_fn_1 \
+    --deselect=tests/test_process.py::Test_UV_Process::test_process_preexec_fn_2 \
+    --deselect=tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_3 \
+    --deselect=tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_5 \
+    --deselect=tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_6 \
+    --deselect=tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_8 \
+    --deselect=tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_9 \
+    --deselect=tests/test_dns.py::Test_AIO_DNS::test_getaddrinfo_3 \
+    --deselect=tests/test_dns.py::Test_AIO_DNS::test_getaddrinfo_5 \
+    --deselect=tests/test_dns.py::Test_AIO_DNS::test_getaddrinfo_6 \
+    --deselect=tests/test_dns.py::Test_AIO_DNS::test_getaddrinfo_8 \
+    --deselect=tests/test_dns.py::Test_AIO_DNS::test_getaddrinfo_9
diff --git a/meta/recipes-devtools/python/python3-uvloop_0.22.1.bb b/meta/recipes-devtools/python/python3-uvloop_0.22.1.bb
index 887c262ae7..39b6a2602a 100644
--- a/meta/recipes-devtools/python/python3-uvloop_0.22.1.bb
+++ b/meta/recipes-devtools/python/python3-uvloop_0.22.1.bb
@@ -7,11 +7,34 @@ LIC_FILES_CHKSUM = "file://LICENSE-APACHE;md5=bb92739ddad0a2811957bd98bdb90474 \
 
 DEPENDS += "libuv python3-wheel-native"
 
-SRC_URI += "file://0001-setup.cfg-use-system-libuv.patch"
+SRC_URI += "\
+    file://0001-setup.cfg-use-system-libuv.patch \
+    file://run-ptest \
+"
 SRC_URI[sha256sum] = "6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f"
 
-inherit pypi python_setuptools_build_meta cython
+inherit pypi python_setuptools_build_meta cython ptest-python-pytest
 
 RDEPENDS:${PN} = "python3-asyncio"
 
+RDEPENDS:${PN}-ptest += "\
+    python3-ctypes \
+    python3-io \
+    python3-logging \
+    python3-math \
+    python3-multiprocessing \
+    python3-netclient \
+    python3-numbers \
+    python3-pickle \
+    python3-pprint \
+    python3-psutil \
+    python3-pyopenssl \
+    python3-threading \
+"
+
+do_install_ptest:append() {
+    # test_sourcecode needs these to skip cleanly when flake8 and mypy are missing
+    install -m 0644 ${S}/.flake8 ${S}/mypy.ini ${D}${PTEST_PATH}/
+}
+
 BBCLASSEXTEND = "native nativesdk"
