setUp / tearDown (@Before / @After) зачем они нам нужны в JUnit?
Я считаю, что мы все знаем, что setUp (@Before) будет выполняться до любого метода тестирования и tearDown(@After) будет выполняться после метода тестирования.
также мы знаем, что Junit создаст один экземпляр Test в методе испытания.
мой вопрос в том, что мы можем просто переместить содержимое метода установки в конструктор класса и удалить метод установки? есть ли какая-то конкретная причина, чтобы сохранить метод установки?
6 ответов:
этот (старый) лучшие практики JUnit статья ставит его так:
не используйте конструктор тестового набора для настройки тестового набора
настройка тестового случая в конструктор-это не очень хорошая идея. Рассмотрим:
public class SomeTest extends TestCase public SomeTest (String testName) { super (testName); // Perform test set-up } }представьте себе, что при выполнении установки код установки выдает
IllegalStateException. В ответ, В JUnit будет броситьAssertionFailedError, указывая, что тестовый случай не может быть создать экземпляр. Вот пример результирующая трассировка стека:junit.framework.AssertionFailedError: Cannot instantiate test case: test1 at junit.framework.Assert.fail(Assert.java:143) at junit.framework.TestSuite.runTest(TestSuite.java:178) at junit.framework.TestCase.runBare(TestCase.java:129) at junit.framework.TestResult.protect(TestResult.java:100) at junit.framework.TestResult.runProtected(TestResult.java:117) at junit.framework.TestResult.run(TestResult.java:103) at junit.framework.TestCase.run(TestCase.java:120) at junit.framework.TestSuite.run(TestSuite.java, Compiled Code) at junit.ui.TestRunner2.run(TestRunner.java:429)эта трассировка стека доказывает скорее неинформативный; это только указывает на то, что тестовый случай не может быть создать экземпляр. Это не детализирует местоположение исходной ошибки или место происхождение. Этот недостаток информации делает трудно вывести исключение основная причина.
вместо настройки данных в конструктор, выполните установку теста мимо переопределение
setUp(). Любое исключение брошенный внутри это правильно. Сравните эту трассировку стека в предыдущем примере:java.lang.IllegalStateException: Oops at bp.DTC.setUp(DTC.java:34) at junit.framework.TestCase.runBare(TestCase.java:127) at junit.framework.TestResult.protect(TestResult.java:100) at junit.framework.TestResult.runProtected(TestResult.java:117) at junit.framework.TestResult.run(TestResult.java:103) ...эта трассировка стека намного больше информативно; он показывает, какое исключение был брошен (
IllegalStateException) и откуда. Это делает его гораздо проще чтобы объяснить сбой тестовой установки.
на работе мы обнаружили кое-что довольно интересное, что отвечает на ваш вопрос. Когда вы запускаете набор тестов, особенно большой набор тестов (200+) JUnit начинает использовать много памяти, это связано с тем, что все тесты создаются перед запуском любого фактического метода тестирования.
мы столкнулись с "утечкой памяти" из-за этого, потому что мы использовали Spring для подключения в некоторых объектах JPA EntiryManager для наших тестов базы данных, это стало много объектов и много памяти и около половины пути через тесты мы получали исключения из памяти.
IMHO, лучше всего использовать setUp и tearDown, чтобы ввести ваши зависимости и обнулить все ссылки на классы, это заставит ваши тесты работать быстрее и сэкономит вам много головной боли!
надеюсь, вы узнаете из наших ошибок:)
вот 3 веские причины, почему. Вкратце:
некоторые ситуации могут предпочесть отложить настройку тестовых приборов как можно дольше, чтобы перед тест выполняет.
некоторые тестовые случаи могут быть частью глубокой иерархии наследования тестовых случаев. Возможно, предпочтительно отложить настройку тестовых приспособлений до завершения полной иерархии конструкторов.
вы получаете лучшую диагностику, если код установки не выполняется в setUp (), а не в конструкторе.
1. Отложите настройку светильников до непосредственно перед тестовым случаем
дизайн для удобства использования
http://www.artima.com/weblogs/viewpost.jsp?thread=70189... И как выразился Эллиот расти Гарольд, если вы собираетесь создать новый экземпляр TestCase для каждого метода тестирования, " какого черта беспокоиться о методе setUp ()?" вы можете просто используйте конструктор теста.
Я слышал, как Брюс Экель указал, что есть большая разница между созданием вашего устройства в setUp () и созданием его в конструкторе TestCase. Джунит создает все экземпляры TestCase спереди и затем для каждого экземпляра вызывается setup (), метод test и tearDown (). Другими словами,тонкое различие заключается в том, что конструкторы все вызываются в пакетном режиме фронт, тогда как метод setUp () вызывается непосредственно перед каждым методом тестирования. Но это, кажется, не так уж полезно разница на практике.
2. Отложите настройку светильников до тех пор, пока не будут созданы все тестовые случаи
экстремальное Программирование JAVA ETutorial - 4.6 настройка и разрыв Down
http://etutorials.org/Programming/Java+extreme+programming/Chapter+4.+JUnit/4.6+Set+Up+and+Tear+Down/вам может быть интересно, почему вы должны написать метод setUp () вместо простой инициализации полей в конструкторе тестового набора. В конце концов, поскольку новый экземпляр тестового набора создается для каждого из его методов тестирования, конструктор всегда вызывается перед setUp( ). В подавляющем большинстве случаев, вы можете использовать конструктор вместо Setup( ) без каких-либо побочных эффектов.
в тех случаях, когда ваш тестовый случай является частью более глубокого наследования иерархия, вы можете отложить инициализацию объекта до тех пор, пока экземпляры производных [тестовых] классов не будут полностью построены. Это хорошая техническая причина, по которой вы можете использовать setUp( ) вместо конструктора для инициализации. Использование setUp( ) и tearDown () - это также хорошо для целей документации, просто потому, что это может сделать код легче читать.
3. Лучшая диагностика в случае установки неудача
JUnit best practices (JavaWorld)
http://www.javaworld.com/jw-12-2000/jw-1221-junit.htmlнастройка тестового случая в конструкторе не является хорошей идеей. ...
представьте себе [в коде, где настройка выполняется в конструкторе тестового случая], что при выполнении установки код установки вызывает исключение IllegalStateException. В ответ JUnit бросит AssertionFailedError, указывая, что тестовый случай может не быть инстанцированным. ...
эта трассировка стека [исключения, вызванного в коде установки в конструкторе тестового набора], оказывается довольно неинформативной; это только указывает на то, что тестовый набор не может быть создан.
вместо настройки данных в конструкторе, выполните настройку теста, переопределив setUp (). Любое исключение, вызванное в setUp (), сообщается правильно. ...
этот трассировка стека [исключения, вызванного в методе setUp () вместо конструктора тестового набора], гораздо более информативна; она показывает, какое исключение было вызвано (IllegalStateException) и откуда. Это значительно упрощает объяснение сбоя тестовой установки.
пользовательский бегун, такой как
SpringJUnit4ClassRunnerможет потребоваться выполнить некоторые коды между конструктором и@Beforeметод. В этом случае бегун может ввести некоторую зависимость, которая@Beforeметоды нужны. Но инъекция зависимостей может выполняться только после создания объекта.
причина, по которой вам это нужно, заключается в том, что для многих тестов вам часто нужно инициализировать состояние перед каждым тестом, чтобы все тесты могли делать предположения о начальном состоянии, в котором они работают.
предположим, что ваш тестовый класс обертывает, скажем, доступ к базе данных. После каждого теста вы хотите удалить все изменения, внесенные вашими тестами в БД - если вы этого не сделали, каждый тест выполняется с немного измененной базой данных. Кроме того, любой тест может увидеть другой набор изменений, если некоторые подмножества предыдущих тестов завершились неудачно. Например, предположим, что test1 выполняет вставку, test2 проверяет, что вы точно читаете размер таблицы. День 1, тест1 терпит неудачу, и 0 правильно. День 2, тест1 успешно, и 1 Правильно?
кстати, junit также поддерживает
@BeforeClassЕсли вы хотите сделать глобальную настройку, а настройка и демонтаж являются необязательными.
Я думаю, что по какой-то причине должно понравиться следующее:
- Если вы перемещаете @Before contents в конструктор, это нормально, но @After contents, где вы можете двигаться?
- различия конструктора и @Before / @After заключается в том, что конструктор должен использоваться для экземпляра некоторых для класса, @Before/@After-для подготовки ресурсов тестового случая.
Comments