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

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

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

Как я вижу, использование IronPython и IronRuby имеет несколько преимуществ перед кодом С# в качестве языка тестирования:

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

Рассмотрим сценарий, в котором вы пишете проект ASP MVC, где вы хотели бы подделать тип браузера, делающего запрос на контроллер. В С# вы можете издеваться над этим (используя 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

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

Если я ошибаюсь, я бы с радостью согласился. =)

Ответ 4

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

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

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

Ответ 9

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

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

Ответ 10

Опыт 1

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

  • Веб-приложение Grails
  • и приложение Java Swing

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

Опыт 2

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

Заключение

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

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