Как научиться писать юнит-тесты, в которых будет смысл и не ошалеть от скуки?
Знакомая проблема. Хорошо писать тесты для простой функциональности. Но что делать, когда нужно тестировать не просто отдельные функции, а ещё и их комбинации? Что делать, когда количество комбинаций входных данных — огромно, или вообще бесконечно, и каждая комбинация может привести к ошибке?

Для себя нашёл частичный выход: пишу высокоуровневые тесты, а низкоуровневые заменяю множеством assert-ов. Assert проще написать, поскольку не надо воспроизводить контекст ни программно, ни мысленно — assert всегда выполняется в нужном контексте. И при запуске высокоуровнего теста фактически выполняется гораздо больше проверок, чем написано в самом тесте. Assert-ты также очень помогают в отладке — с их помощью быстрее локализуются ошибки.

Кстати, для библиотечных проектов совершенно необходимо писать и проекты, эти библиотеки использующие. Иначе — библиотека получается гарантированно ненужной. Так вот, само такое приложение и тесты к нему являются одновременно и тестами библиотеки.
Так как вопрос в общем, то в общем уменьшение использования состояний уменьшает сложность тестирования. Например, при использовании функцонального стиля.