Это Утверждение.Не() считается плохой практикой?
Я использую Assert.Терпеть неудачу много при выполнении TDD. Обычно я работаю над одним тестом за раз, но когда я получаю идеи для вещей, которые я хочу реализовать позже, я быстро пишу пустой тест, где имя метода теста указывает, что я хочу реализовать как своего рода список задач. Чтобы убедиться, что я не забыл, я поставил утверждение.Fail () в теле.
при попытке xUnit.Net я обнаружил, что они не реализовали Assert.Неудача. Конечно, вы всегда можете утверждать.IsTrue (false) но это не так сообщи и о моем намерении. У меня сложилось такое впечатление.Сбой не был реализован специально. Это считается плохой практикой? Если да, то почему?
@Martin Meredith Это не совсем то, что я делаю. Сначала я пишу тест, а затем реализую код, чтобы заставить его работать. Обычно я думаю о нескольких тестах сразу. Или я думаю о тесте, чтобы написать, когда я работаю над чем-то еще. Вот когда я пишу пустой провальный тест, чтобы помнить. К тому времени, как я приступаю к написанию теста, я аккуратно работаю тест-первый.
@Jimmeh Похоже, это хорошая идея. Проигнорированные тесты не терпят неудачу, но они все еще появляются в отдельном списке. Надо попробовать.
@Matt Howells великая идея. NotImplementedException передает намерение лучше, чем assert.Fail () в этом случае
@Mitch Пшеница Это то, что я искал. Кажется, он был оставлен, чтобы предотвратить его злоупотребление другим способом, которым я его злоупотребляю.
13 ответов:
для этого сценария, а не вызова assert.Сбой, я делаю следующее (В C# / NUnit)
[Test] public void MyClassDoesSomething() { throw new NotImplementedException(); }
это более явно, чем утверждение.Неудача.
[Test] public void ThrowsExceptionCorrectly() { const string BAD_INPUT = "bad input"; try { new MyClass().DoSomething(BAD_INPUT); Assert.Fail("No exception was thrown"); } catch (MyCustomException ex) { Assert.AreEqual(BAD_INPUT, ex.InputString); } }
xUnit.Net метод Assert.Броски делают это намного аккуратнее, не требуя утверждения.Не способ. Не включая утверждение.Метод Fail() xUnit.Net рекомендует разработчикам находить и использовать более явные альтернативы, а также поддерживать создание новых утверждений там, где это необходимо.
Это было намеренно. Это ответ Брэда Уилсона на вопрос, почему нет утверждения.Fail ():
мы не пропустили это, на самом деле. Я найдите утверждение.Неудача-это костыль, который подразумевает, что, вероятно, есть утверждение отсутствует. Иногда это просто способ структурирования теста, а также иногда это потому, что утверждать может используйте другое утверждение.
Я всегда использовал Assert.Fail () для обработки случаев, когда вы обнаружили, что тест должен завершиться неудачей с помощью логики, выходящей за рамки простого сравнения значений. В качестве примера:
try { // Some code that should throw ExceptionX Assert.Fail("ExceptionX should be thrown") } catch ( ExceptionX ex ) { // test passed }
таким образом, отсутствие утверждения.Не() в рамках выглядит как ошибка для меня. Я бы предложил исправить класс Assert, чтобы включить метод Fail (), а затем отправить патч разработчикам платформы вместе с вашими аргументами для его добавления.
Что касается вашей практики создания тестов, которые намеренно не удается в вашем рабочем пространстве, чтобы напомнить себе, чтобы реализовать их перед совершением, это кажется мне прекрасной практикой.
Я использую MbUnit для моего модульного тестирования. У них есть возможность игнорировать тесты, которые отображаются как оранжевый (а не зеленый или красный) в наборе тестов. Возможно, xUnit имеет что-то подобное, и это означает, что вам даже не нужно вводить какое-либо утверждение в метод, потому что оно будет отображаться в раздражающе другом цвете, что затруднит его пропустить?
Edit:
в MbUnit это происходит следующим образом:
[Test] [Ignore] public void YourTest() { }
это шаблон, который я использую при написании теста для кода, который я хочу бросить исключение по дизайну:
[TestMethod] public void TestForException() { Exception _Exception = null; try { //Code that I expect to throw the exception. MyClass _MyClass = null; _MyClass.SomeMethod(); //Code that I expect to throw the exception. } catch(Exception _ThrownException) { _Exception = _ThrownException } finally { Assert.IsNotNull(_Exception); //Replace NullReferenceException with expected exception. Assert.IsInstanceOfType(_Exception, typeof(NullReferenceException)); } }
IMHO это лучший способ тестирования исключений с помощью Assert.Неудача.)( Причина этого заключается в том, что я не только тестирую исключение, но и тестирую тип исключения. Я понимаю, что это похоже на ответ от Мэтта Хауэлла, но IMHO, использующий блок finally, более надежен.
очевидно, что это все равно можно включить другие методы Assert для проверки входной строки исключений и т. д. Я был бы признателен за ваши комментарии и мнения о моей модели.
лично у меня нет проблем с использованием набора тестов в качестве списка задач, как это до тех пор, как вы в конечном итоге получить вокруг написания теста до вы реализуете код, чтобы пройти.
сказав это, я сам использовал этот подход, хотя теперь я нахожу, что это приводит меня к написанию слишком много тестов заранее, что странным образом похоже на обратную проблему не писать тесты вообще: вы в конечном итоге принимаете решения о дизайне немного слишком рано ИМХО.
кстати в MSTest, стандартный шаблон теста использует Assert.Неубедительно в конце своих образцов.
AFAIK the xUnit.NET фреймворк призван быть чрезвычайно легким, и да, они намеренно сократили неудачу, чтобы побудить разработчика использовать явное условие отказа.
Wild guess: удержание утверждения.Fail предназначен для того, чтобы вы перестали думать, что хороший способ написать тестовый код-это огромная куча спагетти, ведущая к утверждению.Не в плохих случаях. [Edit to add: ответы других людей в целом подтверждают это, но с цитатами]
Так как это не то, что вы делаете, вполне возможно, что xUnit.Net это чрезмерная защита.
I предпочитаю реализовывать функцию под названием ThisCodeHasNotBeenWrittenYet (на самом деле что-то короче, для удобства ввода). Невозможно передать намерение более четко, чем это, и у вас есть точный поисковый запрос.
Если это не удается, или не реализовано (чтобы спровоцировать ошибку компоновщика), или макрос, который не компилируется, может быть изменен в соответствии с вашими текущими предпочтениями. Например, когда вы хотите запустить что-то, что и готово, вы хотите неудачу. Когда ты садишься чтобы избавиться от них всех, вам может понадобиться ошибка компиляции.
С хорошим кодом я обычно делаю:
void goodCode() { // TODO void goodCode() throw new NotSupportedOperationException("void goodCode()"); }
С тестовым кодом я обычно делаю:
@Test void testSomething() { // TODO void test Something Assert.assert("Some descriptive text about what to test") }
Если вы используете JUnit и не хотите получить сбой, но ошибку, то я обычно делаю:
@Test void testSomething() { // TODO void test Something throw new NotSupportedOperationException("Some descriptive text about what to test") }
Почему бы вам использовать Assert.Не удалось сказать, что исключение должно быть брошено? В этом нет необходимости. Почему бы просто не использовать атрибут ExpectedException?
будьте осторожны
Assert.Fail
и его тлетворное влияние, чтобы заставить разработчиков писать глупые или сломанные тесты. Например:[TestMethod] public void TestWork() { try { Work(); } catch { Assert.Fail(); } }
это глупо, потому что try-catch является избыточным. Тест завершается неудачно, если он создает исключение.
и
[TestMethod] public void TestDivide() { try { Divide(5,0); Assert.Fail(); } catch { } }
это сломано, тест всегда будет проходить независимо от результата функции деления. Опять же, тест не выполняется, если и только если он бросает исключение.
Если вы пишете тест, который просто терпит неудачу, а затем пишете код для него, а затем пишете тест. Это не тестовая разработка.
Технически, Утверждают.fail () не должен быть необходим, если вы используете тестовую разработку правильно.
вы думали об использовании списка задач или применении методологии GTD к своей работе?
MS тест имеет Assert.Fail (), но он также имеет Assert.Неубедительно (). Я думаю, что наиболее подходящее использование для Assert.Fail ()-это если у вас есть какая-то встроенная логика, которую было бы неудобно вводить в утверждение, хотя я даже не могу придумать хороших примеров. По большей части, если тестовая платформа поддерживает что-то другое, чем Assert.Fail () затем используйте это.
Я думаю, вы должны спросить себя, что (авансовое) тестирование должно делать.
во-первых, вы пишете (набор) тест без реализации. Может быть, и сценарии на черный день.
все эти тесты должны потерпеть неудачу, чтобы быть правильным тестов: Таким образом, вы хотите достичь двух вещей: 1) Убедитесь, что ваша реализация-это правильно; 2) Убедитесь, что ваш юнит-тесты являются правильными.
теперь, если вы делаете upfront TDD, вы хотите выполнить все свои тесты, а также части NYI. Результат ваш общий тестовый прогон проходит, если: 1) все реализованные вещи успешно 2) все NYI вещи терпит неудачу
В конце концов, это будет модульный тест ommision, если ваши модульные тесты будут успешными, пока нет реализации, не так ли?
вы хотите в конечном итоге получить что-то вроде почты вашего непрерывного интеграционного теста, который проверяет весь реализованный и не реализованный код и отправляется, если какой-либо реализованный код терпит неудачу или какой-либо не реализованный код успешно выполняется. Оба нежелательны результаты.
просто напишите [игнорировать] тесты не будет делать эту работу. Ни один из них не утверждает, что останавливает первый сбой утверждения, а не запускает другие строки тестов в тесте.
теперь, как достичь этого? Я думаю, что это требует более продвинутой организации вашего тестирования. И для достижения этих целей требуется какой-то другой механизм, который затем утверждает.
Я думаю, что вы должны разделить свои тесты и создать некоторые тесты, которые полностью выполняются, но должны потерпеть неудачу, и наоборот наоборот.
идеи состоят в том, чтобы разделить ваши тесты на несколько сборок, использовать группировку тестов (заказанные тесты в mstest могут выполнять эту работу).
тем не менее, сборка CI, которая отправляет по почте, если не все тесты в отделе NYI терпят неудачу, нелегка и прямолинейна.