2009-02-14 3 views
1

Представьте себе систему фильтров (возможно, аудио-фильтры или фильтры текстовых потоков).Как избежать дублирующих модульных тестов при тестировании взаимодействий на композитах?

A Filter базовый класс имеет метод do_filter(), который принимает некоторый ввод, изменяет его (возможно) и возвращает его как результат.

Существует несколько подклассов, построенных с использованием TDD, и каждый из них имеет набор тестов, которые проверяют их изолированно.

Наряду приходит составную класс, несвязанного типа Widget, который состоит из двух членов различных Filter типов (a и b), которые имеют дело с совершенно другим входом - то есть, определенные входным который будет изменен фильтром a является прошел через немодифицированный фильтром b и наоборот. Его метод process_data() вызывает каждый элемент фильтра do_filter().

При разработке составного класса существуют тесты emerge, которые проверяют, что фильтры Widget не обрабатывают одни и те же данные.

Проблема в том, что подобные тесты идентичны тесту отдельного фильтра. Несмотря на то, что могут быть и другие тесты, результаты тестов, которые должны быть изменены обоими фильтрами, многие из тестов могут быть почти равны , скопированы и вставлены из каждого теста фильтра с небольшими изменениями, необходимыми для их тестирования с помощью Widget (например, как вызов process_data()), но входные данные и проверки assert идентичны.

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

ответ

3

В течение одного тестового набора/класса есть метод

public void TestForFooBehaviour(IFilter filter) 
{ 
    /* whatever you would normally have in a test method */ 
} 

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

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

1

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

1

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

How to unit test abstract classes: extend with stubs?

Смежные вопросы