2009-05-14 1 views
1

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

ответ

0

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

+0

Разве сумма кучи не увеличивалась бы где-то между тестовыми прогонами - так как junit теперь должен записывать дополнительный TestResult? –

+0

До тех пор, пока не запускается сбор мусора, память, используемая при первом запуске теста, не восстанавливается. – Mnementh

0

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

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

+0

Нетрудно найти их. Их десятки тысяч. Большинство из них вызывает Singleton.getInstance(). Reset() или что-то впоследствии смягчает проблему. Вероятно, есть несколько тестов, которых нет, и их очень сложно найти. –

+1

Время, чтобы избавиться от всех синглтонов тогда :) –

+0

Я согласен в теории, но потребовались годы. Это десятимиллиметровая база кода, и очень сложно реорганизовать синглтоны в небольших кусках. –

2

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

0

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

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

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

1

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

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

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

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

Edit: Wierd, но, как я просматривал этот ответ, я получил телефонный звонок от Embarcadero, который, по-видимому купленного Optimizeit, сделал некоторые обновления и теперь маркетинг под названием J Optimizer.

0

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