Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision ea6226569c27a942134dad8c4fb127053ee0c553)
+++ tests/Makefile.am	(revision f806b61240fa8f82c3add1d6bac8a1176b4d9868)
@@ -36,5 +36,5 @@
 	-Wno-unused-function \
 	-quiet @CFA_FLAGS@ \
-	-DIN_DIR="${srcdir}/.in/"
+	-DIN_DIR="${abs_srcdir}/.in/"
 
 AM_CFLAGS += ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
Index: tests/Makefile.in
===================================================================
--- tests/Makefile.in	(revision ea6226569c27a942134dad8c4fb127053ee0c553)
+++ tests/Makefile.in	(revision f806b61240fa8f82c3add1d6bac8a1176b4d9868)
@@ -382,6 +382,6 @@
 # applies to both programs
 AM_CFLAGS = $(if $(test), 2> $(test), ) -g -Wall -Wno-unused-function \
-	-quiet @CFA_FLAGS@ -DIN_DIR="${srcdir}/.in/" ${DEBUG_FLAGS} \
-	${INSTALL_FLAGS} ${ARCH_FLAGS}
+	-quiet @CFA_FLAGS@ -DIN_DIR="${abs_srcdir}/.in/" \
+	${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
 PRETTY_PATH = cd ${srcdir} &&
 avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa
Index: tests/pybin/tools.py
===================================================================
--- tests/pybin/tools.py	(revision ea6226569c27a942134dad8c4fb127053ee0c553)
+++ tests/pybin/tools.py	(revision f806b61240fa8f82c3add1d6bac8a1176b4d9868)
@@ -11,9 +11,9 @@
 import subprocess
 import sys
+import tempfile
 import time
 import types
 
 from pybin import settings
-from subprocess import Popen, PIPE, STDOUT
 
 ################################################################################
@@ -27,14 +27,14 @@
 	# if this is a dry_run, only print the commands that would be ran
 	if settings.dry_run :
-		cmd = "cmd: {}".format(' '.join(cmd))
-		if output and output != subprocess.DEVNULL and output != subprocess.PIPE:
+		cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd))
+		if output and not isinstance(output, int):
 			cmd += " > "
 			cmd += output
 
-		if error and error != subprocess.DEVNULL and error != subprocess.PIPE and error != subprocess.STDOUT:
+		if error and not isinstance(error, int):
 			cmd += " 2> "
 			cmd += error
 
-		if input and input != subprocess.DEVNULL and os.path.isfile(input):
+		if input and not isinstance(input, int) and os.path.isfile(input):
 			cmd += " < "
 			cmd += input
@@ -45,15 +45,11 @@
 	with contextlib.ExitStack() as onexit:
 		# add input redirection if needed
-		if input and input != subprocess.DEVNULL:
-			if os.path.isfile(input):
-				input = open(input)
-				onexit.push(input)
-			else:
-				input = None
+		input = openfd(input, 'r', onexit, True)
 
 		# add output redirection if needed
-		if output and output != subprocess.DEVNULL and output != subprocess.PIPE:
-			output = open(output, 'w')
-			onexit.push(output)
+		output = openfd(output, 'w', onexit, False)
+
+		# add error redirection if needed
+		error = openfd(error, 'w', onexit, False)
 
 		# run the desired command
@@ -63,5 +59,5 @@
 				stdin =input,
 				stdout=output,
-				stderr=STDOUT,
+				stderr=error,
 				timeout=settings.timeout.single if timeout else None
 			)
@@ -91,4 +87,18 @@
 def is_exe(fname):
 	return os.path.isfile(fname) and os.access(fname, os.X_OK)
+
+def openfd(file, mode, exitstack, checkfile):
+	if not file:
+		return file
+
+	if isinstance(file, int):
+		return file
+
+	if checkfile and not os.path.isfile(file):
+		return None
+
+	file = open(file, mode)
+	exitstack.push(file)
+	return file
 
 # Remove 1 or more files silently
@@ -159,4 +169,14 @@
     return None
 
+@contextlib.contextmanager
+def tempdir():
+	cwd = os.getcwd()
+	with tempfile.TemporaryDirectory() as temp:
+		os.chdir(temp)
+		try:
+			yield temp
+		finally:
+			os.chdir(cwd)
+
 ################################################################################
 #               file handling
@@ -259,12 +279,12 @@
 
 def core_info(path):
+	if not os.path.isfile(path):
+		return 1, "ERR Executable path is wrong"
+
 	cmd   = os.path.join(settings.SRCDIR, "pybin/print-core.gdb")
 	if not os.path.isfile(cmd):
 		return 1, "ERR Printing format for core dumps not found"
 
-	dname = os.path.dirname(path)
-	core  = os.path.join(dname, "core" )
-	if not os.path.isfile(path):
-		return 1, "ERR Executable path is wrong"
+	core  = os.path.join(os.getcwd(), "core" )
 
 	if not os.path.isfile(core):
Index: tests/test.py
===================================================================
--- tests/test.py	(revision ea6226569c27a942134dad8c4fb127053ee0c553)
+++ tests/test.py	(revision f806b61240fa8f82c3add1d6bac8a1176b4d9868)
@@ -8,4 +8,5 @@
 import re
 import sys
+import tempfile
 import time
 
@@ -143,36 +144,38 @@
 		make_ret, _ = make( test.target(), output=subprocess.DEVNULL, error=out_file, error_file = err_file )
 
-	# if the make command succeds continue otherwise skip to diff
 	run_dur = None
-	if success(make_ret):
-		with Timed() as run_dur:
-			if settings.dry_run or is_exe(exe_file):
-				# run test
-				retcode, _ = sh(exe_file, output=out_file, input=in_file, timeout=True)
+	# run everything in a temp directory to make sure core file are handled properly
+	with tempdir():
+		# if the make command succeds continue otherwise skip to diff
+		if success(make_ret):
+			with Timed() as run_dur:
+				if settings.dry_run or is_exe(exe_file):
+					# run test
+					retcode, _ = sh(exe_file, output=out_file, input=in_file, timeout=True)
+				else :
+					# simply cat the result into the output
+					retcode = cat(exe_file, out_file)
+		else:
+			retcode = mv(err_file, out_file)
+
+		if success(retcode):
+			if settings.generating :
+				# if we are ounly generating the output we still need to check that the test actually exists
+				if no_rule(out_file, test.target()) :
+					retcode = 1
+					error = "\t\tNo make target for test %s!" % test.target()
+					rm(out_file)
+				else:
+					error = None
 			else :
-				# simply cat the result into the output
-				retcode = cat(exe_file, out_file)
-	else:
-		retcode = mv(err_file, out_file)
-
-	if success(retcode):
-		if settings.generating :
-			# if we are ounly generating the output we still need to check that the test actually exists
-			if no_rule(out_file, test.target()) :
-				retcode = 1
-				error = "\t\tNo make target for test %s!" % test.target()
-				rm(out_file)
-			else:
-				error = None
-		else :
-			# fetch return code and error from the diff command
-			retcode, error = diff(cmp_file, out_file)
-
-	else:
-		with open (out_file, "r") as myfile:
-			error = myfile.read()
-
-		ret, info = core_info(exe_file)
-		error = error + info if error else info
+				# fetch return code and error from the diff command
+				retcode, error = diff(cmp_file, out_file)
+
+		else:
+			with open (out_file, "r") as myfile:
+				error = myfile.read()
+
+			ret, info = core_info(exe_file)
+			error = error + info if error else info
 
 
