Обоснование того, почему вы должны помещать модульные тесты в отдельные сборки, состоит в том, чтобы предотвратить смешивание тестового кода с рабочим кодом. Сборки обеспечивают четкое разделение проблем и делают его достаточно гибким, чтобы вы могли удалить тесты, когда они не нужны. Например. когда вы отпускаете, конечный пользователь не заинтересован в загрузке всего тестового кода, когда он / она хочет использовать только конечный результат.
Относительно наличия множества тестовых сборок (по одной на каждую сборку "фактического кода") является вменяемой идеей. Добавление ссылок между тестовыми сборками не так сложно, и на самом деле помогает избежать слишком частого перепутывания кода, поскольку вам не нужно много ссылок (т.е. зависимостей) между сборками.
Также не пытайтесь использовать слишком много общей логики для модульных тестов, потому что для этого нужны модульные тесты / макеты / DI! Наличие большого количества пользовательских фабрик в тестовом коде является хорошим показателем того, что вы сделали производственный код слишком сложным, чем он должен быть.