Add soft timeouts

Implements #86 by adding a soft-timeout option. In contrast to the existing timeout option, a soft timeout is not asynchronous and therefore allows the test runner to intercept the timeout exception.