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

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

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

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

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

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

10 ответов


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

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

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

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


Я большой поклонник железных языков, но есть значительные недостатки в использовании их для тестирования статически скомпилированного кода. Тестирование 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# не так хороша.

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


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

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

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


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

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

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

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

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


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


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

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


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

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


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

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

опыт 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 (по крайней мере, некоторые). Но для кода приложения я никогда не находил написания модульных тестов в же язык как рабочий код особенно выгодно.