reaper, относительно assert'ов, это сложный вопрос. Они пришли из компилируемых языков, таких как С, где они удалялись из программы после компиляции.
В некоторых моих проектах я использовал концепцию защищенного программирования. Согласно ей, надо проверять все входные и выходные данные метода. То есть надо проверять все аргументы методов и функций внутри функции. Я делал это и выбрасывал исключения InvalidArgumantException. В этих же проектах я все тщательно тестировал и иногда сталкивался с ситуацией, когда тест не срабатывал из за выброса этих InvalidArgumentException. Благодаря им, я мог быстро локализовать ошибку (неверные входные данные), что нельзя было сделать с помощью тестов. С другой стороны использовать проверку аргументов и выбрасывать InvalidArgumentException довольно накладное решение на продакшене, гораздо эффективнее было бы использовать assert'ы для этих целей, которые так же помогут быстро локализовать ошибку (в том числе в тестах), а на продакшене их можно легко отключить, дабы не перегружать проект.
Другими словами тесты это хорошо, но с их помощью не всегда легко локализовать ошибку. Не стоит бояться того, что код у вас будет "не красивым", assert'ы прекрасно комментируют код:
function log($type, $message){
assert('array_search($type, ["notice", "warning", "error"]) !== false)');
assert('is_string($message) && !empty($message)');
...
}В примере сразу становится видно, что:
* $type должен быть строкой notice, warning или error
* $message не должна быть пустой
И не нужны никакие коментарии