Тестируешь тест? - PullRequest
       20

Тестируешь тест?

7 голосов
/ 03 февраля 2009

Я в основном трачу свое время на автоматические тесты приложений win32 и .NET, которые занимают около 30% нашего времени на написание и 70% на его обслуживание. Мы изучали методы сокращения времени обслуживания и уже перешли к многоразовой тестовой библиотеке, которая охватывает большинство ключевых компонентов нашего программного обеспечения. Кроме того, у нас еще есть работа, чтобы привести нашу библиотеку в состояние, когда мы можем использовать тестирование на основе ключевых слов .

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

Как вы думаете, автоматизированные библиотеки тестирования Gui должны быть модульными? Или это просто трата времени?

Ответы [ 13 ]

11 голосов
/ 03 февраля 2009

Прежде всего, я считаю очень полезным смотреть на юнит-тест как на «исполняемые спецификации» вместо тестов. Я записываю то, что хочу, чтобы мой код делал, и затем реализую его. Большинство преимуществ, которые я получаю от написания модульных тестов, заключается в том, что они управляют процессом реализации и фокусируют мое мышление. Тот факт, что они могут повторно использовать мой код, почти счастливое совпадение.

Тестирование тестов кажется просто способом решения проблемы, а не ее решения. Кто собирается тестировать тесты, которые тестируют тесты? Уловка, которую использует TDD, чтобы удостовериться, что тесты действительно полезны, заключается в том, чтобы сначала они провалились. Это может быть то, что вы также можете использовать здесь. Напишите тест, увидите, что он провалился, затем исправьте код.

9 голосов
/ 03 февраля 2009

Я не думаю, что вам следует юнит-тестировать свои юнит-тесты.

Но если вы написали свою собственную библиотеку тестирования с пользовательскими утверждениями, контроллерами клавиатуры, кнопочными тестерами или чем-то еще, тогда да. Вам следует написать модульные тесты, чтобы убедиться, что все они работают по назначению.

Библиотека NUnit, например, тестируется модулем.

5 голосов
/ 03 февраля 2009

Возможно, вы захотите взглянуть на Кто тестирует тесты .

Короткий ответ: код проверяет тесты, а тесты проверяют код.

А?

Проверка атомных часов
Позвольте мне начать с аналогии. Предположим, что вы путешествовать с атомными часами. Откуда ты знаешь, что часы правильно откалиброван?

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

Если они разные, значит, вы знаете, что одно или другое не так.

Так что в этой ситуации, если единственный вопрос, который вы задаете, это "мой часы дают правильное время? », тогда вам действительно нужны третьи часы проверить вторые и четвертые часы, чтобы проверить третьи? Не если все. Переполнение стека исключено!

IMPO: это компромисс между тем, сколько у вас есть времени и сколько качества вы хотели бы иметь.

  • Если бы я использовал самодельные тестовые харны, я бы проверил их, если позволит время.
  • Если я использую сторонний инструмент, я ожидаю, что поставщик проверил его.
5 голосов
/ 03 февраля 2009

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

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

2 голосов
/ 20 июня 2010

Ответ

Да, ваши библиотеки тестирования GUI должны быть протестированы.

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

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

Чтобы проверить CheckGrid метод:

  • Заполнить сетку известными значениями
  • Вызвать метод CheckGrid со значениями, заполненными
  • Если этот случай проходит, работает хотя бы один аспект CheckGrid .
  • Во втором случае вы ожидаете, что метод CheckGrid сообщит о сбое теста.
  • Подробности того, как вы указываете ожидание, будут зависеть от вашей платформы xUnit (см. Пример позже). Но в принципе, если CheckGrid не сообщает о сбое теста, то сам тестовый случай должен завершиться неудачей.
  • Наконец, вам может потребоваться еще несколько тестов для особых условий, таких как: пустые сетки, размер сетки, не соответствующий размеру массива.

Вы должны иметь возможность изменить следующий пример dunit для большинства фреймворков, чтобы проверить, что CheckGrid правильно обнаруживает ошибки:

begin
  //Populate TheGrid
  try
    CheckGrid(<incorrect values>, TheGrid);
    LFlagTestFailure := False;
  except
    on E: ETestFailure do
      LFlagTestFailure := True;
  end;
  Check(LFlagTestFailure, 'CheckGrid method did not detect errors in grid content');
end;

Позвольте мне повторить: ваши библиотеки тестирования GUI должны быть протестированы; и дело в том - как вы делаете это эффективно?

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

Side Note

Одна вещь, которую вы сказали, немного беспокоит меня ... вы сказали, что "70% (вашего времени) поддерживаются (ваши тесты)"

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

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

Некоторые предложения:

  • Остерегайтесь недетерминированных значений. Например, даты и искусственные ключи могут нанести ущерб определенным тестам. Вам нужна четкая стратегия решения этой проблемы. (Другой ответ сам по себе.)
  • Вам нужно будет тесно сотрудничать с «производственными разработчиками», чтобы обеспечить стабилизацию аспектов тестируемых интерфейсов. То есть Они должны знать, как ваши тесты идентифицируют компоненты GUI и взаимодействуют с ними, чтобы они не могли произвольно нарушить ваши тесты с изменениями, которые «не влияют на них».
  • В предыдущем пункте было бы полезно запускать автоматические тесты всякий раз, когда они вносят изменения.
  • Вам также следует остерегаться слишком большого количества тестов, которые просто сводятся к произвольным перестановкам. Например, если у каждого клиента есть категория A, B, C или D; затем 4 теста «Новый клиент» (по 1 для каждой категории) дают вам 3 дополнительных теста, которые на самом деле не говорят вам намного больше, чем первый, и которые «сложно» поддерживать.
2 голосов
/ 19 июля 2009

Обычно мы используем следующие правила:

1) Весь код продукта имеет как модульные тесты (расположенные в точном соответствии с классами и функциями кода продукта), так и отдельные функциональные тесты (упорядоченные по видимым для пользователя функциям)

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

3) Юнит-тесты и функциональные тесты сами по себе никогда не тестировались напрямую - APART использует процедуру TDD для написания теста перед кодом продукта, а затем запускает тест, чтобы увидеть, как он провалился. Если вы этого не сделаете, вы будете поражены тем, насколько легко случайно написать тесты, которые всегда проходят. В идеале вы должны реализовывать свой код продукта по одному шагу за раз и запускать тесты после каждого изменения, чтобы увидеть каждое отдельное утверждение в вашем тесте, а затем реализоваться и начать выполнение. Тогда вы увидите следующее утверждение провал. Таким образом, ваши тесты ДЕЙСТВИТЕЛЬНО проверяются, но только во время написания кода продукта.

4) Если мы выделяем код из наших модульных или функциональных тестов - создавая тестовую библиотеку, которая используется во многих тестах, тогда мы проводим модульное тестирование всего этого.

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

2 голосов
/ 11 февраля 2009

В книге Кента Бека "Разработка через тестирование: на примере" приведен пример разработки модульных тестов на основе тестирования, поэтому, безусловно, можно протестировать ваши тесты.

Я не работал с GUI или .NET, но какие у вас опасения по поводу ваших модульных тестов?

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

Или вы обеспокоены тем, что он может описывать целевой код как функционирующий должным образом, даже если это не так? Если вы беспокоитесь об этом, тогда вам может потребоваться мутационное тестирование . Мутационное тестирование изменяет части тестируемого кода, чтобы увидеть, не приведут ли эти изменения к неудачным тестам. Если это не так, то либо код не выполняется, либо результаты этого кода не проверяются.

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

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

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

2 голосов
/ 04 февраля 2009

Тесты тестируют код, а код тестирует тесты. Когда вы говорите одно и то же намерение двумя разными способами (один раз в тестах и ​​один раз в коде), вероятность того, что они оба ошибаются, очень мала (если уже требования не были неправильными). Это можно сравнить с двойной бухгалтерией, используемой бухгалтерами. Смотри http://butunclebob.com/ArticleS.UncleBob.TheSensitivityProblem

Недавно в комментариях http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel

обсуждалась эта же проблема.

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

Обычно писать модульные тесты после написания кода слишком поздно, потому что тогда код имеет тенденцию быть более связанным. Модульные тесты заставляют код быть более разъединенным, потому что в противном случае небольшие блоки (класс или тесно связанная группа классов) не могут быть протестированы изолированно.

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

2 голосов
/ 03 февраля 2009

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

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

1 голос
/ 25 октября 2013

Из вашего вопроса я могу понять, что вы создаете Keyword Driven Framework для проведения автоматизации тестирования. В этом случае всегда рекомендуется провести тестирование белого ящика с общими функциями и функциями графического интерфейса. Поскольку вы заинтересованы в модульном тестировании каждой функциональности тестирования GUI в своих библиотеках, пожалуйста, сделайте это. Тестирование всегда хорошо. Это не пустая трата времени, я бы воспринимал это как «добавленную стоимость» вашей инфраструктуры.

Вы также упомянули об обработке тестового кода. Если вы имеете в виду тестовый подход, сгруппируйте различные функции / модули, выполняющие аналогичную работу, например: проверка (наличие) элемента GUI, ввод элемента GUI, чтение элемента GUI. Сгруппируйте для разных типов элементов и выполните подход модульного тестирования для каждой группы. Вам будет легче отслеживать тестирование. Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...