Я разработчик элементов управления и относительный новичок в модульном тестировании. Почти ежедневно я борюсь с тем, что вы не можете проверить элементы управления из-за взаимодействия с пользовательским интерфейсом. Я создаю демонстрационный элемент управления, чтобы показать, что можно значительно сократить ручное тестирование, если элемент управления предназначен для тестирования. В настоящее время у меня есть логическое покрытие на 50%, но я думаю, что смогу увеличить его до 75% или выше, если бы смог найти способ протестировать некоторые из более сложных деталей.
Например, у меня есть класс со свойствами, которые описывают состояние элемента управления, и метод, который генерирует объект WPF PathGeometry
, состоящий из нескольких сегментов. Реализация выглядит примерно так:
internal PathGeometry CreateOuterGeometry()
{
double arcRadius = OuterCoordinates.Radius;
double sweepAngle = OuterCoordinates.SweepAngle;
ArcSegment outerArc = new ArcSegment(...);
LineSegment arcEndToCenter = new LineSegment(...);
PathFigure fig = new PathFigure();
// configure figure and add segments...
PathGeometry outerGeometry = new PathGeometry();
outerGeometry.Figures.Add(fig);
return outerGeometry;
}
У меня есть несколько других подобных методов, которые учитывают несколько сотен блоков непокрытого кода, дополнительное покрытие 25%. Первоначально я планировал проверить эти методы, но отверг это мнение. Я все еще новичок в модульном тестировании, и единственный способ, которым я мог придумать, чтобы проверить код, - это несколько методов, подобных этому:
void CreateOuterGeometry_AngleIsSmall_ArcSegmentIsCorrect()
{
ClassUnderTest classUnderTest = new ClassUnderTest();
// configure the class under test...
ArcSegment expectedArc = // generate expected Arc...
PathGeometry geometry = classUnderTest.CreateOuterGeometry()
ArcSegment arc = geometry.Figures.Segments[0];
Assert.AreEqual(expectedArc, arc)
}
Сам тест выглядит хорошо; Я написал бы один для каждого ожидаемого сегмента. Но у меня были некоторые проблемы:
- Нужны ли мне тесты для проверки "Является ли первый сегмент
ArcSegment
?" Теоретически тест проверяет это, но не должен ли каждый тест проверять только одну вещь? Это звучит как две вещи.
- В контроле есть как минимум шесть случаев для расчета и четыре крайних случая; это означает, что для каждого метода мне нужно как минимум десять тестов.
- Во время разработки я изменил, как различные геометрии генерировались несколько раз. Это заставило бы меня переписать все тесты.
Первая проблема заставила меня задуматься, потому что казалось, что это может увеличить количество тестов. Я подумал, что мне, возможно, придется проверить такие вещи, как "Были ли сегменты х?" и «Является ли сегмент n правильным типом?», но теперь, когда я подумал больше, я вижу, что в методе нет логики ветвления, поэтому мне нужно выполнить эти тесты только один раз. Вторая проблема сделала меня более уверенным, что с тестом будет много усилий. Это кажется неизбежным. Третья проблема состоит из первых двух. Каждый раз, когда я менял способ вычисления геометрии, мне приходилось редактировать примерно 40 тестов, чтобы они соответствовали новой логике. Это также включает добавление или удаление тестов, если сегменты были добавлены или удалены.
Из-за этих трех проблем я решил написать приложение и план тестирования вручную, который переводит элемент управления во все интересные состояния и просит пользователя проверить, выглядит ли он определенным образом. Было ли это неправильно? Я переоцениваю усилия, связанные с написанием модульных тестов? Есть ли альтернативный способ проверить это, который может быть проще? (В настоящее время я изучаю макеты и заглушки; кажется, что это потребует некоторого рефакторинга дизайна и в итоге потребует примерно столько же усилий.)