Чюваки, скажите, тут есть кто-нибудь, кто рьяно TDDирует по вечерам? У меня тут терзания какие-то есть, простыня инсаде.

Tagged with →  

6 Responses to Чюваки, скажите, тут есть кто-нибудь, кто рьяно TDDирует по вечерам?

  1. 01pSpb:

    Вот смотрите, я пишу, например на пхп. Или питоне. Ну или вообще — на руби. Не суть важно.
    И так как я весь такой прввильный, приложение пишу серьезное и голову себе не хочу ебать в дальнейшем, я пишу тесты (юнит). Вот ситуация такая:
    есть у меня функция (или метод класса, всё равно). На вход она принимает три параметра. Я как разработчик предполагаю, что первым параметром ко мне придет инстанс класса подключения к бд (причем, коннект уже инициализирован), вторым — массив ИДшников юзеров из бд, которые не забанены и третьим какой-то айдишник какой-то сущности (например, у меня в проекте есть медальки, которые я раздаю, ну, например, самым активным пользователям сайта). А возвращает метод массив результатов апдейта каждой записи в базе.
    Чтобы у меня не болела голова я должен в тесте проверить следующие вещи:

    1) Класс объекта в первом параметре (в пхп тут немного проще — хоть какой-то тайп-хинтинг есть)
    2) Коннект (скорее всего какой-то флаг внутри класса) установлен
    3) Второй параметр — массив
    4) Каждый член этого массива — инт
    5) Каждому инту соответствует запись в таблице users, причем, поле is_banned должно быть false
    6) Третий параметр — массив
    7) Каждый член этого массива — реальный ИДшник из таблицы medals

    Это мы проверяем только входные параметры. Выходные:
    1) Результат — массив
    2) Ключ вложенного массива в результат — ИДшник юзера, значение — true/false
    3) Проверить, действительно ли у каждого юзера появилась запись в таблице-связке с нужным ИДшником медали

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

    Короче, я к чему. Я пойду ебну грамм 150, а то устал на работе, а вы поделитесь своими соображениями на тему автоматического тестирования кода, позязя, а то я расстроенный какой-то — не люблю делать ненужныю работу, которая может быть неэффективной.

  2. Okain:

    А если засылать по 1 неправильному параметру в тесте?
    Первый тест проверяет неправильность первого параметра, второй — второго и т.д.

  3. 01pSpb:

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

  4. AsaEkb:

    1) Для комбинаторной сложности есть генераторы. PHPUnit — http://www.phpunit.de/manual/3.6/en/writ… Можно и руками, если ты можешь нормально поймать сообщение об ошибке (через исключение, например) https://github.com/limb-php-framework/li

    2) Проверять типы вообще не обязательно. Если ты покрываешь тестом все ветки метода, то запихнуть вместо объекта число не получится. Хотя можно, конечно, нарваться на совпадающие методы двух разных объектов. У себя я проверку типов не тестирую, но проверки расставляю, чтобы потом легко по стектрейсу находить виноватого.

    3) У тебя ни слова про логику. Ты по сути тестируешь правильность фикстуры.

    4) 5 и 7 ложаться на SQL
    3)

    >В языках со строгой типизацей половину из этого списка можно нахуй выкинуть. То есть, по сути, тесты прикрывают жопы разработчиков, которые пишут на говенных языках?!

  5. AsaEkb:

    Пятница-пятница. Продолжаю:

    4) 5 и 7 не ложатся на SQL, я передумал.

    Имеем:
    — три теста на типы(позитивная/негативная проверка в каждом)
    — тест на правильные id’шники пользователей
    — тест на заблокированность
    — тест на правильный id медальки
    — …

    Короче, ты много всего запихнул в этот метод. Собственно поэтому и тестов много. Незаблокированных пользователей по id я бы сделал в отдельной фабрике или фабричном методе. UsersFactory::getNonBlockedById(int id|array id). Медальку тоже. В итоге, в других методах тебе не придется загрузку проверять.

  6. AmtEkb:

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

    Ошибки можно сокращать не только бесконечными тестами, но и невозможностью их совершить, благодаря архитектуре и продуманно разнесённой по методам логике работы.

Добавить комментарий