NUnit Атрибут для имитации Assert.Inconclusive на основе условий с пользовательским текстом сообщения - PullRequest
2 голосов
/ 13 января 2020

У меня есть несколько тестов, которые зависят от того, является ли определенная вещь истинной (доступ к inte rnet, как это происходит, но это не важно, и я не хочу обсуждать детали условия).

Я могу очень легко написать вспомогательный метод stati c, который проверит условие (без параметров) и вызовет Assert.Inconclusive("Explanatory Message"), если оно true / false. И затем назовите это в начале каждого Test, который имеет это требование.

Но я бы хотел сделать это как Attribute, если возможно.


Как, в деталях, добиться этого в NUnit?

Что я пробовал до сих пор:

Есть IApplyToTest интерфейс , предоставляемый NUnit, который я могу сделать своим атрибутом реализации и позволит мне подключиться к TestRunner, но я не могу заставить его делать то, что я хочу: (

Этот интерфейс дает мне доступ к NUnit.Framework.Internal.Test объекту.

Если я позвоню:

test.RunState = RunState.NotRunnable;

, тогда я получу нечто эквивалентное на Assert.Fail("").

Точно так же RunState.Skipped или RunState.Ignored дают мне эквивалент Assert.Ignore("").

Но ни один из них не устанавливает сообщение в Тесте, и нет test.Message = "foo"; или эквивалент (который я вижу).

Существует test.MakeInvalid("Foo"), который делает , чтобы установить сообщение, но это эквивалентно Assert.Fail("Foo").

Я нашел то, что выглядело многообещающе:

var result = test.MakeTestResult();
result.SetResult(ResultState.Inconclusive, "Custom Message text");

Но, похоже, ничего не делает ; тест просто проходит :( Я искал метод test.SetAsCurrentResult(result) на тот случай, если мне нужно «прикрепить» этот объект результата обратно к тесту? Но ничего не происходит.

Такое ощущение, что это возможно, но я не могу понять, как заставить все это играть вместе.


Если кто-нибудь может даже показать мне, как добраться до Skipped + Custom Message displayed, то я, вероятно, возьму это!

1 Ответ

0 голосов
/ 14 января 2020

Если вы действительно хотите, чтобы ваш тест был Inconclusive, то для этого есть Assume.That. Используйте его так же, как если бы вы использовали Assert.That, и указанное ограничение не выполнится, ваш результат теста будет неубедительным.

Это будет самый простой ответ на ваш вопрос.

Однако, читая вы пытались, я не думаю, что вы действительно хотите Inconclusive, по крайней мере, не так, как это определено NUnit.

В NUnit, Inconclusive означает, что тест не считается, потому что он не мог быть запущенным Результат в основном исчезает, и тестовый запуск выполнен успешно.

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

NUnit предоставляет Assert.Ignore и Warn.If (также Warn.Unless) для эти ситуации. Или вы можете установить соответствующие состояния результатов в своем пользовательском атрибуте.

Относительно реализации ... RunState теста применяется к его статусу еще до того, как кто-либо попытался его выполнить. Так, например, RunState может игнорироваться, если кто-то использовал IgnoreAttribute, или может быть NotRunnable, если для него требуются аргументы, и ни один из них не предоставлен. Inconclusive run sttate не существует, потому что это означало бы, что тест написан так, что он все время не дает результатов, что не имеет смысла. Интерфейс IApplyToTest позволяет атрибуту изменять состояние теста в точке обнаружения еще до его запуска, поэтому вы не захотите его использовать.

После NUnit попытался выполнить тест, он получает ResultState, который может быть неокончательным. Вы можете повлиять на это в коде теста, но не через атрибут. Здесь нужно что-то, что проверяет условия, необходимые для запуска теста непосредственно перед его запуском, и пропускает выполнение, если условия не выполняются. Этот атрибут должен быть тем, который генерирует команду в цепочке команд, выполняющих тест. Вероятно, для этого потребуется реализовать ICommandWrapper, что немного сложнее, чем IApplyToTest, потому что код атрибута должен генерировать экземпляр команды, который будет правильно работать с самим NUnit и другими командами в цепочке.

Если бы у меня была такая ситуация, я полагаю, что использовал бы параметр Run, чтобы указать, должно ли быть доступно целое число rnet. Затем тесты могут

Assume.That(InternetIsNotNeeded());

молча игнорировать эти тесты или потерпеть неудачу, как и ожидалось, когда будет доступен inte rnet.

...