Каковы (не) преимущества написания модульных тестов на другом языке, чем код? - PullRequest
10 голосов
/ 13 ноября 2009

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

Возможно, иногда имеет смысл писать свои модульные тесты на языке, который лучше подходит для написания модульных тестов? Конкретный пример, который я имею в виду, - это написание приложения на C #, но с использованием IronRuby или IronPython для написания тестов.

На мой взгляд, использование IronPython и IronRuby имеет несколько преимуществ по сравнению с кодом C # в качестве языка тестирования:

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

Каковы компромиссы в использовании двух разных языков для тестирования и производственного кода?

Ответы [ 10 ]

11 голосов
/ 13 ноября 2009

Недостатки, которые приходят мне в голову:

  • В зависимости от языка вам нужна другая среда разработки (дополнительная зависимость проекта, дополнительные усилия по настройке машины разработки, дополнительные лицензии, дополнительное обучение ...)
  • Рефакторинг иногда поддерживается IDE - но, скорее всего, не для этого другого языка. Таким образом, вы должны выполнить их рефакторинг вручную.
  • Модульные тесты также можно использовать в качестве примеров программирования . Тесты показывают, как тестируемые классы предназначены для использования. Это не очень хорошо работает, если тесты написаны на другом языке.
7 голосов
/ 13 ноября 2009

Одна очевидная потенциальная проблема - это запутанный опыт отладки. Я лично не пытался отлаживать разные языки в .NET - что произойдет, если вы перейдете на код C # из IronPython?

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

3 голосов
/ 13 ноября 2009

Я большой поклонник языков Iron, но есть значительные недостатки в их использовании для тестирования статически скомпилированного кода. Тестирование Ruby / Python с Ruby / Python прекрасно работает, то есть вы можете подделывать объекты любым количеством способов. Но тестирование C # с Ruby / Python может привести к большей сложности, чем хотелось бы.

Рассмотрим сценарий, в котором вы пишете проект ASP MVC, в котором вы хотели бы подделать тип браузера, отправляющего запрос контроллеру. В C # вы можете сделать это так (используя Moq):

var fakeRequest = new Moq.Mock<System.Web.HttpRequestBase>();
fakeRequest.Setup(request => request.Browser.Type).Returns("Fake");

В IronRuby это будет выглядеть примерно так:

class FakeBrowser < HttpBrowserCapabilitiesBase
  def type
    "Fake"
  end
end

class FakeRequest < HttpRequestBase
  def browser
    FakeBrowser.new
  end
end

Чем глубже контекст, который необходимо выдумать, тем сложнее он становится. В C # фреймворк автоматически выполняет подтип для вас, но на динамическом языке вам, к сожалению, предстоит много работы. Библиотеки-насмешки, такие как PyMock или Mocha, не будут работать для таких тестов, потому что тестируемый код имеет строгие типизированные зависимости, а поддельные объекты, генерируемые средами Ruby / Python, не будут соответствовать этим зависимостям. Мне бы хотелось, чтобы ситуация улучшилась по мере развития как IronRuby, так и IronPython, но сейчас история с тестированием на C # не так хороша.

Если мое мнение неверно, я бы с удовольствием исправился. =)

2 голосов
/ 13 ноября 2009

Я думаю, что это отличный вопрос и идея, заслуживающая рассмотрения - особенно в среде, такой как Visual Studio / .NET, где это легко поддерживается

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

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

Будет еще интереснее, если вы выйдете за рамки «модульных» тестов и протестируете их на всех уровнях, где конкретные возможности конкретных языков могут дать преимущества при создании тестового примера.

Последний вопрос заключается в том, перевешивают ли преимущества недостатки ... и это, вероятно, в некоторой степени зависит от конкретного случая.

2 голосов
/ 13 ноября 2009

Основным недостатком, как я вижу, является ремонтопригодность. Если вы пишете код на C #, ваша команда разработчиков компетентна в этом языке, как и новые сотрудники. Вам нужна многофункциональная команда разработчиков.

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

Вам также нужно переключаться между синтаксисами во время написания кодов / тестов - это немного неприятно.

1 голос
/ 13 ноября 2009

Я согласен с другими ответами, что есть недостатки, но я удивлен, что так мало говорили о преимуществах.

  • Работа с TDD на разных языках - отличный способ выучить новые языки: написать тесты на языке, который вы хорошо знаете, и реализовать на языке, который вы изучаете. По мере изучения вы обнаружите лучшие способы написания кода, чем в первый раз, но рефакторинг очень прост, потому что у вас есть набор тестов.
  • Владение несколькими языками помогает вам (и вашей команде) быть в курсе.
  • Вы получаете лучшую проверку того, что ваш API совместим между языками.
1 голос
/ 13 ноября 2009

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

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

1 голос
/ 13 ноября 2009

При создании API или библиотеки я часто поставляю модульные тесты в виде документации о том, как лучше всего использовать API или библиотеку. Большую часть времени я создаю библиотеку C #, я поставляю клиенту, который будет писать код C # для использования библиотеки.

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

1 голос
/ 13 ноября 2009

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

0 голосов
/ 05 марта 2012

Опыт 1

В прошлом году я работал над проектом, состоящим из двух основных частей:

  1. Веб-приложение Grails
  2. и приложение Java Swing

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

Опыт 2

Другим недавним проектом, над которым я работал, было веб-приложение на C # ASP.NET MVC 3, где я написал все модульные тесты на F #. Я выбрал C # для веб-приложения, потому что чувствовал, что он лучше работает с MVC 3. Я выбрал F # для модульных тестов, потому что это мой любимый язык. Единственными проблемами, с которыми я столкнулся, были небольшие неприятности с такими типами, как null против option.

Заключение

Когда у нас есть два языка, предназначенные для одной и той же среды выполнения (ну, C # / F # и Java / Groovy для CLR и JRE соответственно), где один используется для производственного кода, а другой - для модульных тестов, беспокоиться не о чем по поводу совместимости как минимум. Тогда я думаю, что это действительно вопрос того, чувствуете ли вы и ваша команда достаточно комфортно на обоих языках (и я полагаю, вы можете быть достаточно любезны, чтобы подумать и о будущих сопровождающих). На самом деле, я думаю, что вы вынуждены использовать другой язык для модульного тестирования, когда язык модульного тестирования на самом деле является вашим языком комфорта или выбором по сравнению с вашим рабочим языком.

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

...