diff --git a/.travis.yml b/.travis.yml
index a1a314d9..a8e2fa86 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,5 +18,5 @@ install:
   - export PYTHONWARNINGS=all
 script:
   - python checkdeps.py
-  - xvfb-run src/bitmessagemain.py -t
+  - python src/bitmessagemain.py -t
   - python -bm tests
diff --git a/requirements.txt b/requirements.txt
index b12641c2..c7c599d5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,7 @@
 coverage
-python_prctl
 psutil
 pycrypto
-six
 PyQt5;python_version>="3.7"
+python_prctl;platform_system=="Linux"
+six
+xvfbwrapper;platform_system=="Linux"
diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py
index 2f46c6ec..dc7426ac 100755
--- a/src/bitmessagemain.py
+++ b/src/bitmessagemain.py
@@ -21,16 +21,13 @@ app_dir = pathmagic.setup()
 import depends
 depends.check_dependencies()
 
-import ctypes
 import getopt
 import multiprocessing
 # Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully.
 import signal
-import socket
 import threading
 import time
 import traceback
-from struct import pack
 
 import defaults
 import shared
@@ -39,7 +36,7 @@ import state
 from bmconfigparser import BMConfigParser
 from debug import logger  # this should go before any threads
 from helper_startup import (
-    adjustHalfOpenConnectionsLimit, start_proxyconfig)
+    adjustHalfOpenConnectionsLimit, fixSocket, start_proxyconfig)
 from inventory import Inventory
 # Network objects and threads
 from network import (
@@ -54,67 +51,6 @@ from threads import (
     addressGenerator, objectProcessor, singleCleaner, singleWorker, sqlThread)
 
 
-def _fixSocket():
-    if sys.platform.startswith('linux'):
-        socket.SO_BINDTODEVICE = 25
-
-    if not sys.platform.startswith('win'):
-        return
-
-    # Python 2 on Windows doesn't define a wrapper for
-    # socket.inet_ntop but we can make one ourselves using ctypes
-    if not hasattr(socket, 'inet_ntop'):
-        addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
-
-        def inet_ntop(family, host):
-            """Converting an IP address in packed
-            binary format to string format"""
-            if family == socket.AF_INET:
-                if len(host) != 4:
-                    raise ValueError("invalid IPv4 host")
-                host = pack("hH4s8s", socket.AF_INET, 0, host, "\0" * 8)
-            elif family == socket.AF_INET6:
-                if len(host) != 16:
-                    raise ValueError("invalid IPv6 host")
-                host = pack("hHL16sL", socket.AF_INET6, 0, 0, host, 0)
-            else:
-                raise ValueError("invalid address family")
-            buf = "\0" * 64
-            lengthBuf = pack("I", len(buf))
-            addressToString(host, len(host), None, buf, lengthBuf)
-            return buf[0:buf.index("\0")]
-        socket.inet_ntop = inet_ntop
-
-    # Same for inet_pton
-    if not hasattr(socket, 'inet_pton'):
-        stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
-
-        def inet_pton(family, host):
-            """Converting an IP address in string format
-            to a packed binary format"""
-            buf = "\0" * 28
-            lengthBuf = pack("I", len(buf))
-            if stringToAddress(str(host),
-                               int(family),
-                               None,
-                               buf,
-                               lengthBuf) != 0:
-                raise socket.error("illegal IP address passed to inet_pton")
-            if family == socket.AF_INET:
-                return buf[4:8]
-            elif family == socket.AF_INET6:
-                return buf[8:24]
-            else:
-                raise ValueError("invalid address family")
-        socket.inet_pton = inet_pton
-
-    # These sockopts are needed on for IPv6 support
-    if not hasattr(socket, 'IPPROTO_IPV6'):
-        socket.IPPROTO_IPV6 = 41
-    if not hasattr(socket, 'IPV6_V6ONLY'):
-        socket.IPV6_V6ONLY = 27
-
-
 def signal_handler(signum, frame):
     """Single handler for any signal sent to pybitmessage"""
     process = multiprocessing.current_process()
@@ -151,7 +87,7 @@ class Main(object):
     def start(self):
         """Start main application"""
         # pylint: disable=too-many-statements,too-many-branches,too-many-locals
-        _fixSocket()
+        fixSocket()
         adjustHalfOpenConnectionsLimit()
 
         config = BMConfigParser()
diff --git a/src/helper_startup.py b/src/helper_startup.py
index 56bf87cb..c0c35fd9 100644
--- a/src/helper_startup.py
+++ b/src/helper_startup.py
@@ -3,12 +3,15 @@ Startup operations.
 """
 # pylint: disable=too-many-branches,too-many-statements
 
+import ctypes
 import logging
 import os
 import platform
+import socket
 import sys
 import time
 from distutils.version import StrictVersion
+from struct import pack
 
 try:
     import defaults
@@ -304,6 +307,68 @@ def adjustHalfOpenConnectionsLimit():
     state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64
 
 
+def fixSocket():
+    """Add missing socket options and methods mainly on Windows"""
+    if sys.platform.startswith('linux'):
+        socket.SO_BINDTODEVICE = 25
+
+    if not sys.platform.startswith('win'):
+        return
+
+    # Python 2 on Windows doesn't define a wrapper for
+    # socket.inet_ntop but we can make one ourselves using ctypes
+    if not hasattr(socket, 'inet_ntop'):
+        addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
+
+        def inet_ntop(family, host):
+            """Converting an IP address in packed
+            binary format to string format"""
+            if family == socket.AF_INET:
+                if len(host) != 4:
+                    raise ValueError("invalid IPv4 host")
+                host = pack("hH4s8s", socket.AF_INET, 0, host, "\0" * 8)
+            elif family == socket.AF_INET6:
+                if len(host) != 16:
+                    raise ValueError("invalid IPv6 host")
+                host = pack("hHL16sL", socket.AF_INET6, 0, 0, host, 0)
+            else:
+                raise ValueError("invalid address family")
+            buf = "\0" * 64
+            lengthBuf = pack("I", len(buf))
+            addressToString(host, len(host), None, buf, lengthBuf)
+            return buf[0:buf.index("\0")]
+        socket.inet_ntop = inet_ntop
+
+    # Same for inet_pton
+    if not hasattr(socket, 'inet_pton'):
+        stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
+
+        def inet_pton(family, host):
+            """Converting an IP address in string format
+            to a packed binary format"""
+            buf = "\0" * 28
+            lengthBuf = pack("I", len(buf))
+            if stringToAddress(str(host),
+                               int(family),
+                               None,
+                               buf,
+                               lengthBuf) != 0:
+                raise socket.error("illegal IP address passed to inet_pton")
+            if family == socket.AF_INET:
+                return buf[4:8]
+            elif family == socket.AF_INET6:
+                return buf[8:24]
+            else:
+                raise ValueError("invalid address family")
+        socket.inet_pton = inet_pton
+
+    # These sockopts are needed on for IPv6 support
+    if not hasattr(socket, 'IPPROTO_IPV6'):
+        socket.IPPROTO_IPV6 = 41
+    if not hasattr(socket, 'IPV6_V6ONLY'):
+        socket.IPV6_V6ONLY = 27
+
+
 def start_proxyconfig():
     """Check socksproxytype and start any proxy configuration plugin"""
     if not get_plugin:
diff --git a/src/tests/core.py b/src/tests/core.py
index 92d66bc0..18685e13 100644
--- a/src/tests/core.py
+++ b/src/tests/core.py
@@ -3,6 +3,7 @@ Tests for core and those that do not work outside
 (because of import error for example)
 """
 
+import atexit
 import os
 import pickle  # nosec
 import Queue
@@ -416,8 +417,9 @@ def run():
     suite = loader.loadTestsFromTestCase(TestCore)
     try:
         import bitmessageqt.tests
+        from xvfbwrapper import Xvfb
     except ImportError:
-        pass
+        Xvfb = None
     else:
         qt_tests = loader.loadTestsFromModule(bitmessageqt.tests)
         suite.addTests(qt_tests)
@@ -428,4 +430,8 @@ def run():
 
     sys.excepthook = keep_exc
 
+    if Xvfb:
+        vdisplay = Xvfb(width=1024, height=768)
+        vdisplay.start()
+        atexit.register(vdisplay.stop)
     return unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/src/tests/test_logger.py b/src/tests/test_logger.py
index da0f9341..d6bf33ed 100644
--- a/src/tests/test_logger.py
+++ b/src/tests/test_logger.py
@@ -29,7 +29,7 @@ format=%(asctime)s {1} %(message)s
 class=FileHandler
 level=NOTSET
 formatter=default
-args=('{0}', 'w')
+args=({0!r}, 'w')
 
 [logger_root]
 level=DEBUG
diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index 7f7691d1..bcec289f 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -192,6 +192,7 @@ class TestProcessShutdown(TestProcessProto):
 
 class TestProcess(TestProcessProto):
     """A test case for pybitmessage process"""
+    @unittest.skipIf(sys.platform[:5] != 'linux', 'probably needs prctl')
     def test_process_name(self):
         """Check PyBitmessage process name"""
         self.assertEqual(self.process.name(), 'PyBitmessage')
diff --git a/src/tests/test_protocol.py b/src/tests/test_protocol.py
index ee649481..d285d1df 100644
--- a/src/tests/test_protocol.py
+++ b/src/tests/test_protocol.py
@@ -6,11 +6,17 @@ import sys
 import unittest
 
 from pybitmessage import protocol, state
+from pybitmessage.helper_startup import fixSocket
 
 
 class TestProtocol(unittest.TestCase):
     """Main protocol test case"""
 
+    @classmethod
+    def setUpClass(cls):
+        """Execute fixSocket() before start. Only for Windows?"""
+        fixSocket()
+
     def test_checkIPv4Address(self):
         """Check the results of protocol.checkIPv4Address()"""
         token = 'HELLO'