Конкурс модульного тестирования

12

Мои работодатели проводят ежемесячные соревнования по дневному тестированию. Целый день посвящен написанию юнит-тестов - очевидно, что мы проводим больше тестов в течение месяца, но это целый день - и «победитель» конкурса получает приз. Однако мы находим, что трудно определить, кто победитель.

Мы назначали очки для каждого теста. Так что, если вы написали модульный тест, как это ...

for (int i = 0; i < 100; i++) {
  assertTrue(i*i, square(i));
}

вам бы дали 100 баллов. Очевидно, это упрощенный пример, но он демонстрирует проблемы с назначением «точек» для каждого теста.

Мы в первую очередь магазин Java и Javascript. Поэтому я предложил подсчитать количество проверенных ветвей кода в качестве метрики. Мы можем легко подсчитать количество ветвей, протестированных с помощью инструмента покрытия кода (например, EclEmma). Однако, не уверен, как мы будем делать это с нашими тестами Selenium и получением покрытия кода из источников Javascript (есть идеи?)

Есть ли у кого-нибудь предложения о том, как мы могли бы лучше определить победителя этого конкурса?

редактировать

Я знаю, как писать модульные тесты, я знаю, как писать эффективные модульные тесты, мне не нужна помощь в определении того, что тестировать. Я не имею никакого контроля над этим соревнованием - соревнование продолжится. Так что я либо добавляю какой-то вклад, чтобы сделать его лучше, либо продолжаю играть в тесты (да, я играю в них. Конечно, я играю в них. Есть призы, которые можно выиграть)

редактировать

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

Shaun
источник
Не совсем. Я понял это с самого начала
Shaun
2
Вы, кажется, еще не полностью осознали всю степень. Любая мера того, кто написал лучшие тестовые случаи, будет либо полностью субъективной, либо в некоторой степени иметь эти проблемы. То, какой показатель лучше всего работает, будет зависеть от ваших целей на этих соревнованиях и от того, насколько зрелыми (то есть, вряд ли они будут использовать результат, а не будут писать лучшие тесты, какие только могут), участники будут.
Опять нет. Я понял, что они могут быть разыграны. У меня нет контроля над этим соревнованием, но меня спросили, «как мы можем сделать это лучше»
Shaun
13
Будет ли считаться улучшением, чтобы не сделать его конкурентом? Почему все должно быть соревнованием? Почему ты не можешь сотрудничать? Возможно, было бы полезно избавиться от ваших более бессмысленных модульных тестов и создать хороший набор полезных тестов на дым и регрессию.
Томас Оуэнс
1
Я с Томасом ... победителем должна стать база кода / клиент, потому что качество кода улучшилось. Установите общую / групповую цель на основе покрытия кода модульных тестов ... + 5% по сравнению с текущим или любым другим. ... и не разыгрывайте систему призов ... что случилось с хорошо выполненной работой, это ее собственная награда?
Джефф

Ответы:

15

Есть ли у кого-нибудь предложения о том, как мы могли бы лучше определить победителя этого конкурса?

Единственное, что имеет для меня смысл, - это голосование - каждый разработчик может назначить несколько баллов каждому тесту другого разработчика (кроме своего). Может быть, 3 балла за тест, который он считает «самым эффективным», 2 балла за второй и один за третий. Тест с наибольшим количеством очков выигрывает. Это может дать лучшие результаты, когда распределение баллов выполнено, не зная заранее, кто написал конкретный тест.

В качестве бонуса вы будете проверять все ваши тесты.

Док Браун
источник
2
Это была моя мысль тоже. Нет другого способа измерить ценность тестов.
Эрик Кинг,
2
Да, «хорошее тестирование» - это такая субъективная вещь, которую нужно оценивать как коллегами, так и авторитетными авторитетами. Погоня за метриками просто приведет к большим потерям усилий и небольшой реальной стоимости. Может быть интересно иметь несколько призов: самый творческий тест, награда «тестирование чего-то, что ранее считалось непроверенным», лучший тест производительности, самый эффективный тест, самый непонятный тест, самый умный тест, самый ценный тест, тест, который, скорее всего, оценят конечные пользователи ...
Timday
6

Так что, если вы написали модульный тест, как это ...

for (int i = 0; i < 100; i++) {
 assertTrue(i*i, square(i));
}

вам бы дали 100 баллов.

Я бы дал этому человеку 0 баллов (даже если бы тест проверял что-то действительно релевантное), потому что утверждения внутри цикла не имеют смысла, а тесты с несколькими утверждениями (особенно в форме цикла или карты) трудны для работы.

По сути, проблема заключается в том, чтобы иметь метрику, которую нельзя [легко] обмануть. Метрика, основанная исключительно на количестве утверждений, в точности соответствует плате разработчиков за LOC. Как и в случае с pay-by-LOC, что приводит к огромному и невозможному сопровождению кода, политика вашей компании ведет к бесполезным и, возможно, плохо написанным тестам.

Если количество подтверждений не имеет значения, число проверок также не имеет значения. Это также относится ко многим метрикам (включая комбинированные), которые можно себе представить для подобных ситуаций.

В идеале вы должны применять системный подход. На практике это вряд ли может работать в большинстве компаний по разработке программного обеспечения. Поэтому я могу предложить несколько других вещей:

  1. Использование парных обзоров для тестов и что-то похожее на количество WTF в минуту .

  2. Измерьте влияние этих тестов с течением времени на количество ошибок . Это имеет несколько преимуществ:

    • Кажется справедливым,
    • Фактически может быть измерено, если вы соберете достаточно данных о сообщениях об ошибках и их судьбе,
    • На самом деле стоит того!
  3. Используйте покрытие филиала , но объедините его с другими показателями (а также с обзором). Покрытие филиала имеет свои преимущества, но тестирование кода CRUD просто для того, чтобы получить лучшую оценку, не лучший способ потратить время разработчиков.

  4. Решите все вместе, какие показатели вы хотите применить на данный момент (такие решения могут не приветствоваться или даже быть невозможными в некоторых компаниях и командах). Часто просматривайте и изменяйте показатели, выбирая те, которые становятся более актуальными, и убедитесь, что все четко понимают, что измеряется и как.

Арсений Мурзенко
источник
1
+1 за ноль очков. Другие возражения были бы ААА - Arrange, Act, Assert; Параметризованные тесты; Нет копирования кода реализации ...
The Packer
5

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

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

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

Увеличение охвата кода может обеспечить более объективное измерение улучшения, представленного новыми тестами. Во-первых, общее покрытие кода должно быть записано за день до соревнования. Затем каждый разработчик должен будет каким-то образом показать увеличение покрытия кода, которое является результатом только их тестов, без учета увеличения покрытия кода, вызванного тестами, написанными другими разработчиками. Это означает, что вам, вероятно, понадобится судья, который пойдет на машину каждого разработчика и запишет покрытие нового кода до того, как будут проведены какие-либо тесты.

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

Майк Накис
источник
2
Звучит многообещающе ... но затем поведение "игровой системы" превращается в создание замечательной коллекции известных только вам ошибок, которые будут "обнаружены" в следующем конкурсе тестирования ... dilbert.com/strip/1995-11 -13
день
3
Один из вариантов - начислять баллы только за ошибки в коде, написанном кем-то другим.
Чел Скеггс
@ col6y ты прав, это тоже очень важно. К сожалению, все еще есть способы настроить систему. Например, если ваш код вызывает мой код для выполнения своей работы, мой код может проследить, чтобы ваш код попал в «аварию».
Майк Накис
3
Я не согласен. Модульные тесты, когда они только что написаны, не предназначены для поиска ошибок , это заблуждение. Они могут найти регрессии спустя недели или месяцы после того, как они были написаны, но, скорее всего, уже слишком поздно для предоставления полезных показателей для конкуренции. Обычно вы пишете модульный тест после того, как произошла конкретная ошибка, чтобы быть уверенным, что в будущем вы не получите такой же тип ошибки.
Док Браун