Entonces, ¿las pruebas de afirmación única violan DRY?
No, pero promueve la violación.
Dicho esto, un buen diseño orientado a objetos tiende a salir por la ventana para las pruebas unitarias, principalmente por una buena razón. Es más importante que las pruebas unitarias se aíslen unas de otras para que la prueba se pueda interrogar de forma aislada y, si es necesario, se repare con la confianza de que no se rompen otras pruebas. Básicamente, la exactitud y legibilidad de la prueba es más importante que su tamaño o facilidad de mantenimiento.
Francamente, nunca he sido fanático de la única afirmación por regla de prueba por las razones que usted describe: conduce a una gran cantidad de código repetitivo que es difícil de leer, fácil de errar y difícil de corregir si refactoriza (lo que te lleva a refactorizar menos).
Si se supone que una función devuelve una lista de "foo" y "bar" para una entrada dada, pero en cualquier orden, está perfectamente bien usar dos afirmaciones para verificar que ambos están en el conjunto de resultados. Cuando se mete en problemas es cuando una sola prueba está comprobando dos entradas o dos efectos secundarios y no sabe cuál de los dos causó la falla.
Lo veo como una variación del Principio de responsabilidad única: debe haber una sola cosa que puede hacer que una prueba falle, y en un mundo ideal ese cambio solo debe romper una prueba.
Pero al final es una compensación. ¿Es más probable que pase más tiempo manteniendo todo el código de copia pegado, o pasará más tiempo buscando las causas raíz cuando múltiples fuentes pueden romper las pruebas? Mientras escribas -algunas- pruebas, probablemente no importe demasiado. A pesar de mi desdén por las pruebas de una sola afirmación, tiendo a equivocarme con más pruebas. Su experiencia puede ser diferente.