Não sei se esta será a resposta de todos, mas depois de algumas escavações, aqui está o que descobrimos.
O erro é obviamente causado pelo fato de que o ouvinte não estava aceitando conexões, mas por que obteríamos esse erro quando outros testes poderiam se conectar bem (também poderíamos conectar sem problemas através do sqlplus)? A chave para o problema não era que não pudéssemos nos conectar, mas que era intermitente
Após alguma investigação, descobrimos que havia alguns dados estáticos criados durante a configuração da classe que manteriam conexões abertas durante a vida da classe de teste, criando novas à medida que avançava. Agora, embora todos os recursos tenham sido liberados corretamente quando essa classe saiu do escopo (por meio de um bloco finally{}, é claro), houve alguns casos durante a execução em que essa classe engoliu todas as conexões disponíveis (ok, alerta de prática - este era o código de teste de unidade que se conectava diretamente em vez de usar um pool, portanto, o mesmo problema não poderia acontecer na produção).
A correção foi não tornar essa classe estática e executá-la na configuração da classe, mas usá-la nos métodos setUp e tearDown por método.
Então, se você receber esse erro em seus próprios aplicativos, dê um tapa em um criador de perfil naquele bad boy e veja se você pode ter um vazamento de conexão. Espero que ajude.