diff --git a/test/box/xlog.result b/test/box/xlog.result
index 703e40f21b090c55220cdc5b214c229f27360a4d..ee29f761090a5aeddd3063cae4325018691efb8f 100644
--- a/test/box/xlog.result
+++ b/test/box/xlog.result
@@ -17,7 +17,6 @@ box.space[0]:insert(3, 'third tuple')
 - [3, 'third tuple']
 ...
 00000000000000000004.xlog.inprogress exists
-Stopping the server...
 00000000000000000004.xlog.inprogress has been successfully renamed
 
 # An inprogress xlog file with one record must be renamed during recovery.
diff --git a/test/box/xlog.test.py b/test/box/xlog.test.py
index df308636d58d64439570652dc232ca408ad689f0..09e0857698e178217f864b26d13991055e0b6fa4 100644
--- a/test/box/xlog.test.py
+++ b/test/box/xlog.test.py
@@ -1,9 +1,8 @@
-# encoding: utf-8
-#
 import os
-from os.path import abspath
 import shutil
 
+from os.path import abspath
+
 # cleanup vardir
 server.stop()
 server.deploy()
@@ -40,7 +39,7 @@ admin("box.space[0]:insert(3, 'third tuple')")
 if os.access(wal_inprogress, os.F_OK):
   print "00000000000000000004.xlog.inprogress exists"
 
-server.stop(silent=False)
+server.stop()
 
 if os.access(wal, os.F_OK) and not os.access(wal_inprogress, os.F_OK):
   print "00000000000000000004.xlog.inprogress has been successfully renamed"
diff --git a/test/lib/colorer.py b/test/lib/colorer.py
index f6059db015ca624b29970529f2fd3575eb065db3..642199eb43f0c1abfaa60577fa25b34223f6f6c5 100644
--- a/test/lib/colorer.py
+++ b/test/lib/colorer.py
@@ -1,53 +1,111 @@
+import os
+import sys
+
+class Singleton(type):
+    _instances = {}
+    def __call__(cls, *args, **kwargs):
+        if cls not in cls._instances:
+            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
+        return cls._instances[cls]
+
 class Colorer(object):
     """
-    Colorer/Styler for VT102+ (Not full). Based on:
+    Colorer/Styler based on VT220+ specifications (Not full). Based on:
     1. ftp://ftp.cs.utk.edu/pub/shuford/terminal/dec_vt220_codes.txt
     2. http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
     """
-    color = {
-        "black"   : 0,
-        "red"     : 1,
-        "green"   : 2,
-        "yellow"  : 3,
-        "blue"    : 4,
-        "magenta" : 5,
-        "cyan"    : 6,
-        "white"   : 7
+    __metaclass__ = Singleton
+    fgcolor = {
+        "black"    : '0;30',
+        "red"      : '0;31',
+        "green"    : '0;32',
+        "brown"    : '0;33',
+        "blue"     : '0;34',
+        "magenta"  : '0;35',
+        "cyan"     : '0;36',
+        "grey"     : '0;37',
+        "lgrey"    : '1;30',
+        "lred"     : '1;31',
+        "lgreen"   : '1;32',
+        "yellow"   : '1;33',
+        "lblue"    : '1;34',
+        "lmagenta" : '1;35',
+        "lcyan"    : '1;36',
+        "white"    : '1;37',
+        }
+    bgcolor = {
+        "black"    : '0;40',
+        "red"      : '0;41',
+        "green"    : '0;42',
+        "brown"    : '0;43',
+        "blue"     : '0;44',
+        "magenta"  : '0;45',
+        "cyan"     : '0;46',
+        "grey"     : '0;47',
+        "lgrey"    : '1;40',
+        "lred"     : '1;41',
+        "lgreen"   : '1;42',
+        "yellow"   : '1;43',
+        "lblue"    : '1;44',
+        "lmagenta" : '1;45',
+        "lcyan"    : '1;46',
+        "white"    : '1;47',
     }
-    foreground = 30
-    background = 40
     attributes = {
-        "off"   : 0,
+        "bold"      : '1',
+        "underline" : '4',
+        "blinking"  : '5',
+        "negative"  : '7',
+        "invisible" : '8',
+    }
+    begin = "\033["
+    end = "m"
+    disable = begin+'0'+end
 
-        "bold"  : 1,
-        "booff" : 22,
+    def __init__(self):
+        self.stdout = sys.stdout
+        self.is_term = self.stdout.isatty()
+        self.colors = int(os.popen('tput colors').read()) if self.is_term else None
 
-        "underline" : 4,
-        "unoff" : 24,
+    def set_stdout(self):
+        sys.stdout = self
 
-        "blinking" : 5,
-        "bloff" : 25,
+    def ret_stdout(self):
+        sys.stdout = self.stdout
 
-        "negative" : 7,
-        "neoff" : 27,
+    def write(self, *args, **kwargs):
+        flags = []
+        for i in self.attributes:
+            if i in kwargs and kwargs[i] == True:
+                flags.append(self.attributes[i])
+        flags.append(self.fgcolor[kwargs['fgcolor']]) if 'fgcolor' in kwargs else None
+        flags.append(self.bgcolor[kwargs['bgcolor']]) if 'bgcolor' in kwargs else None
 
-        "invisible": 8
-        "inoff" : 28,
-    }
-    disable = "\033[0m"
-    def __init__(self):
-        self.stdout = sys.stdout
-        self.is_term = self.stdout.isatty()
+        if self.is_term:
+            self.stdout.write(self.begin+';'.join(flags)+self.end)
+        for i in args:
+            self.stdout.write(str(i))
+        if self.is_term:
+            self.stdout.write(self.disable)
+        self.stdout.flush()
+
+    def __call__(self, *args, **kwargs):
+        self.write(*args, **kwargs)
+
+    def writeout_unidiff(self, diff):
+        for i in diff:
+            if i.startswith('+'):
+                self.write(i, fgcolor='blue')
+            elif i.startswith('-'):
+                self.write(i, fgcolor='red')
+            elif i.startswith('@'):
+                self.write(i, fgcolor='magenta')
+
+    def flush(self):
+        return self.stdout.flush()
+
+    def fileno(self):
+        return self.stdout.fileno()
 
-    def write(self, *args **kwargs):
-        a.push()
-        fgcolor = kwargs['fgcolor'] if 'fgcolor' in kwargs else None
-        a.push(str(self.color[kwargs['fgcolor']]+self.foreground))
-        bgcolor = kwargs['bgcolor'] if 'bgcolor' in kwargs else None
-        bold = kwargs['bold'] if 'bold' in kwargs else False
-        uline = kwargs['underline'] if 'underline' in kwargs else False
-        blink = kwargs['blinking'] if 'blinking' in kwargs else False
-        neg = kwargs['negative'] if 'negative' in kwargs else False
-        inv = kwargs['invisible'] if 'invisible' in kwargs else False
-
-        self.stdout.write()
+    def isatty(self):
+        return self.is_term
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index 033cf342f102c28babca1107c3bb86c1dd9fec2b..575f4a0bf014f57b816f72ae39221ba8f1fa0787 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -21,7 +21,7 @@ from lib.test_suite import FilteredStream, Test, check_libs
 from lib.admin_connection import AdminConnection
 
 from lib.preprocessor import State
-
+from lib.colorer import Colorer
 try:
     import cStringIO as StringIO
 except ImportError:
@@ -29,6 +29,7 @@ except ImportError:
 
 check_libs()
 import tarantool
+color_stdout = Colorer()
 
 def check_port(port):
     """Check if the port we're connecting to is available"""
@@ -165,7 +166,8 @@ class TarantoolServer(Server):
         builddir = os.path.join(builddir, "src/box")
         path = builddir + os.pathsep + os.environ["PATH"]
         if not silent:
-            print "Looking for server binary in {0} ...".format(path)
+            color_stdout("Looking for server binary in ", fgcolor='lmagenta')
+            color_stdout(path+" ...\n", fgcolor='green')
         for _dir in path.split(os.pathsep):
             exe = os.path.join(_dir, self.default_bin_name)
             if os.access(exe, os.X_OK):
@@ -185,13 +187,15 @@ class TarantoolServer(Server):
         self.valgrind_log = os.path.abspath(os.path.join(self.vardir, self.valgrind_log))
 
         if not silent:
-            print "Installing the server..."
-            print "  Found executable at " + self.binary
-            print "  Creating and populating working directory in " + self.vardir + "..."
+            color_stdout("Installing the server ...\n", fgcolor='lmagenta')
+            color_stdout("    Found executable at ", fgcolor='lmagenta')
+            color_stdout(self.binary+'\n', fgcolor='green', bold=True)
+            color_stdout("    Creating and populating working directory in ", fgcolor='lmagenta')
+            color_stdout(self.vardir+' ...\n', fgcolor='green', bold=True)
 
         if os.access(self.vardir, os.F_OK):
             if not silent:
-                print "  Found old vardir, deleting..."
+                color_stdout("    Found old vardir, deleting ...\n", fgcolor='lmagenta')
             self.kill_old_server()
             self.cleanup()
         else:
@@ -302,21 +306,23 @@ class TarantoolServer(Server):
 
         if self.is_started:
             if not silent:
-                print "The server is already started."
+                color_stdout("The server is already started.\n", fgcolor='lred')
             return
 
         if not silent:
-            print "Starting the server..."
+            color_stdout("Starting the server ...\n", fgcolor='lmagenta')
             version = self.version()
-            print "Starting {0} {1}.".format(os.path.basename(self.binary), version)
+            color_stdout("Starting ", fgcolor='lmagenta')
+            color_stdout(os.path.basename(self.binary), " \n", fgcolor='green')
+            color_stdout(version, "\n", fgcolor='grey')
 
         check_port(self.port)
         args = self.prepare_args()
 
         if self.gdb:
             args = prepare_gdb(self.binary, args)
-            print "You started the server in gdb mode."
-            print "To attach, use `screen -r tnt-gdb`"
+            color_stdout("You started the server in gdb mode.\n", fgcolor='yellow', bold=True)
+            color_stdout("To attach, use `screen -r tnt-gdb`\n", fgcolor='yellow', bold=True)
         elif self.valgrind:
             args = prepare_valgrind([self.binary] + args, self.valgrind_log,
                                     os.path.abspath(os.path.join(self.vardir,
@@ -342,11 +348,11 @@ class TarantoolServer(Server):
         start up."""
         if not self.is_started:
             if not silent:
-                print "The server is not started."
+                color_stdout("The server is not started.\n", fgcolor='red')
             return
 
         if not silent:
-            print "Stopping the server..."
+            color_stdout("Stopping the server ...\n", fgcolor='lmagenta')
 
         if self.process == None:
             self.kill_old_server()
@@ -424,7 +430,7 @@ class TarantoolServer(Server):
             return # Nothing to do
 
         if not silent:
-            print "  Found old server, pid {0}, killing...".format(pid)
+            color_stdout("    Found old server, pid {0}, killing ...".format(pid), fgcolor='yellow')
 
         try:
             os.kill(pid, signal.SIGTERM)
@@ -446,13 +452,11 @@ class TarantoolServer(Server):
             pass
         return pid
 
-    def print_log(self, lines, stdout=None):
-        if stdout is None:
-            stdout = sys.stdout
-        stdout.write("\nLast {0} lines of Tarantool Log file:\n".format(lines))
+    def print_log(self, lines):
+        color_stdout.write("\nLast {0} lines of Tarantool Log file:\n".format(lines), fgcolor='lred')
         with open(os.path.join(self.vardir, 'tarantool.log'), 'r') as log:
             for i in log.readlines()[-lines:]:
-                stdout.write(i)
+                color_stdout.write(i, fgcolor='grey')
 
     def wait_until_started(self):
         """Wait until the server is started and accepting connections"""
diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py
index 57678a72dbfe93294b6aafd5939af9bc4e1d7a08..cf507f604433008079f36d293947aca2a684f9db 100644
--- a/test/lib/test_suite.py
+++ b/test/lib/test_suite.py
@@ -11,7 +11,9 @@ import collections
 import ConfigParser
 
 from lib.server import Server
+from lib.colorer import Colorer
 
+color_stdout = Colorer()
 try:
     from cStringIO import StringIO
 except ImportError:
@@ -87,7 +89,7 @@ def print_tail_n(filename, num_lines):
     with open(filename, "r+") as logfile:
         tail_n = collections.deque(logfile, num_lines)
         for line in tail_n:
-            sys.stdout.write(line)
+            color_stdout.write(line, fgcolor='lblue')
 
 
 class Test:
@@ -172,20 +174,20 @@ class Test:
             check_valgrind_log(server.valgrind_log) == False
 
         elif self.skip:
-            print "[ SKIP ]"
+            color_stdout("[ SKIP ]\n", fgcolor='grey')
             if os.path.exists(self.tmp_result):
                 os.remove(self.tmp_result)
         elif self.is_executed_ok and self.is_equal_result and self.is_valgrind_clean:
-            print "[ PASS ]"
+            color_stdout("[ PASS ]\n", fgcolor='green')
             if os.path.exists(self.tmp_result):
                 os.remove(self.tmp_result)
         elif (self.is_executed_ok and not self.is_equal_result and not
               os.path.isfile(self.result)):
             os.rename(self.tmp_result, self.result)
-            print "[ NEW ]"
+            color_stdout("[ NEW ]\n", fgcolor='lblue')
         else:
             os.rename(self.tmp_result, self.reject)
-            print "[ FAIL ]" if not self.is_terminated else "[ TERMINATED ]"
+            color_stdout("[ FAIL ]\n" if not self.is_terminated else "[ TERMINATED ]\n", fgcolor='red')
 
             where = ""
             if not self.is_executed_ok:
@@ -208,7 +210,7 @@ class Test:
         """Print 10 lines of client program output leading to test
         failure. Used to diagnose a failure of the client program"""
 
-        print message
+        color_stdout(message, color='lred')
         print_tail_n(logfile, 10)
 
     def print_unidiff(self):
@@ -216,7 +218,7 @@ class Test:
         to establish the cause of a failure when .test differs
         from .result."""
 
-        print "Test failed! Result content mismatch:"
+        color_stdout("\nTest failed! Result content mismatch:\n", fgcolor='lred')
         with open(self.result, "r") as result:
             with open(self.reject, "r") as reject:
                 result_time = time.ctime(os.stat(self.result).st_mtime)
@@ -227,8 +229,8 @@ class Test:
                                             self.reject,
                                             result_time,
                                             reject_time)
-                for line in diff:
-                    sys.stdout.write(line)
+
+                color_stdout.writeout_unidiff(diff)
 
 class TestSuite:
     """Each test suite contains a number of related tests files,
@@ -280,10 +282,11 @@ class TestSuite:
             raise RuntimeError("Unknown server: core = {0}".format(
                                self.ini["core"]))
 
-        print "Collecting tests in \"" + suite_path + "\": " +\
-            self.ini["description"] + "."
+        color_stdout("Collecting tests in ", fgcolor='lmagenta')
+        color_stdout(repr(suite_path), fgcolor='green')
+        color_stdout(": ", self.ini["description"], ".\n", fgcolor='lmagenta')
         self.server.find_tests(self, suite_path)
-        print "Found " + str(len(self.tests)) + " tests."
+        color_stdout("Found ", str(len(self.tests)), " tests.\n", fgcolor='green')
 
     def run_all(self):
         """For each file in the test suite, run client program
@@ -307,45 +310,46 @@ class TestSuite:
             shutil.copy(i, self.args.vardir)
 
         if self.args.start_and_exit:
-            print "  Start and exit requested, exiting..."
+            color_stdout("    Start and exit requested, exiting...\n", fgcolor='yellow')
             exit(0)
 
         longsep = '='*70
         shortsep = '-'*60
-        print longsep
-        print "TEST".ljust(48), "RESULT"
-        print shortsep
+        color_stdout(longsep, "\n", fgcolor='blue')
+        color_stdout("TEST".ljust(48), fgcolor='lblue')
+        color_stdout("RESULT\n", fgcolor='green')
+        color_stdout(shortsep, "\n", fgcolor='blue')
         failed_tests = []
         try:
             for test in self.tests:
-                sys.stdout.write(test.name.ljust(48))
+                color_stdout(test.name.ljust(48), fgcolor='lblue')
                 # 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 ]"
+                    color_stdout("[ DISABLED ]\n", fgcolor='grey')
                 else:
                     test.run(self.server)
                     if not test.passed():
                         failed_tests.append(test.name)
         except (KeyboardInterrupt) as e:
-            print '\n',
+            color_stdout('\n')
             raise
         finally:
-            print shortsep
+            color_stdout(shortsep, "\n", fgcolor='blue')
             self.server.stop(silent=False)
             self.server.cleanup()
 
         if failed_tests:
-            print "Failed {0} tests: {1}.".format(len(failed_tests),
-                                                ", ".join(failed_tests))
+            color_stdout("Failed {0} tests: {1}.".format(len(failed_tests),
+                                                ", ".join(failed_tests)),
+                                                fgcolor='red')
 
         if self.args.valgrind and check_valgrind_log(self.server.valgrind_log):
-            print "  Error! There were warnings/errors in valgrind log file:"
+            color_stdout("  Error! There were warnings/errors in valgrind log file:", fgcolor='red')
             print_tail_n(self.server.valgrind_log, 20)
             return ['valgrind error in ' + self.suite_path]
         return failed_tests
diff --git a/test/test-run.py b/test/test-run.py
index f085dc32b4e1cf951c485bf7ad160f69bd1c9963..7b6a0d74905170474a1dd7f9d34ca122e8a4e670 100755
--- a/test/test-run.py
+++ b/test/test-run.py
@@ -32,8 +32,10 @@ import shutil
 import os.path
 import argparse
 
+from lib.colorer import Colorer
 from lib.test_suite import TestSuite
 
+color_stdout = Colorer()
 #
 # Run a collection of tests.
 #
@@ -130,7 +132,7 @@ class Options:
         """Check the arguments for correctness."""
         check_error = False
         if self.args.gdb and self.args.valgrind:
-            print "Error: option --gdb is not compatible with option --valgrind"
+            color_stdout("Error: option --gdb is not compatible with option --valgrind", fgcolor='red')
             check_error = True
         if check_error:
             exit(-1)
@@ -167,7 +169,7 @@ def main():
     failed_tests = []
 
     try:
-        print "Started", " ".join(sys.argv)
+        color_stdout("Started {}\n".format(" ".join(sys.argv)), fgcolor='green')
         suite_names = []
         if options.args.suites != []:
             suite_names = options.args.suites
@@ -181,7 +183,7 @@ def main():
         for suite in suites:
             failed_tests.extend(suite.run_all())
     except RuntimeError as e:
-        print "\nFatal error: {0}. Execution aborted.".format(e)
+        color_stdout("\nFatal error: {0}. Execution aborted.\n".format(e), fgcolor='red')
         if options.args.gdb:
             time.sleep(100)
         return (-1)
@@ -189,9 +191,9 @@ def main():
         os.chdir(oldcwd)
 
     if failed_tests and options.args.is_force:
-        print '\n===== %d tests failed:' % len(failed_tests)
+        color_stdout("\n===== {0} tests failed:".format(len(failed_tests))+"\n", fgcolor="red")
         for test in failed_tests:
-            print "----- %s" % test
+             color_stdout("----- "+test+"\n", fgcolor="yellow")
 
     return (-1 if failed_tests else 0)