diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result
new file mode 100644
index 0000000000000000000000000000000000000000..2cbea1b12f7dbce2dd4ffdee9918376813c49467
--- /dev/null
+++ b/test/box/bad_trigger.result
@@ -0,0 +1,15 @@
+ 
+ #
+ # if on_connect() trigger raises an exception, the connection is dropped
+ # 
+ 
+type(box.session.on_connect(function() nosuchfunction() end))
+---
+- nil
+...
+Exception raised
+
+type(box.session.on_connect(nil))
+---
+- function
+...
diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e6f851caed34f9bd7dbb7ed84746b82609ba1c8
--- /dev/null
+++ b/test/box/bad_trigger.test.py
@@ -0,0 +1,17 @@
+from lib.box_connection import BoxConnection
+print """ 
+ #
+ # if on_connect() trigger raises an exception, the connection is dropped
+ # 
+ """
+
+admin("type(box.session.on_connect(function() nosuchfunction() end))")
+con1 = BoxConnection('localhost', server.primary_port)
+try:
+    con1.execute("select * from t0 where k0=0")
+    con1.execute("select * from t0 where k0=0")
+except Exception as e:
+    print "Exception raised\n"
+
+# Clean-up
+admin("type(box.session.on_connect(nil))")
diff --git a/test/box/configuration.test.py b/test/box/configuration.test.py
index a7688d2fc7014f2e85bb5dbe24e0a45f80e7dd9e..c7335d399700e974ff46f42707e35cb09b23e329 100644
--- a/test/box/configuration.test.py
+++ b/test/box/configuration.test.py
@@ -1,6 +1,3 @@
-# encoding: utf-8
-#
-
 import os
 import sys
 import shutil
@@ -27,12 +24,9 @@ server.stop()
 server.deploy("box/tarantool_scriptdir.cfg")
 admin("print_config()")
 
-
 # restore default server
 server.stop()
 shutil.rmtree(script_dir_path, True)
 server.deploy(self.suite_ini["config"])
 
 sys.stdout.pop_filter()
-
-# vim: syntax=python
diff --git a/test/box/session.result b/test/box/session.result
index b860330e8c27da1a7f70515685e2d9f74d80ecb1..f8cb1a0206901a92963e8181f8444d71df1641aa 100644
--- a/test/box/session.result
+++ b/test/box/session.result
@@ -1,22 +1,31 @@
+box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum')
+---
+- [0, 0, 'tweedledum']
+...
+box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')
+---
+- [0, 0, 'primary', 1752392040, 1, 1, 0, 'num']
+...
 box.session.exists(box.session.id())
 ---
- - 1
+- 1
 ...
 box.session.exists()
 ---
-error: 'session.exists(sid): bad arguments'
+- error: 'session.exists(sid): bad arguments'
 ...
 box.session.exists(1, 2, 3)
 ---
-error: 'session.exists(sid): bad arguments'
+- error: 'session.exists(sid): bad arguments'
 ...
 box.session.exists(1234567890)
 ---
- - 0
+- 0
 ...
+-- check session.id()
 box.session.id() > 0
 ---
- - true
+- true
 ...
 f = box.fiber.create(function() box.fiber.detach() failed = box.session.id() ~= 0 end)
 ---
@@ -26,87 +35,92 @@ box.fiber.resume(f)
 ...
 failed
 ---
- - false
+- false
 ...
 f1 = box.fiber.create(function() if box.session.id() == 0 then failed = true end end)
 ---
 ...
 box.fiber.resume(f1)
 ---
- - true
+- true
 ...
 failed
 ---
- - false
+- false
 ...
 box.session.peer() == box.session.peer(box.session.id())
 ---
- - true
+- true
 ...
+-- check on_connect/on_disconnect triggers
 box.session.on_connect(function() end)
 ---
- - nil
+- null
 ...
 box.session.on_disconnect(function() end)
 ---
- - nil
+- null
 ...
+-- check it's possible to reset these triggers
 type(box.session.on_connect(function() error('hear') end))
 ---
- - function
+- function
 ...
 type(box.session.on_disconnect(function() error('hear') end))
 ---
- - function
+- function
 ...
+-- check on_connect/on_disconnect argument count and type
 box.session.on_connect()
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_disconnect()
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_connect(function() end, function() end)
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_disconnect(function() end, function() end)
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_connect(1, 2)
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_disconnect(1, 2)
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_connect(1)
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
 box.session.on_disconnect(1)
 ---
-error: 'session.on_connect(chunk): bad arguments'
+- error: 'session.on_connect(chunk): bad arguments'
 ...
+-- use of nil to clear the trigger
 type(box.session.on_connect(nil))
 ---
- - function
+- function
 ...
 type(box.session.on_disconnect(nil))
 ---
- - function
+- function
 ...
 type(box.session.on_connect(nil))
 ---
- - nil
+- nil
 ...
 type(box.session.on_disconnect(nil))
 ---
- - nil
+- nil
 ...
+-- check how connect/disconnect triggers work
 function inc() active_connections = active_connections + 1 end
 ---
 ...
@@ -115,57 +129,69 @@ function dec() active_connections = active_connections - 1 end
 ...
 box.session.on_connect(inc)
 ---
- - nil
+- null
 ...
 box.session.on_disconnect(dec)
 ---
- - nil
+- null
 ...
 active_connections = 0
 ---
 ...
+--# create connection con_one to default
 active_connections
 ---
- - 1
+- 1
 ...
+--# create connection con_two to default
 active_connections
 ---
- - 2
+- 2
+...
+--# drop connection con_one
+--# drop connection con_two
+active_connections
+---
+- 0
 ...
 type(box.session.on_connect(nil))
 ---
- - function
+- function
 ...
 type(box.session.on_disconnect(nil))
 ---
- - function
+- function
 ...
+-- write audit trail of connect/disconnect into a space
 box.session.on_connect(function() box.insert(0, box.session.id()) end)
 ---
- - nil
+- null
 ...
 box.session.on_disconnect(function() box.delete(0, box.session.id()) end)
 ---
- - nil
+- null
 ...
+--# create connection con_three to default
+--# set connection con_three
 box.unpack('i', box.select(0, 0, box.session.id())[0]) == box.session.id()
 ---
- - true
-...
-type(box.session.on_connect(function() nosuchfunction() end))
----
- - function
+- true
 ...
-disconnected
+--# set connection default
+--# drop connection con_three
+-- cleanup
 type(box.session.on_connect(nil))
 ---
- - function
+- function
 ...
 type(box.session.on_disconnect(nil))
 ---
- - function
+- function
 ...
 active_connections
 ---
- - 0
+- 0
+...
+box.space[0]:drop()
+---
 ...
diff --git a/test/box/session.test.lua b/test/box/session.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..a61cc3d0a2963aac84fde3062e5641a2085e42c7
--- /dev/null
+++ b/test/box/session.test.lua
@@ -0,0 +1,78 @@
+box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum')
+box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')
+
+box.session.exists(box.session.id())
+box.session.exists()
+box.session.exists(1, 2, 3)
+box.session.exists(1234567890)
+
+-- check session.id()
+box.session.id() > 0
+f = box.fiber.create(function() box.fiber.detach() failed = box.session.id() ~= 0 end)
+box.fiber.resume(f)
+failed
+f1 = box.fiber.create(function() if box.session.id() == 0 then failed = true end end)
+box.fiber.resume(f1)
+failed
+box.session.peer() == box.session.peer(box.session.id())
+
+-- check on_connect/on_disconnect triggers
+box.session.on_connect(function() end)
+box.session.on_disconnect(function() end)
+
+-- check it's possible to reset these triggers
+type(box.session.on_connect(function() error('hear') end))
+type(box.session.on_disconnect(function() error('hear') end))
+
+-- check on_connect/on_disconnect argument count and type
+box.session.on_connect()
+box.session.on_disconnect()
+
+box.session.on_connect(function() end, function() end)
+box.session.on_disconnect(function() end, function() end)
+
+box.session.on_connect(1, 2)
+box.session.on_disconnect(1, 2)
+
+box.session.on_connect(1)
+box.session.on_disconnect(1)
+
+-- use of nil to clear the trigger
+type(box.session.on_connect(nil))
+type(box.session.on_disconnect(nil))
+type(box.session.on_connect(nil))
+type(box.session.on_disconnect(nil))
+
+-- check how connect/disconnect triggers work
+function inc() active_connections = active_connections + 1 end
+function dec() active_connections = active_connections - 1 end
+box.session.on_connect(inc)
+box.session.on_disconnect(dec)
+active_connections = 0
+--# create connection con_one to default
+active_connections
+--# create connection con_two to default
+active_connections
+--# drop connection con_one
+--# drop connection con_two
+active_connections
+
+type(box.session.on_connect(nil))
+type(box.session.on_disconnect(nil))
+
+-- write audit trail of connect/disconnect into a space
+box.session.on_connect(function() box.insert(0, box.session.id()) end)
+box.session.on_disconnect(function() box.delete(0, box.session.id()) end)
+
+--# create connection con_three to default 
+--# set connection con_three
+box.unpack('i', box.select(0, 0, box.session.id())[0]) == box.session.id()
+--# set connection default
+--# drop connection con_three
+
+-- cleanup
+type(box.session.on_connect(nil))
+type(box.session.on_disconnect(nil))
+active_connections
+
+box.space[0]:drop()
diff --git a/test/box/session.test.py b/test/box/session.test.py
deleted file mode 100644
index de7c22cbb800d34cc42d439109db67900590f7f9..0000000000000000000000000000000000000000
--- a/test/box/session.test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# encoding: utf-8
-from lib.admin_connection import AdminConnection
-from lib.box_connection import BoxConnection
-
-admin("box.session.exists(box.session.id())")
-admin("box.session.exists()")
-admin("box.session.exists(1, 2, 3)")
-admin("box.session.exists(1234567890)")
-
-# check session.id()
-admin("box.session.id() > 0")
-admin("f = box.fiber.create(function() box.fiber.detach() failed = box.session.id() ~= 0 end)")
-admin("box.fiber.resume(f)")
-admin("failed")
-admin("f1 = box.fiber.create(function() if box.session.id() == 0 then failed = true end end)")
-admin("box.fiber.resume(f1)")
-admin("failed")
-admin("box.session.peer() == box.session.peer(box.session.id())")
-
-# check on_connect/on_disconnect triggers
-admin("box.session.on_connect(function() end)")
-admin("box.session.on_disconnect(function() end)")
-
-# check it's possible to reset these triggers
-#
-admin("type(box.session.on_connect(function() error('hear') end))")
-admin("type(box.session.on_disconnect(function() error('hear') end))")
-
-# check on_connect/on_disconnect argument count and type
-admin("box.session.on_connect()")
-admin("box.session.on_disconnect()")
-
-admin("box.session.on_connect(function() end, function() end)")
-admin("box.session.on_disconnect(function() end, function() end)")
-
-admin("box.session.on_connect(1, 2)")
-admin("box.session.on_disconnect(1, 2)")
-
-admin("box.session.on_connect(1)")
-admin("box.session.on_disconnect(1)")
-
-# use of nil to clear the trigger
-admin("type(box.session.on_connect(nil))")
-admin("type(box.session.on_disconnect(nil))")
-admin("type(box.session.on_connect(nil))")
-admin("type(box.session.on_disconnect(nil))")
-
-# check how connect/disconnect triggers work
-admin("function inc() active_connections = active_connections + 1 end")
-admin("function dec() active_connections = active_connections - 1 end")
-admin("box.session.on_connect(inc)")
-admin("box.session.on_disconnect(dec)")
-admin("active_connections = 0")
-con1 = AdminConnection('localhost', server.admin_port)
-con1("active_connections")
-con2 = AdminConnection('localhost', server.admin_port)
-con2("active_connections")
-con1.disconnect()
-con2.disconnect()
-admin("type(box.session.on_connect(nil))")
-admin("type(box.session.on_disconnect(nil))")
-
-# write audit trail of connect/disconnect into a space
-admin("box.session.on_connect(function() box.insert(0, box.session.id()) end)")
-admin("box.session.on_disconnect(function() box.delete(0, box.session.id()) end)")
-con1("box.unpack('i', box.select(0, 0, box.session.id())[0]) == box.session.id()")
-con1.disconnect()
-
-# if on_connect() trigger raises an exception, the connection is dropped
-admin("type(box.session.on_connect(function() nosuchfunction() end))")
-con1 = BoxConnection('localhost', server.primary_port)
-try:
-    con1.execute("select * from t0 where k0=0")
-    con1.execute("select * from t0 where k0=0")
-except Exception as e:
-    print "disconnected"
-
-# cleanup
-
-admin("type(box.session.on_connect(nil))")
-admin("type(box.session.on_disconnect(nil))")
-admin("active_connections")
-
-# vim: syntax=python
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index ca11c1a308669ce3433e1f7bdbeb80efb68a72ee..1761ee7320967549ec60f5831d2241919ef6b5f4 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -132,7 +132,7 @@ class LuaTest(FuncTest):
                         elif matched2.group(1) == 'deploy':
                             name = matched2.group(2)
                             if name in self.suite_ini['servers']:
-                                self.suite_ini['servers'][name].deploy()
+                                self.suite_ini['servers'][name].deploy(silent=True)
                             else:
                                 raise LuaPreprocessorException("Wrong server name: " + name)
                         elif matched2.group(1) == 'reconfigure':
@@ -169,11 +169,12 @@ class LuaTest(FuncTest):
                 elif matched3:
                     try:
                         if matched3.group(1) == 'create':
-                            name, namecon = re.match("(.*)\s+to\s+(.*)", matched3.group(2)).groups()
-                            self.suite_ini['connections'][namecon] = AdminConnection('localhost', self.suite_ini['server'][name].port)
+                            namecon, name = re.match("(.*)\s+to\s+(.*)", matched3.group(2)).groups()
+                            self.suite_ini['connections'][namecon] = AdminConnection('localhost', self.suite_ini['servers'][name].port)
+                            self.suite_ini['connections'][namecon].connect()
                         elif matched3.group(1) == 'drop':
                             name = matched3.group(2)
-                            if name in self.suite_ini['connections'] and not self.suite_ini['connections'] is curcon:
+                            if name in self.suite_ini['connections']:
                                 self.suite_ini['connections'][name].disconnect()
                                 self.suite_ini['connections'].pop(name)
                             else:
@@ -270,7 +271,8 @@ class TarantoolServer(Server):
                                    '*.inprogress',
                                    '*.cfg',
                                    '*.sup',
-                                   '*.lua']
+                                   '*.lua',
+                                   '*.pid']
         self.process = None
         self.config = None
         self.vardir = None
diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py
index 73e2245adaae1e5e6b39f32a6ba2334e1a1c6dc7..62282d91fdf46f1e2072a78a06acaf735c565d50 100644
--- a/test/lib/test_suite.py
+++ b/test/lib/test_suite.py
@@ -215,7 +215,7 @@ class TestSuite:
         self.args = args
         self.tests = []
         self.ini = {}
-
+        self.suite_path = suite_path
         self.ini["core"] = "tarantool"
 
         if os.access(suite_path, os.F_OK) == False:
@@ -280,33 +280,34 @@ class TestSuite:
         print "TEST".ljust(48), "RESULT"
         print shortsep
         failed_tests = []
+        try:
+            for test in self.tests:
+                sys.stdout.write(test.name.ljust(48))
+                # for better diagnostics in case of a long-running test
+                sys.stdout.flush()
+
+                test_name = os.path.basename(test.name)
+
+                if (test_name in self.ini["disabled"]
+                    or not self.server.debug and test_name in self.ini["release_disabled"]
+                    or self.args.valgrind and test_name in self.ini["valgrind_disabled"]):
+                    print "[ disabled ]"
+                else:
+                    test.run(self.server)
+                    if not test.passed():
+                        failed_tests.append(test.name)
+        finally:
+            print '\n', shortsep
+            self.server.stop(silent=False)
+            self.server.cleanup()
 
-        for test in self.tests:
-            sys.stdout.write(test.name.ljust(48))
-            # for better diagnostics in case of a long-running test
-            sys.stdout.flush()
-
-            test_name = os.path.basename(test.name)
-
-            if (test_name in self.ini["disabled"]
-                or not self.server.debug and test_name in self.ini["release_disabled"]
-                or self.args.valgrind and test_name in self.ini["valgrind_disabled"]):
-                print "[ disabled ]"
-            else:
-                test.run(self.server)
-                if not test.passed():
-                    failed_tests.append(test.name)
-
-        print shortsep
         if failed_tests:
             print "Failed {0} tests: {1}.".format(len(failed_tests),
                                                 ", ".join(failed_tests))
-        self.server.stop(silent=False)
-        self.server.cleanup()
 
         if self.args.valgrind and check_valgrind_log(self.server.valgrind_log):
             print "  Error! There were warnings/errors in valgrind log file:"
             print_tail_n(self.server.valgrind_log, 20)
-            return 1
-        return len(failed_tests)
+            return ['valgrind error in ' + self.suite_path]
+        return failed_tests
 
diff --git a/test/replication/consistent.result b/test/replication/consistent.result
index ffc30b8bfef7549e038f55f4202cb1514268eb02..d70a9d1e5c69a3fefc318d35867db0e5ab7af6f5 100644
--- a/test/replication/consistent.result
+++ b/test/replication/consistent.result
@@ -20,9 +20,12 @@ function _insert(_begin, _end, msg)
 end;
 ---
 ...
+begin_lsn = box.info.lsn;
+---
+...
 function _select(_begin, _end)
     a = {}
-    while box.info.lsn < _end + 3 do
+    while box.info.lsn < begin_lsn + _end do
         box.fiber.sleep(0.001)
     end
     for i = _begin, _end do
diff --git a/test/replication/consistent.test.lua b/test/replication/consistent.test.lua
index 75e4db9ad002cc45de5300dcd37a0432502ffee3..bca123f762b72f00e582065be3e98f4e13486c3d 100644
--- a/test/replication/consistent.test.lua
+++ b/test/replication/consistent.test.lua
@@ -14,9 +14,11 @@ function _insert(_begin, _end, msg)
     return unpack(a)
 end;
 
+begin_lsn = box.info.lsn;
+
 function _select(_begin, _end)
     a = {}
-    while box.info.lsn < _end + 3 do
+    while box.info.lsn < begin_lsn + _end do
         box.fiber.sleep(0.001)
     end
     for i = _begin, _end do
diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result
index d522395ba3b01fc2f14694dcd17a731253cff4c1..b6d1767f74304dc3a0a710505794fed9a9f47465 100644
--- a/test/replication/hot_standby.result
+++ b/test/replication/hot_standby.result
@@ -2,14 +2,6 @@
 --# create server replica with configuration='replication/cfg/replica.cfg'
 --# start server hot_standby
 --# start server replica
-box.replace(box.schema.SPACE_ID, 0, 0, 'tweedledum')
----
-- [0, 0, 'tweedledum']
-...
-box.replace(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')
----
-- [0, 0, 'primary', 1752392040, 1, 1, 0, 'num']
-...
 --# setopt delimiter ';'
 --# set connection default, hot_standby, replica
 function _insert(_begin, _end)
@@ -30,15 +22,27 @@ function _select(_begin, _end)
 end;
 ---
 ...
-function _wait_lsn(_lsn)
-    while box.info.lsn < _lsn do
+begin_lsn = box.info.lsn;
+---
+...
+function _wait_lsn(_lsnd)
+    while box.info.lsn < _lsnd + begin_lsn do
         box.fiber.sleep(0.001)
     end
+    begin_lsn = begin_lsn + _lsnd
 end;
 ---
 ...
 --# setopt delimiter ''
 --# set connection default
+box.replace(box.schema.SPACE_ID, 0, 0, 'tweedledum')
+---
+- [0, 0, 'tweedledum']
+...
+box.replace(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')
+---
+- [0, 0, 'primary', 1752392040, 1, 1, 0, 'num']
+...
 _insert(1, 10)
 ---
 - [1, 'the tuple 1']
@@ -66,7 +70,7 @@ _select(1, 10)
 - [10, 'the tuple 10']
 ...
 --# set connection replica
-_wait_lsn(13)
+_wait_lsn(12)
 ---
 ...
 _select(1, 10)
@@ -122,10 +126,22 @@ _select(11, 20)
 - [20, 'the tuple 20']
 ...
 --# set connection replica
-_wait_lsn(23)
+_wait_lsn(12)
 ---
 ...
 _select(11, 20)
+---
+- [11, 'the tuple 11']
+- [12, 'the tuple 12']
+- [13, 'the tuple 13']
+- [14, 'the tuple 14']
+- [15, 'the tuple 15']
+- [16, 'the tuple 16']
+- [17, 'the tuple 17']
+- [18, 'the tuple 18']
+- [19, 'the tuple 19']
+- [20, 'the tuple 20']
+...
 --# stop server hot_standby
 --# stop server replica
 --# cleanup server hot_standby
diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua
index 388879c340c90a3be5a4c5309c9956da4651759a..61cf50258bdf70a402116d5c6846978acaad7a4f 100644
--- a/test/replication/hot_standby.test.lua
+++ b/test/replication/hot_standby.test.lua
@@ -2,8 +2,6 @@
 --# create server replica with configuration='replication/cfg/replica.cfg'
 --# start server hot_standby
 --# start server replica
-box.replace(box.schema.SPACE_ID, 0, 0, 'tweedledum')
-box.replace(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')
 
 --# setopt delimiter ';'
 --# set connection default, hot_standby, replica
@@ -21,18 +19,23 @@ function _select(_begin, _end)
     end
     return unpack(a)
 end;
-function _wait_lsn(_lsn)
-    while box.info.lsn < _lsn do
+begin_lsn = box.info.lsn;
+function _wait_lsn(_lsnd)
+    while box.info.lsn < _lsnd + begin_lsn do
         box.fiber.sleep(0.001)
     end
+    begin_lsn = begin_lsn + _lsnd
 end;
 --# setopt delimiter ''
 --# set connection default
+box.replace(box.schema.SPACE_ID, 0, 0, 'tweedledum')
+box.replace(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')
+
 _insert(1, 10)
 _select(1, 10)
 
 --# set connection replica
-_wait_lsn(13)
+_wait_lsn(12)
 _select(1, 10)
 
 --# stop server default
@@ -46,7 +49,7 @@ _insert(11, 20)
 _select(11, 20)
 
 --# set connection replica
-_wait_lsn(23)
+_wait_lsn(12)
 _select(11, 20)
 
 --# stop server hot_standby
diff --git a/test/test-run.py b/test/test-run.py
index b6f0961919573753d36824a3ff103420b39dadf5..f085dc32b4e1cf951c485bf7ad160f69bd1c9963 100755
--- a/test/test-run.py
+++ b/test/test-run.py
@@ -164,7 +164,7 @@ def main():
         path = '.'
     os.chdir(path)
 
-    failed_tests = 0
+    failed_tests = []
 
     try:
         print "Started", " ".join(sys.argv)
@@ -179,7 +179,7 @@ def main():
         suites = [TestSuite(suite_name, options.args) for suite_name in sorted(suite_names)]
 
         for suite in suites:
-            failed_tests += suite.run_all()
+            failed_tests.extend(suite.run_all())
     except RuntimeError as e:
         print "\nFatal error: {0}. Execution aborted.".format(e)
         if options.args.gdb:
@@ -188,7 +188,12 @@ def main():
     finally:
         os.chdir(oldcwd)
 
-    return -failed_tests
+    if failed_tests and options.args.is_force:
+        print '\n===== %d tests failed:' % len(failed_tests)
+        for test in failed_tests:
+            print "----- %s" % test
+
+    return (-1 if failed_tests else 0)
 
 if __name__ == "__main__":
   exit(main())