From 68e0d0dbe7f251c2fde7380d0b5afa4b982e0ff1 Mon Sep 17 00:00:00 2001
From: Inso <insomniak.fr@gmail.com>
Date: Sat, 28 Nov 2015 19:51:59 +0100
Subject: [PATCH] Fix tests in travis and appveyor and raise exception from
 coroutines

---
 src/cutecoin/gui/process_cfg_community.py     |  2 +-
 src/cutecoin/tests/__init__.py                |  2 +-
 src/cutecoin/tests/core/test_account.py       | 13 ++-----
 src/cutecoin/tests/core/test_bma_access.py    | 14 ++-----
 src/cutecoin/tests/core/test_community.py     | 13 ++-----
 src/cutecoin/tests/core/test_identities.py    | 13 ++-----
 src/cutecoin/tests/core/test_identity.py      | 19 ++++------
 src/cutecoin/tests/core/test_wallet.py        | 13 ++-----
 .../core/txhistory/test_txhistory_loading.py  | 14 ++-----
 .../gui/certification/test_certification.py   | 14 ++-----
 .../identities_tab/test_identities_table.py   | 17 +++------
 .../main_window/test_main_window_dialogs.py   | 14 ++-----
 .../gui/main_window/test_main_window_menus.py | 13 ++-----
 .../preferences/test_preferences_dialog.py    | 27 +++----------
 .../process_cfg_account/test_add_account.py   | 13 ++-----
 .../test_add_community.py                     | 14 ++-----
 .../tests/gui/transfer/test_transfer.py       | 14 ++-----
 .../tests/gui/wot_tab/test_wot_tab.py         | 14 ++-----
 .../tests/{qapp.py => quamash_test.py}        | 38 ++++++++++---------
 19 files changed, 93 insertions(+), 188 deletions(-)
 rename src/cutecoin/tests/{qapp.py => quamash_test.py} (50%)

diff --git a/src/cutecoin/gui/process_cfg_community.py b/src/cutecoin/gui/process_cfg_community.py
index a9fcbab6..47d6e097 100644
--- a/src/cutecoin/gui/process_cfg_community.py
+++ b/src/cutecoin/gui/process_cfg_community.py
@@ -93,7 +93,7 @@ class StepPageInit(Step):
                 self.config_dialog.label_error.setText(self.tr("Could not find your identity on the network."))
             elif registered[0] is False and registered[2]:
                 self.config_dialog.label_error.setText(self.tr("""Your pubkey or UID is different on the network.
-    Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
+Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
             else:
                 self.config_dialog.community = community
                 self.config_dialog.next()
diff --git a/src/cutecoin/tests/__init__.py b/src/cutecoin/tests/__init__.py
index 75eaa872..7d9d5e42 100644
--- a/src/cutecoin/tests/__init__.py
+++ b/src/cutecoin/tests/__init__.py
@@ -1 +1 @@
-from .qapp import get_application, unitttest_exception_handler
\ No newline at end of file
+from .quamash_test import QuamashTest
\ No newline at end of file
diff --git a/src/cutecoin/tests/core/test_account.py b/src/cutecoin/tests/core/test_account.py
index 4fbbf67e..6de121ce 100644
--- a/src/cutecoin/tests/core/test_account.py
+++ b/src/cutecoin/tests/core/test_account.py
@@ -6,22 +6,17 @@ import logging
 from PyQt5.QtCore import QLocale
 from cutecoin.core.registry.identities import IdentitiesRegistry
 from cutecoin.core import Account
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 
 
-class TestAccount(unittest.TestCase):
+class TestAccount(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry()
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_load_save_account(self):
         account = Account("test_salt", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
diff --git a/src/cutecoin/tests/core/test_bma_access.py b/src/cutecoin/tests/core/test_bma_access.py
index f1f0c83e..f4af6ac9 100644
--- a/src/cutecoin/tests/core/test_bma_access.py
+++ b/src/cutecoin/tests/core/test_bma_access.py
@@ -8,7 +8,7 @@ from PyQt5.QtCore import QLocale
 from cutecoin.core.registry.identities import Identity, IdentitiesRegistry, LocalState, BlockchainState
 from cutecoin.tests.mocks.monkeypatch import pretender_reversed
 from cutecoin.tests.mocks.bma import nice_blockchain, corrupted
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 from cutecoin.core import Application, Community
 from cutecoin.core.net import Network, Node
 from ucoinpy.documents.peer import BMAEndpoint
@@ -17,12 +17,10 @@ from cutecoin.tools.exceptions import MembershipNotFoundError
 from ucoinpy.api.bma import API
 
 
-class TestBmaAccess(unittest.TestCase):
+class TestBmaAccess(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry()
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -38,11 +36,7 @@ class TestBmaAccess(unittest.TestCase):
         self.community = Community("test_currency", self.network, self.bma_access)
 
     def tearDown(self):
-        try:
-            if not self.lp.is_closed():
-                self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_compare_json_with_nonetype(self):
         res = self.bma_access._compare_json({}, corrupted.bma_null_data)
diff --git a/src/cutecoin/tests/core/test_community.py b/src/cutecoin/tests/core/test_community.py
index 97ff383e..07a5fb9b 100644
--- a/src/cutecoin/tests/core/test_community.py
+++ b/src/cutecoin/tests/core/test_community.py
@@ -8,21 +8,16 @@ from cutecoin.core.registry.identities import IdentitiesRegistry
 from cutecoin.core.net.api.bma.access import BmaAccess
 from cutecoin.core.net.network import Network
 from cutecoin.core import Community
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 
 
-class TestCommunity(unittest.TestCase):
+class TestCommunity(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_load_save_community(self):
         network = Network("test_currency", [])
diff --git a/src/cutecoin/tests/core/test_identities.py b/src/cutecoin/tests/core/test_identities.py
index 5b862cdb..a9f46641 100644
--- a/src/cutecoin/tests/core/test_identities.py
+++ b/src/cutecoin/tests/core/test_identities.py
@@ -6,21 +6,16 @@ import quamash
 import logging
 from PyQt5.QtCore import QLocale
 from cutecoin.core.registry.identities import Identity, IdentitiesRegistry, LocalState, BlockchainState
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 
 
-class TestIdentity(unittest.TestCase):
+class TestIdentity(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_identity_from_handled_data(self):
         community = mock.MagicMock()
diff --git a/src/cutecoin/tests/core/test_identity.py b/src/cutecoin/tests/core/test_identity.py
index 7af9db4f..03412853 100644
--- a/src/cutecoin/tests/core/test_identity.py
+++ b/src/cutecoin/tests/core/test_identity.py
@@ -8,7 +8,7 @@ from PyQt5.QtCore import QLocale
 from cutecoin.core.registry.identities import Identity, IdentitiesRegistry, LocalState, BlockchainState
 from cutecoin.tests.mocks.monkeypatch import pretender_reversed
 from cutecoin.tests.mocks.bma import nice_blockchain, corrupted
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 from cutecoin.core import Application, Community
 from cutecoin.core.net import Network, Node
 from ucoinpy.documents.peer import BMAEndpoint
@@ -17,12 +17,10 @@ from cutecoin.tools.exceptions import MembershipNotFoundError
 from ucoinpy.api.bma import API
 
 
-class TestIdentity(unittest.TestCase):
+class TestIdentity(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry()
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -38,17 +36,14 @@ class TestIdentity(unittest.TestCase):
         self.community = Community("test_currency", self.network, self.bma_access)
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_identity_certified_by(self):
         mock = nice_blockchain.get_mock()
         time.sleep(2)
         logging.debug(mock.pretend_url)
         API.reverse_url = pretender_reversed(mock.pretend_url)
-        identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+        identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831,
                             LocalState.COMPLETED, BlockchainState.VALIDATED)
 
         @asyncio.coroutine
@@ -65,7 +60,7 @@ class TestIdentity(unittest.TestCase):
         time.sleep(2)
         logging.debug(mock.pretend_url)
         API.reverse_url = pretender_reversed(mock.pretend_url)
-        identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+        identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831,
                             LocalState.COMPLETED, BlockchainState.VALIDATED)
 
         @asyncio.coroutine
@@ -84,7 +79,7 @@ class TestIdentity(unittest.TestCase):
         time.sleep(2)
         logging.debug(mock.pretend_url)
         API.reverse_url = pretender_reversed(mock.pretend_url)
-        identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+        identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831,
                             LocalState.COMPLETED, BlockchainState.VALIDATED)
 
         @asyncio.coroutine
diff --git a/src/cutecoin/tests/core/test_wallet.py b/src/cutecoin/tests/core/test_wallet.py
index 05db39fe..4130f456 100644
--- a/src/cutecoin/tests/core/test_wallet.py
+++ b/src/cutecoin/tests/core/test_wallet.py
@@ -6,22 +6,17 @@ import logging
 from PyQt5.QtCore import QLocale
 from cutecoin.core.registry.identities import IdentitiesRegistry
 from cutecoin.core import Wallet
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 
 
-class TestWallet(unittest.TestCase):
+class TestWallet(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry({})
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_load_save_wallet(self):
         wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
diff --git a/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py b/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py
index 18bced16..d75f19c1 100644
--- a/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py
+++ b/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py
@@ -6,23 +6,20 @@ import time
 import logging
 from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint
 from PyQt5.QtCore import QLocale, Qt
-from PyQt5.QtTest import QTest
 from cutecoin.tests.mocks.bma import nice_blockchain
 from cutecoin.core.registry.identities import IdentitiesRegistry
 from cutecoin.core.app import Application
 from cutecoin.core import Account, Community, Wallet
 from cutecoin.core.net import Network, Node
 from cutecoin.core.net.api.bma.access import BmaAccess
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 from ucoinpy.documents.peer import BMAEndpoint
 
 
-class TestTxHistory(unittest.TestCase):
+class TestTxHistory(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry({})
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -47,10 +44,7 @@ class TestTxHistory(unittest.TestCase):
                                "john", [self.community], [self.wallet], [], self.identities_registry)
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     # this test fails with old algorithm
     def notest_txhistory_reload(self):
diff --git a/src/cutecoin/tests/gui/certification/test_certification.py b/src/cutecoin/tests/gui/certification/test_certification.py
index 0e2de3a8..d319758e 100644
--- a/src/cutecoin/tests/gui/certification/test_certification.py
+++ b/src/cutecoin/tests/gui/certification/test_certification.py
@@ -19,17 +19,14 @@ from cutecoin.core.app import Application
 from cutecoin.core import Account, Community, Wallet
 from cutecoin.core.net import Network, Node
 from cutecoin.core.net.api.bma.access import BmaAccess
-from cutecoin.tests import get_application, unitttest_exception_handler
+from cutecoin.tests import QuamashTest
 from ucoinpy.api import bma
 
 
-class TestCertificationDialog(unittest.TestCase):
+class TestCertificationDialog(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
-        #self.lp.set_exception_handler(lambda lp, ctx : unitttest_exception_handler(self, lp, ctx))
         self.identities_registry = IdentitiesRegistry({})
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -57,10 +54,7 @@ class TestCertificationDialog(unittest.TestCase):
         self.password_asker.remember = True
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_certification_init_community(self):
         mock = init_new_community.get_mock()
diff --git a/src/cutecoin/tests/gui/identities_tab/test_identities_table.py b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py
index 5a553d05..2639dc56 100644
--- a/src/cutecoin/tests/gui/identities_tab/test_identities_table.py
+++ b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py
@@ -19,15 +19,13 @@ from cutecoin.core import Account, Community, Wallet
 from cutecoin.core.net import Network, Node
 from ucoinpy.documents.peer import BMAEndpoint
 from cutecoin.core.net.api.bma.access import BmaAccess
-from cutecoin.tests import get_application, unitttest_exception_handler
+from cutecoin.tests import QuamashTest
 
 
-class TestIdentitiesTable(unittest.TestCase):
+class TestIdentitiesTable(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry()
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -55,10 +53,7 @@ class TestIdentitiesTable(unittest.TestCase):
         self.password_asker.remember = True
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_search_identity_found(self):
         mock = nice_blockchain.get_mock()
@@ -82,7 +77,7 @@ class TestIdentitiesTable(unittest.TestCase):
         @asyncio.coroutine
         def exec_test():
             yield from asyncio.sleep(2)
-            urls = [mock.get_request(i).url for i in range(0, 6)]
+            urls = [mock.get_request(i).url for i in range(0, 7)]
             self.assertTrue('/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls,
                             msg="Not found in {0}".format(urls))
             self.assertTrue('/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls,
@@ -97,7 +92,7 @@ class TestIdentitiesTable(unittest.TestCase):
             QTest.keyClicks(identities_tab.edit_textsearch, "doe")
             QTest.mouseClick(identities_tab.button_search, Qt.LeftButton)
             yield from asyncio.sleep(2)
-            req = 6
+            req = 7
 
             self.assertEqual(mock.get_request(req).method, 'GET')
             self.assertEqual(mock.get_request(req).url,
diff --git a/src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py b/src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py
index a3f55041..fab668dc 100644
--- a/src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py
+++ b/src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py
@@ -6,28 +6,22 @@ from PyQt5.QtCore import QLocale, QTimer
 from PyQt5.QtNetwork import QNetworkAccessManager
 from cutecoin.gui.mainwindow import MainWindow
 from cutecoin.core.app import Application
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 from cutecoin.core.registry.identities import IdentitiesRegistry
 
 # Qapplication cause a core dumped when re-run in setup
 # set it as global var
 
-class MainWindowDialogsTest(unittest.TestCase):
+class MainWindowDialogsTest(unittest.TestCase, QuamashTest):
     def setUp(self):
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.qapplication = get_application()
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
 
         self.application = Application(self.qapplication, self.lp, IdentitiesRegistry())
         self.main_window = MainWindow(self.application)
 
     def tearDown(self):
-        # delete all top widgets from main QApplication
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_action_about(self):
         #select menu
diff --git a/src/cutecoin/tests/gui/main_window/test_main_window_menus.py b/src/cutecoin/tests/gui/main_window/test_main_window_menus.py
index 6fe831e8..d6078bb1 100644
--- a/src/cutecoin/tests/gui/main_window/test_main_window_menus.py
+++ b/src/cutecoin/tests/gui/main_window/test_main_window_menus.py
@@ -7,23 +7,18 @@ from PyQt5.QtWidgets import QMenu
 from PyQt5.QtCore import QLocale
 from cutecoin.gui.mainwindow import MainWindow
 from cutecoin.core.app import Application
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 
-class MainWindowMenusTest(unittest.TestCase):
+class MainWindowMenusTest(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
 
         self.application = Application(self.qapplication, self.lp, None)
         self.main_window = MainWindow(self.application)
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_menubar(self):
         children = self.main_window.menubar.children()
diff --git a/src/cutecoin/tests/gui/preferences/test_preferences_dialog.py b/src/cutecoin/tests/gui/preferences/test_preferences_dialog.py
index d9a771ea..f8d9d032 100644
--- a/src/cutecoin/tests/gui/preferences/test_preferences_dialog.py
+++ b/src/cutecoin/tests/gui/preferences/test_preferences_dialog.py
@@ -2,40 +2,23 @@ import sys
 import unittest
 import asyncio
 import quamash
-import time
 import logging
-from ucoinpy.documents.peer import BMAEndpoint
-from quamash import QApplication
-from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox
-from PyQt5.QtCore import QLocale, Qt
-from PyQt5.QtTest import QTest
-from ucoinpy.api.bma import API
-from cutecoin.tests.mocks.monkeypatch import pretender_reversed
-from cutecoin.tests.mocks.bma import init_new_community
+from PyQt5.QtCore import QLocale
 from cutecoin.core.registry.identities import IdentitiesRegistry
 from cutecoin.gui.preferences import PreferencesDialog
 from cutecoin.core.app import Application
-from cutecoin.core import Account, Community, Wallet
-from cutecoin.core.net import Network, Node
-from cutecoin.core.net.api.bma.access import BmaAccess
-from cutecoin.tests import get_application, unitttest_exception_handler
+from cutecoin.tests import QuamashTest
 from ucoinpy.api import bma
 
 
-class TestCertificationDialog(unittest.TestCase):
+class TestPreferencesDialog(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
-        #self.lp.set_exception_handler(lambda lp, ctx : unitttest_exception_handler(self, lp, ctx))
         self.identities_registry = IdentitiesRegistry({})
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_preferences_default(self):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
diff --git a/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py b/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py
index 9f35dad5..49ee670b 100644
--- a/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py
+++ b/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py
@@ -12,15 +12,13 @@ from cutecoin.gui.process_cfg_account import ProcessConfigureAccount
 from cutecoin.gui.password_asker import PasswordAskerDialog
 from cutecoin.core.app import Application
 from cutecoin.core.account import Account
-from cutecoin.tests import get_application
+from cutecoin.tests import QuamashTest
 
 
-class ProcessAddCommunity(unittest.TestCase):
+class ProcessAddCommunity(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
         self.identities_registry = IdentitiesRegistry({})
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -34,10 +32,7 @@ class ProcessAddCommunity(unittest.TestCase):
         self.password_asker.remember = True
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_create_account(self):
         process_account = ProcessConfigureAccount(self.application,
diff --git a/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py b/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py
index ce466074..0190127c 100644
--- a/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py
+++ b/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py
@@ -15,16 +15,13 @@ from cutecoin.gui.process_cfg_community import ProcessConfigureCommunity
 from cutecoin.gui.password_asker import PasswordAskerDialog
 from cutecoin.core.app import Application
 from cutecoin.core.account import Account
-from cutecoin.tests import get_application, unitttest_exception_handler
+from cutecoin.tests import QuamashTest
 
 
-class ProcessAddCommunity(unittest.TestCase):
+class ProcessAddCommunity(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
-        #self.lp.set_exception_handler(lambda lp, ctx : unitttest_exception_handler(self, lp, ctx))
         self.identities_registry = IdentitiesRegistry({})
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -38,10 +35,7 @@ class ProcessAddCommunity(unittest.TestCase):
         self.password_asker.remember = True
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_register_community_empty_blockchain(self):
         mock = new_blockchain.get_mock()
diff --git a/src/cutecoin/tests/gui/transfer/test_transfer.py b/src/cutecoin/tests/gui/transfer/test_transfer.py
index e3dc8327..24d0ab69 100644
--- a/src/cutecoin/tests/gui/transfer/test_transfer.py
+++ b/src/cutecoin/tests/gui/transfer/test_transfer.py
@@ -19,17 +19,14 @@ from cutecoin.core import Account, Community, Wallet
 from cutecoin.core.net import Network, Node
 from ucoinpy.documents.peer import BMAEndpoint
 from cutecoin.core.net.api.bma.access import BmaAccess
-from cutecoin.tests import get_application, unitttest_exception_handler
+from cutecoin.tests import QuamashTest
 from ucoinpy.api import bma
 
 
-class TestTransferDialog(unittest.TestCase):
+class TestTransferDialog(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
-        #self.lp.set_exception_handler(lambda lp, ctx : unitttest_exception_handler(self, lp, ctx))
         self.identities_registry = IdentitiesRegistry({})
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -57,10 +54,7 @@ class TestTransferDialog(unittest.TestCase):
         self.password_asker.remember = True
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_transfer_nice_community(self):
         mock = nice_blockchain.get_mock()
diff --git a/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py b/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py
index af48ad83..a1be3839 100644
--- a/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py
+++ b/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py
@@ -19,16 +19,13 @@ from cutecoin.core.app import Application
 from cutecoin.core import Account, Community, Wallet
 from cutecoin.core.net import Network, Node
 from cutecoin.core.net.api.bma.access import BmaAccess
-from cutecoin.tests import get_application, unitttest_exception_handler
+from cutecoin.tests import QuamashTest
 
 
-class TestIdentitiesTable(unittest.TestCase):
+class TestWotTab(unittest.TestCase, QuamashTest):
     def setUp(self):
-        self.qapplication = get_application()
+        self.setUpQuamash()
         QLocale.setDefault(QLocale("en_GB"))
-        self.lp = quamash.QEventLoop(self.qapplication)
-        asyncio.set_event_loop(self.lp)
-        self.lp.set_exception_handler(lambda lp, ctx : unitttest_exception_handler(self, lp, ctx))
         self.identities_registry = IdentitiesRegistry()
 
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
@@ -56,10 +53,7 @@ class TestIdentitiesTable(unittest.TestCase):
         self.password_asker.remember = True
 
     def tearDown(self):
-        try:
-            self.lp.close()
-        finally:
-            asyncio.set_event_loop(None)
+        self.tearDownQuamash()
 
     def test_empty_wot_tab(self):
         mock = nice_blockchain.get_mock()
diff --git a/src/cutecoin/tests/qapp.py b/src/cutecoin/tests/quamash_test.py
similarity index 50%
rename from src/cutecoin/tests/qapp.py
rename to src/cutecoin/tests/quamash_test.py
index 708b11fa..09d5d107 100644
--- a/src/cutecoin/tests/qapp.py
+++ b/src/cutecoin/tests/quamash_test.py
@@ -1,7 +1,26 @@
+import asyncio
+import quamash
 
 _application_ = []
 
 
+class QuamashTest:
+    def setUpQuamash(self):
+        self.qapplication = get_application()
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.lp.set_exception_handler(lambda l, c: unitttest_exception_handler(self, l, c))
+        self.exceptions = []
+
+    def tearDownQuamash(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+        for exc in self.exceptions:
+            raise exc
+
+
 def unitttest_exception_handler(test, loop, context):
     """
     An exception handler which exists the program if the exception
@@ -9,23 +28,8 @@ def unitttest_exception_handler(test, loop, context):
     :param loop: the asyncio loop
     :param context: the exception context
     """
-    message = context.get('message')
-    if not message:
-        message = 'Unhandled exception in event loop'
-
-    try:
-        exception = context['exception']
-    except KeyError:
-        exc_info = False
-    else:
-        exc_info = (type(exception), exception, exception.__traceback__)
-
-    log_lines = [message]
-    for key in [k for k in sorted(context) if k not in {'message', 'exception'}]:
-        log_lines.append('{}: {!r}'.format(key, context[key]))
-
-    test.fail('\n'.join(log_lines))
-
+    exception = context['exception']
+    test.exceptions.append(exception)
 
 
 def get_application():
-- 
GitLab