Как настроить Pex для соблюдения кодовых контрактов?

Учитывая следующий пример кода, как я могу настроить Pex для соблюдения моих контрактов кода?

    public static IEnumerable<User> Administrators(this UserGroup userGroup)
    {
        Contract.Requires(userGroup != null);
        Contract.Requires(userGroup.UserList != null);

        return userGroup.UserList.Where(ul => ul.IsAdmin == true);
    }

Текущая проблема: когда я запускаю Pex, он все еще генерирует тестовые случаи, которые нарушают указанные контракты кода.

К вашему сведению: вот настройки 'Code Contracts' в моем файле csproj.


EDIT: Что-то сломается в SP1?


person Jim G.    schedule 26.05.2011    source источник
comment
Вы пробовали писать им по электронной почте? [email protected]   -  person porges    schedule 27.05.2011
comment
Я думаю, это ошибка. Решение Джона Николаса работает, но для PEX это по-прежнему неправильно. Смысл использования кодовых контрактов с pex заключался в том, что PEX автоматически обнаруживал кодовые контракты и рассматривал их отказ как ожидаемое поведение или прохождение теста.   -  person Joshua Dale    schedule 02.07.2011


Ответы (5)


Сначала вам нужно использовать типизированную версию Requires

использовать ArgumentNullException как T

Также в свойствах вашего проекта вам нужно указать контрактам кода использовать стандартный переписчик. НЕ нажимайте «Утвердить» в случае неудачи;)

Contract.Requires<ArgumentNullException>(i != null);

тогда ваш код выдаст исключение argumetn null, и pex может добавить атрибут к вашему pexmethod, чтобы сказать, что ему разрешено его генерировать, и создаст проходной тест, который выдает исключение

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

person John Nicholas    schedule 24.06.2011
comment
+1: Большое спасибо!! Эта настройка «Утверждать при отказе» сильно сбила меня с толку. - person Jim G.; 24.06.2011
comment
да, я провел несколько часов, разбивая лицо о клавиатуру об этом;) - person John Nicholas; 25.06.2011
comment
Я думаю, что это обходной путь, а не решение. Я думаю, что это решение может не обнаружить настоящее исключение ArgumentNullException, которое может быть вызвано откуда-то еще в тестируемом коде. В своем ответе я предлагаю альтернативное решение, в котором нет этой проблемы. - person lexicalscope; 05.06.2013
comment
Не согласен, так как этот фрагмент кода также должен обрабатывать свое исключение ... это затем будет пузыриться по контракту. - person John Nicholas; 03.07.2013

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

Что делает Pex, так это пишет тесты, нарушающие контракт, чтобы они проходили при возникновении исключения.

TL/DR Не беспокойтесь об этом.

person Bryan Anderson    schedule 27.05.2011
comment
Спасибо за информацию, Брайан. Просто любопытно - есть ли способ, которым я могу сказать Pex, чтобы он ожидал исключения и помечал этот тест зеленым, когда он нарушает контракт? - person Jim G.; 27.05.2011
comment
Pex должен пометить тест зеленым цветом, если он автоматически нарушает контракт, если контракт выдает утверждение или исключение. - person Bryan Anderson; 27.05.2011
comment
Так и должно быть, но я думаю, что текущая реализация не работает. У меня проблема с ним в настоящее время. stackoverflow.com/questions/5845610/ - person Joshua Dale; 22.06.2011
comment
@Joshua Dale: Решение @John Nicholas сработало для меня. Пожалуйста, попробуйте. - person Jim G.; 24.06.2011
comment
Это исправление, но это все еще не правильное поведение. Тесты должны автоматически подхватывать контракты кода и обрабатывать сбои как ожидаемое поведение. - person Joshua Dale; 02.07.2011

У меня такая же проблема. Есть две вещи:

1) Убедитесь, что перезапись во время выполнения включена (как предлагает Джон)

2) Убедитесь, что ваш тестовый класс украшен [PexClass(typeof(MyClass))]

Я написал тест вручную, поэтому я забыл, что атрибут PexClass и контракты обрабатывались Pex как обычные исключения, поэтому они терпели неудачу.

Гонза

person hoonzis    schedule 09.12.2011

Мне также пришлось включить Contract Reference Assembly в Build (я также выпустил файл документа XML, чтобы я мог видеть контракты в VS).

Кажется, это необходимо для того, чтобы Pex понимал контракты.

person nicodemus13    schedule 30.01.2013

Существует атрибут PexAllowedContractRequiresFailure, которым вы можете украсить свой тестовый метод, чтобы указать Pex не создавать тесты, которые приводят к сбою требования.

Вы также должны включить «Выполнить проверку контракта во время выполнения» в свойствах вашего решения.

[TestClass]
public partial class MyTest
{
   [PexMethod]
   [PexAllowedContractRequiresFailure]
   public void TestMethod(int myParam)
   {
      Contract.Requires(myParam > 5);
      ...
   }
}

Существует также связанный PexAllowedContractRequiresFailureAtTypeUnderTestSurface, который, я думаю, может быть полезен, если «Требования», которые вы хотите, чтобы Pex уважал, находятся глубже в дереве вызовов.

person lexicalscope    schedule 04.06.2013