Автоматизированный способ поиска тестов JUnit с утечкой памяти - PullRequest
1 голос
/ 14 мая 2009

Корень нашей проблемы - синглтоны. Но Singletons трудно сломать, и в то же время у нас есть много модульных тестов, которые используют Singletons, не заботясь о полной очистке их в методе tearDown (). Я считаю, что хороший способ обнаружения таких тестов - это поиск утечек памяти. Если объем памяти, использованный после tearDown () и System.gc (), больше, чем при запуске теста, либо произошел утечка теста, либо загрузчик классов был загружен. Есть ли способ автоматически обнаружить такого рода проблемы?

Ответы [ 6 ]

2 голосов
/ 14 мая 2009

Не могли бы вы представить подкласс между TestCase и вашими индивидуальными тестовыми классами, который выполнял очистку? Тогда подклассы будут отвечать только за вызов super.teardown () - и только те, которые имеют teardown () самостоятельно.

1 голос
/ 14 мая 2009

Я полностью согласен с другими авторами, что отслеживание использования памяти не является жизнеспособным способом отследить это - System.gc () не будет вести себя так, как вы ожидаете, или с достаточной точностью для достижения вашей цели.

Вам понадобится инструмент, который позволит вам проверить контрольный график и показать стеки вызовов распределения.

Я использовал OptimizeIt от Borland и JProfiler от ej-технологий, оба с успехом (быстрый Google показывает, что OptimizeIt теперь может быть мертв.)

Существует также возможность использования JVMTI , чтобы собрать лучший монитор для этой конкретной проблемы.

Редактировать : Странно, но, когда я просматривал этот ответ, мне позвонил Embarcadero, который, очевидно, приобрел OptimizeIt, произвел некоторое обновление и теперь занимается маркетингом под именем J Optimizer .

0 голосов
/ 15 мая 2009

Вы можете использовать Eclipse Memory Analyzer для автоматизации анализа дампов кучи, полученных после каждого теста или, возможно, лучше после всех тестов. MAT может обнаружить утечки памяти довольно автоматически.

0 голосов
/ 14 мая 2009

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

С точки зрения более полного решения этой проблемы, вместо того, чтобы обнаруживать ее, я бы порекомендовал вам иметь одноэлементный инициализатор, который запоминает то, что он инициализировал, и один метод разрыва, который разбирает все, что он инициализировал. Таким образом, тесты могут быть выполнены только для инициализации через этот класс, и в разборке нужно сделать только одну вещь.

Я также считаю, что предложение Карла Манастера является хорошим, но если бы вы использовали JUnit4, то у вас мог бы быть метод разрыва, который работает в суперклассе, не забывая вызывать super. Если вы не используете JUnit3 GUI, JUnit4 должен быть заменой. Единственное, что вам нужно, чтобы воспользоваться его новыми функциями, - это перенести весь тест, вы не можете жить в одном классе. Поэтому тесты, которые взаимодействуют с этими синглетонами, необходимо переносить по одному целому классу тестов за раз.

0 голосов
/ 14 мая 2009

Я не думаю, что это хороший подход. System.gc() не гарантирует полной очистки любых неиспользуемых объектов, как вы думаете.

Если ваша корневая проблема заключается в том, что у вас есть модульные тесты, которые в конечном итоге используют глобальные данные (синглеты) без надлежащей очистки их, вам следует атаковать корневую проблему: эти модульные тесты. Не должно быть слишком сложно найти все тесты, которые не используют tearDown(), или найти все тесты, которые используют определенный синглтон.

0 голосов
/ 14 мая 2009

Просто мысль: если у вас есть два пустых теста, запускаемых сразу друг за другом, у второго не должно быть другой памяти, используемой после teardown (). Если это произойдет, у вас (вероятно) есть утечка где-то в вашей системе setup () / teardown ().

...