все. У меня сложное взаимодействие между контрактами, pex и quickgraph, и я был бы очень благодарен за совет от более знающих. Я свел это к случаю воспроизведения, когда комментирование одного контракта устраняет ложноотрицательный результат, но я не смог диагностировать его с помощью отладчика за отведенное время, потому что код объекта (quickgraph) имеет побочные эффекты в свойстве - геттеры, что означает, что отладчик выполняет побочные эффекты при отображении значений свойств, влияя на фактический порядок выполнения.
Сначала немного предыстории, затем подробности, затем указатель на проект, который нужно загрузить и опробовать, если вы захотите вникнуть в него!
Я установил Pex & Moles
http://research.microsoft.com/en-us/projects/pex/downloads.aspx
и CodeContracts для .NET 4.0
http://research.microsoft.com/en-us/projects/contracts/ а>
Я загрузил через nuget самую последнюю версию QuickGraph, которая полностью построена для .NET 3.5. Я сократил его до необходимого мне минимума, вошел в свойства проекта для всех, обновил их все до .NET 4.0 из профиля клиента .NET 3.5, исправил одно критическое изменение источника (что было тривиально и очень, очень маловероятно, чтобы иметь какое-либо соединение с моим проблема). Затем я перешел на вкладку «Контракты кода» на каждой странице проекта и включил все статические и динамические параметры.
http://quickgraph.codeplex.com/releases/view/55262
В проекте 192 юнит-теста, многие из которых сгенерированы Pex (очень красиво!). Чтобы запустить тесты, загрузите zip-файл моего проекта из
http://dl.dropbox.com/u/1997638/QuickGraph.zip
Убедитесь, что у вас есть Pex & Moles и Contracts по ссылкам выше. Откройте решение, перестройте все, затем на уровне решения «Запустить все тесты в решении» (Ctrl-R, A). Все пройдет. Затем перейдите к строке 49 файла IImplicitUndirectedGraphContracts.cs и раскомментируйте Контракт под большим комментарием (добавленным мной). Один тест, Prim12240WithDelegate, завершится ошибкой.
В этом тесте используется конструктор графа, который на лету строит ребра, вызывая предоставленный пользователем делегат в средствах получения свойств для Edges и EdgeCount. Милый. Но что-то идет не так с Контрактом в строке 49 IImplicitUndirecteGraphContracts.cs.
Это ложноотрицательный результат, потому что, если я закомментирую этот контракт, тест пройдёт. Пытаясь проследить это в отладчике, это как-то связано со временем создания краев в средствах получения свойств. Однако я не смог распутать это, потому что отладчик вызывает эти геттеры, код объекта вызывает их, код контрактов вызывает их, может быть, статически, может быть, динамически, я просто потерялся, пытаясь следовать за ним, и подумал, что я Подниму вопрос к тем, кто лучше меня разбирается в деталях исполнения контрактов.
Вот оскорбительный контракт; комментирование этого делает модульный тест успешным:
[Pure]
IEnumerable<TEdge> IImplicitUndirectedGraph<TVertex, TEdge>.AdjacentEdges(TVertex v)
{
IImplicitUndirectedGraph<TVertex, TEdge> ithis = this;
Contract.Requires(v != null);
Contract.Requires(ithis.ContainsVertex(v));
Contract.Ensures(Contract.Result<IEnumerable<TEdge>>() != null);
~~~~~~> Contract.Ensures(
Enumerable.All(
Contract.Result<IEnumerable<TEdge>>(),
edge =>
edge != null &&
ithis.ContainsEdge(edge.Source, edge.Target) &&
(edge.Source.Equals(v) || edge.Target.Equals(v))
)
);
return default(IEnumerable<TEdge>);
}