Недавно я задал (и ответил) вопрос на StackOverflow о том, почему модульное тестирование будет работать при запуске само по себе, а затем сбоит время от времени при запуске с целым пакетом модульных тестов.См. Здесь: SQL Server и TransactionScope (с MSDTC): время от времени не удается получить соединение
Модульные тесты, проходящие при запуске по одному, а затем сбои при совместной работе - это классический признакчто-то серьезно не так с кодом.
Я обнаружил, что есть небольшая утечка ресурсов.Из-за незначительной ошибки, приводившей к невозможности освободить соединения с сервером SQL, у меня заканчивались соединения, и тесты не выполнялись.AFAIK, это работает почти так же, как утечка памяти;соединения выделяются из пула соединений и никогда не освобождаются, так как память может быть выделена, а затем не освобождена.
Однако, это вызывает у меня загадочный вопрос?В чем разница между выполнением моих тестов по одному и выполнением их как набора?Если тесты проходят при запуске по одному, а затем сбой при запуске вместе, то между тестами должна происходить какая-то очистка, которая происходит только тогда, когда тесты запускаются по одному.
Я предполагаю, что это может быть связано с тем, что сборщик мусора .net делает или не делает между тестами.В одном случае соединения освобождаются между тестами;в другом случае это не так.
Как я могу это объяснить?
Обновление : Для тех из вас, кто интересуется спецификой кода, это довольно просто.,Я объявляю новый объект TransactionScope
в моем методе Setup и располагаю его в моем методе Teardown
.Тем не менее, проблемный тест был тестом на основе данных с 100 тестовыми случаями;тестируемый код заполнял объект SqlDataReader
из оператора select с использованием класса SqlHelper, а затем не вызывал метод close в SqlDataReader
.Поскольку я использовал класс SqlHelper для получения SqlDataReader, я ожидал, что соединения будут обработаны для меня.Не так!
Но, чтобы уточнить , я не спрашиваю о моей конкретной ситуации.Что я хочу знать, так это: как вообще освобождаются ресурсы между тестами?Я предположил бы, что это было бы некоторым применением сборщика мусора.Интересно, может ли сборщик мусора все еще очищать предыдущий тест во время следующих тестов (состояние гонки?)
Обновление: что я знаю о сборке мусора с помощью модульных тестов. После моихДля собственного любопытства я вытащил модульные тесты, которые не были выполнены, потому что объект SqlDataReader
оставил соединение открытым.Я пытался добавить System.GC.Collect()
в конце каждого теста.Это успешно освободило соединения, но наложило ~ 50% снижения производительности.