diff --git a/tests/test_shells/bash.ok b/tests/test_shells/bash.ok
new file mode 100644
index 00000000..0576d112
--- /dev/null
+++ b/tests/test_shells/bash.ok
@@ -0,0 +1,14 @@
+ zyx  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
+ zyx   BRANCH  ⋯  tests  shell  3rd  cd .git
+ zyx   BRANCH  ⋯  shell  3rd  .git  cd ..
+ zyx   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+ zyx  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV=
+ zyx   BRANCH  ⋯  tests  shell  3rd  bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
+[1] PID
+ zyx   BRANCH  ⋯  tests  shell  3rd  1  false
+ zyx   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s
+[1]+  Terminated              bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done"
+ zyx   BRANCH  ⋯  tests  shell  3rd  false
+ zyx   BRANCH  ⋯  tests  shell  3rd  1  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
+  HOSTNAME  zyx   BRANCH  ⋯  tests  shell  3rd  exit
+exit
diff --git a/tests/test_shells/input.sh b/tests/test_shells/input.sh
new file mode 100644
index 00000000..44e4de9a
--- /dev/null
+++ b/tests/test_shells/input.sh
@@ -0,0 +1,14 @@
+POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files"
+VIRTUAL_ENV=
+source powerline/bindings/bash/powerline.sh ; cd tests/shell/3rd
+POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
+cd .git
+cd ..
+VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+VIRTUAL_ENV=
+bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
+false
+kill `cat pid` ; sleep 1s
+false
+POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
+exit
diff --git a/tests/test_shells/screenrc b/tests/test_shells/screenrc
new file mode 100644
index 00000000..ad5a1466
--- /dev/null
+++ b/tests/test_shells/screenrc
@@ -0,0 +1,3 @@
+width  1024
+height    1
+logfile "tests/shell/screen.log"
diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh
index 771ebca6..b08f6de7 100755
--- a/tests/test_shells/test.sh
+++ b/tests/test_shells/test.sh
@@ -11,55 +11,33 @@ else
 	}
 fi
 
-get_output() {
-	OUTPUT="`safe_echo "$INPUT" | LANG=C $@ 2>&1 | sed 's/ \+\x08\+//g' | tail -n +6`"
-	OUTPUT="`safe_echo "$OUTPUT" | sed -e s/$(cat tests/shell/3rd/pid)/PID/g -e 's/\x1b/\\\\e/g' | python -c 'import socket, sys; hostname=socket.gethostname(); exec ("""for line in sys.stdin:\n sys.stdout.write(line.replace(hostname, "HOSTNAME"))""")'`"
-	safe_echo "$OUTPUT"
+run_test() {
+	SESNAME="powerline-shell-test-$$"
+	screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" env LANG=C "$@"
+	screen -S "$SESNAME" -X readreg a tests/test_shells/input.sh
+	sleep 5s
+	screen -S "$SESNAME" -p 0 -X width 300 1
+	screen -S "$SESNAME" -p 0 -X logfile tests/shell/screen.log
+	screen -S "$SESNAME" -p 0 -X paste a
+	while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do
+		sleep 1s
+	done
+	sed -i -e "1,3 d" \
+	       -e s/$(cat tests/shell/3rd/pid)/PID/g \
+	       -e "s/$(python -c 'import re, socket; print (re.escape(socket.gethostname()))')/HOSTNAME/g" \
+	       tests/shell/screen.log
+	if ! diff -u tests/test_shells/${1}.ok tests/shell/screen.log ; then
+		return 1
+	fi
+	return 0
 }
 
 mkdir tests/shell
 git init tests/shell/3rd
 git --git-dir=tests/shell/3rd/.git checkout -b BRANCH
 
-INPUT='
-POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files"
-VIRTUAL_ENV=
-COLUMNS=80
-source powerline/bindings/bash/powerline.sh ; cd tests/shell/3rd
-POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
-cd .git
-cd ..
-VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
-VIRTUAL_ENV=
-bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
-false
-kill `cat pid` ; sleep 1s
-false
-POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
-exit
-'
-
-BASH_OUTPUT="`get_output bash --noprofile -i`"
-
-EXPECTED_BASH_OUTPUT='\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mPOWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mcd .git
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240m3rd \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m.git \e[0;38;5;240;49;22m \e[0mcd ..
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mVIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;74;22m \e[0;38;5;231;48;5;74mⓔ  some-virtual-environment \e[0;38;5;74;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mVIRTUAL_ENV=
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mbash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
-[1] PID
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;48;5;166;22m \e[0;38;5;220;48;5;166m1 \e[0;38;5;166;49;22m \e[0mfalse
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;48;5;166;22m \e[0;38;5;220;48;5;166m1 \e[0;38;5;166;48;5;52;22m \e[0;38;5;231;48;5;52m1 \e[0;38;5;52;49;22m \e[0mkill `cat pid` ; sleep 1s
-[1]+  Terminated              bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done"
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mfalse
-\e[0;38;5;231;48;5;31;1m zyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;48;5;52;22m \e[0;38;5;231;48;5;52m1 \e[0;38;5;52;49;22m \e[0mPOWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
-\e[0;38;5;220;48;5;166m  HOSTNAME \e[0;38;5;166;48;5;31;22m \e[0;38;5;231;48;5;31;1mzyx \e[0;38;5;31;48;5;236;22m \e[0;38;5;250;48;5;236m BRANCH \e[0;38;5;236;48;5;240;22m \e[0;38;5;250;48;5;240m⋯ \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mtests \e[0;38;5;245;48;5;240;22m \e[0;38;5;250;48;5;240mshell \e[0;38;5;245;48;5;240;22m \e[0;38;5;252;48;5;240;1m3rd \e[0;38;5;240;49;22m \e[0mexit
-exit'
-if [ "b$EXPECTED_BASH_OUTPUT" != "b$BASH_OUTPUT" ] ; then
-	safe_echo "$EXPECTED_BASH_OUTPUT" > tests/shell/expected
-	safe_echo "$BASH_OUTPUT" > tests/shell/actual
-	diff -u tests/shell/expected tests/shell/actual
-	rm tests/shell/expected tests/shell/actual
+if ! run_test bash --norc --noprofile -i ; then
+	echo "Failed bash"
 	FAILED=1
 fi
 rm -r tests/shell