diff --git a/test/functional/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py
--- a/test/functional/test_framework/authproxy.py
+++ b/test/functional/test_framework/authproxy.py
@@ -124,6 +124,10 @@
         except OSError as e:
             retry = (
                 '[WinError 10053] An established connection was aborted by the software in your host machine' in str(e))
+            # Workaround for a bug on macOS. See
+            # https://bugs.python.org/issue33450
+            retry = retry or (
+                '[Errno 41] Protocol wrong type for socket' in str(e))
             if retry:
                 self.__conn.close()
                 self.__conn.request(method, path, postdata, headers)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -354,13 +354,15 @@
               enable_coverage=False, args=None, combined_logs_len=0, build_timings=None, failfast=False):
     args = args or []
 
-    # Warn if bitcoind is already running (unix only)
+    # Warn if bitcoind is already running
     try:
-        pidofOutput = subprocess.check_output(["pidof", "bitcoind"])
-        if pidofOutput is not None and pidofOutput != b'':
+        # pgrep exits with code zero when one or more matching processes found
+        if subprocess.run(["pgrep", "-x", "bitcoind"],
+                          stdout=subprocess.DEVNULL).returncode == 0:
             print("{}WARNING!{} There is already a bitcoind process running on this system. Tests may fail unexpectedly due to resource contention!".format(
                 BOLD[1], BOLD[0]))
-    except (OSError, subprocess.SubprocessError):
+    except OSError:
+        # pgrep not supported
         pass
 
     # Warn if there is a cache directory