Есть много разных автоматизированных тестов.
Юнит-тесты пишет разработчик (в идеале — тот же самый, который пишет код, покрытый этими тестами, и ДО написания кода). Юнит-тесты помогают удостовериться, что каждый отдельный кусок (поэтому — unit) в программе по отдельности работает корректно. Имея на руках рабочие юнит-тесты, можно спокойно делать рефакторинг.
Интеграционные тесты помогают удостовериться, что и в совокупности все эти куски выдают осмысленные результаты. Из этих тестов становится понятно, что на сайт можно залогиниться, а софтина пишет в файл в корректном формате. Их тоже часто пишут программисты.
Приемочные тесты помогают удостовериться, что программа соответстует требованиям, заложенным в ТЗ/диздок.
Регрессионные тесты — что после последнего обновления ничего не сломалось. Эти два последних делают тестеры, с помощью различных тулзов — для веба, например, это Selenium.
Все эти тесты, в идеале, запускаются на каждый коммит на специальном Continuos Integration сервере, и если программист «опять накодил в углу», ему приходит письмо, что его код не прошел такой-то тест и это надо починить.