Há muitas razões. Eric Lippert afirmou muitas vezes que o motivo feature X
não está no C # é porque não está no orçamento. Os designers de idiomas não têm uma quantidade infinita de tempo nem dinheiro para implementar as coisas, e cada novo recurso tem custos de manutenção associados. Manter o idioma o mais pequeno possível não é apenas mais fácil para os designers de idiomas - também é mais fácil para quem escreve implementações e ferramentas alternativas (por exemplo, IDEs). Além disso, quando algo é implementado em termos do idioma, e não em parte, você obtém portabilidade gratuitamente. Se o teste de unidade estiver sendo implementado como uma biblioteca, você precisará escrevê-lo apenas uma vez e ele funcionará em qualquer implementação em conformidade da linguagem.
Vale a pena notar que D tem suporte no nível de sintaxe para testes de unidade . Não sei por que eles decidiram incluir isso, mas vale a pena notar que D deve ser uma "linguagem de programação de sistemas de alto nível". Os designers queriam que fosse viável para o tipo de código inseguro e de baixo nível C ++ tradicionalmente usado, e um erro no código inseguro é incrivelmente caro - comportamento indefinido. Então, suponho que fazia sentido para eles dedicar um esforço extra a qualquer coisa que o ajudasse a verificar se algum código não seguro funciona. Por exemplo, você pode impor que apenas determinados módulos confiáveis possam executar operações inseguras, como acessos não verificados à matriz ou aritmética de ponteiros.
O desenvolvimento rápido também era uma prioridade para eles, tanto que eles criaram um objetivo de design que o código D compila com rapidez suficiente para torná-lo utilizável como uma linguagem de script. Testes de unidade de cozimento diretamente no idioma, para que você possa executar seus testes, basta passar um sinalizador extra para o compilador.
No entanto, acho que uma ótima biblioteca de testes de unidade faz muito mais do que apenas encontrar alguns métodos e executá-los. Veja o QuickCheck de Haskell, por exemplo, que permite testar coisas como "para todos os x e y f (x, y) == f (y, x)
". O QuickCheck é melhor descrito como um gerador de teste de unidade e permite que você teste as coisas em um nível mais alto do que "para esta entrada, estou esperando esta saída". QuickCheck e Linq não são tão diferentes - ambos são idiomas específicos de domínio. Portanto, em vez de usar o suporte ao teste de unidade em um idioma, por que não adicionar os recursos necessários para tornar as DSLs práticas? Você acabará não apenas com testes de unidade, mas com um idioma melhor como resultado.