Мне интересно, как правильно использовать NUnit. Во-первых, я создал отдельный тестовый проект, который использует мой основной проект в качестве ссылки. Но в этом случае я не могу тестировать частные методы. Я предполагал, что мне нужно включить свой тестовый код в свой основной код ?! - Кажется, это неправильный способ сделать это. (Мне не нравится идея поставки кода с тестами.)
Как вы тестируете частные методы с NUnit?
c#
unit-testing
testing
nunit
MrFox
источник
источник
System.Reflection
позволяет получать доступ и вызывать закрытые методы с использованием флагов привязки, чтобы вы могли взломать NUnit или настроить свою собственную структуру. Или (я думаю, проще) вы можете установить флаг времени компиляции (#if TESTING) для изменения модификаторов доступа, что позволит вам использовать существующие фреймворки.Хотя я согласен с тем, что основное внимание при модульном тестировании должно уделяться общедоступному интерфейсу, вы получите гораздо более детальное представление о своем коде, если также протестируете частные методы. Платформа тестирования MS позволяет это за счет использования PrivateObject и PrivateType, а NUnit - нет. Вместо этого я делаю следующее:
Это означает, что вам не нужно идти на компромисс с инкапсуляцией в пользу тестируемости. Имейте в виду, что вам нужно изменить свой BindingFlags, если вы хотите протестировать частные статические методы. Приведенный выше пример относится только к методам экземпляра.
источник
Обычно при написании модульных тестов тестируются только общедоступные методы.
Если вы обнаружите, что у вас есть много частных методов, которые вы хотите протестировать, обычно это знак того, что вам следует реорганизовать свой код.
Было бы неправильно делать эти методы общедоступными в классе, в котором они сейчас находятся. Это нарушит контракт, который вы хотите, чтобы этот класс имел.
Возможно, будет правильным переместить их во вспомогательный класс и сделать их там общедоступными. Этот класс не может быть предоставлен вашим API.
Таким образом, тестовый код никогда не смешивается с вашим публичным кодом.
Аналогичная проблема заключается в тестировании частных классов, т.е. классы, которые вы не экспортируете из сборки. В этом случае вы можете явно сделать вашу сборку тестового кода другом сборки производственного кода, используя атрибут InternalsVisibleTo.
источник
Можно протестировать частные методы, объявив вашу тестовую сборку как дружественную сборку целевой сборки, которую вы тестируете. См. Ссылку ниже для получения подробной информации:
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
Это может быть полезно, так как в основном тестовый код отделяется от производственного. Сам я этим методом никогда не пользовался, так как никогда не видел в нем необходимости. Я полагаю, что вы могли бы использовать его, чтобы попробовать и протестировать экстремальные тестовые случаи, которые вы просто не можете воспроизвести в своей тестовой среде, чтобы увидеть, как ваш код справляется с этим.
Однако, как уже было сказано, вам действительно не нужно тестировать частные методы. Вы более чем вероятно захотите реорганизовать свой код на более мелкие строительные блоки. Один совет, который может помочь вам, когда вы приступите к рефакторингу, - это попытаться подумать о домене, к которому относится ваша система, и подумать о «настоящих» объектах, которые населяют этот домен. Ваши объекты / классы в вашей системе должны напрямую относиться к реальному объекту, что позволит вам определить точное поведение, которое должен содержать объект, а также ограничить ответственность за объекты. Это будет означать, что вы проводите рефакторинг логически, а не просто для того, чтобы дать возможность протестировать конкретный метод; вы сможете протестировать поведение объектов.
Если вы все еще чувствуете потребность в тестировании внутреннего, вы также можете подумать о насмешках в своем тестировании, поскольку вы, вероятно, захотите сосредоточиться на одном фрагменте кода. Мокинг - это когда вы вводите в него зависимости объектов, но внедряемые объекты не являются «реальными» или производственными объектами. Это фиктивные объекты с жестко запрограммированным поведением, упрощающим выявление поведенческих ошибок. Rhino.Mocks - популярный бесплатный фреймворк для создания макетов, который по сути напишет объекты за вас. TypeMock.NET (коммерческий продукт с доступной версией сообщества) - это более мощный фреймворк, который может имитировать объекты CLR. Очень полезно для имитации классов SqlConnection / SqlCommand и Datatable, например, при тестировании приложения базы данных.
Надеюсь, этот ответ даст вам немного больше информации о модульном тестировании в целом и поможет вам получить лучшие результаты от модульного тестирования.
источник
Я за возможность тестировать частные методы. Когда xUnit запускался, он предназначался для тестирования функциональности после написания кода. Для этого достаточно протестировать интерфейс.
Модульное тестирование превратилось в разработку, основанную на тестировании. Для этого приложения полезно иметь возможность тестировать все методы.
источник
Это вопрос в последние годы, но я подумал, что поделюсь своим способом сделать это.
По сути, у меня есть все классы модульного тестирования в сборке, которую они тестируют, в пространстве имен UnitTest ниже значения по умолчанию для этой сборки - каждый тестовый файл заключен в:
block, и все это означает, что а) он не распространяется в выпуске и б) я могу использовать объявления
internal
/Friend
level без прыжков.Еще одна вещь, которую это предлагает, более уместная для этого вопроса, - это использование
partial
классов, которые можно использовать для создания прокси для тестирования частных методов, например, для тестирования чего-то вроде частного метода, который возвращает целочисленное значение:в основных классах сборки и в тестовом классе:
Очевидно, вам нужно убедиться, что вы не используете этот метод во время разработки, хотя сборка Release вскоре укажет на случайный вызов, если вы это сделаете.
источник
Основная цель модульного тестирования - проверить общедоступные методы класса. Эти общедоступные методы будут использовать эти частные методы. Модульное тестирование проверяет поведение общедоступных материалов.
источник
Приносим извинения, если это не отвечает на вопрос, но такие решения, как использование отражения, операторов #if #endif или отображение частных методов, не решают проблему. Может быть несколько причин, по которым закрытые методы не становятся видимыми ... что, если это производственный код, и команда, например, ретроспективно пишет модульные тесты.
Для проекта, над которым я работаю, только MSTest (к сожалению), похоже, имеет способ, используя аксессоры, для частных методов модульного тестирования.
источник
Вы не тестируете частные функции. Есть способы использовать отражение для доступа к частным методам и свойствам. Но это непросто, и я категорически не рекомендую эту практику.
Вы просто не должны тестировать ничего, что не является общедоступным.
Если у вас есть какие-то внутренние методы и свойства, вам следует подумать о том, чтобы сделать их общедоступными или отправить свои тесты вместе с приложением (что я не вижу в этом проблемы).
Если ваш клиент может запустить Test-Suite и увидеть, что предоставленный вами код действительно «работает», я не вижу в этом проблемы (если вы не разглашаете свой IP-адрес). В каждый выпуск я включаю отчеты об испытаниях и отчеты о покрытии кода.
источник
В теории модульного тестирования следует тестировать только контракт. т.е. только публичные члены класса. Но на практике разработчик обычно хочет протестировать внутренние члены. - и это неплохо. Да, это противоречит теории, но на практике иногда может быть полезно.
Итак, если вы действительно хотите протестировать внутренних членов, вы можете использовать один из следующих подходов:
Пример кода (псевдокод):
источник
Message: Method is not public
.Вы можете сделать свои методы защищенными внутренними, а затем использовать их
assembly: InternalsVisibleTo("NAMESPACE")
в пространстве имен тестирования.Следовательно, НЕТ! Вы не можете получить доступ к частным методам, но это обходной путь.
источник
Я бы сделал видимым пакет частных методов. Таким образом, вы сохраните его достаточно конфиденциальным, но при этом сможете протестировать эти методы. Я не согласен с тем, что люди говорят, что общедоступные интерфейсы - единственные, которые следует тестировать. Часто в частных методах есть действительно критический код, который нельзя должным образом протестировать, пройдя только через внешние интерфейсы.
Так что это действительно сводится к тому, заботитесь ли вы больше о правильном коде или сокрытии информации. Я бы сказал, что видимость пакета - хороший компромисс, так как для доступа к этому методу кому-то нужно будет поместить свой класс в ваш пакет. Это действительно должно заставить их дважды подумать, действительно ли это разумно.
Я, кстати, парень, занимающийся Java, так что package visiblilty в C # можно назвать совершенно другим. Достаточно сказать, что это когда два класса должны находиться в одном пространстве имен, чтобы получить доступ к этим методам.
источник