답변:
사용 @BeforeClass
이 고전적인 솔루션 이라는 @assylias에 동의하지만 항상 편리한 것은 아닙니다. 주석이 달린 메서드 @BeforeClass
는 정적이어야합니다. 테스트 케이스의 인스턴스가 필요한 일부 테스트의 경우 매우 불편합니다. 예를 들어 @Autowired
스프링 컨텍스트에 정의 된 서비스와 함께 작동 하는 데 사용 하는 스프링 기반 테스트입니다 .
이 경우 개인적 setUp()
으로 @Before
주석이 달린 일반 메서드를 사용 하고 사용자 지정 static
(!) boolean
플래그를 관리합니다 .
private static boolean setUpIsDone = false;
.....
@Before
public void setUp() {
if (setUpIsDone) {
return;
}
// do the setup
setUpIsDone = true;
}
setUp()
메서드가 수퍼 클래스 에있는 경우를 제외하고 작동 합니다.이 문제를 해결하기 위해 아래 에 답변 을 게시했습니다 .
당신은 사용할 수 있습니다 주석 :BeforeClass
@BeforeClass
public static void setUpClass() {
//executed only once, before the first test
}
TheClassYouWant.class
getClass () 호출 대신 사용할 수 없습니까? 이것은 실제 Java : String.class.getName()
.
JUnit 5에는 이제 @BeforeAll 주석이 있습니다.
주석이 달린 메서드가 현재 클래스 또는 클래스 계층 구조의 모든 @Test 메서드보다 먼저 실행되어야 함을 나타냅니다. JUnit 4의 @BeforeClass와 유사합니다. 이러한 메서드는 정적이어야합니다.
JUnit 5의 라이프 사이클 주석이 마침내 제대로 된 것 같습니다! 보지 않고도 사용할 수있는 주석을 추측 할 수 있습니다 (예 : @BeforeEach @AfterAll).
@BeforeClass
가지고 있어야합니다 static
. IMO @AlexR의 솔루션이 더 좋습니다.
때 setUp()
테스트 클래스의 슈퍼 클래스에 (예를 들어, AbstractTestBase
다음과 같이 아래), 허용 대답을 수정할 수 있습니다 :
public abstract class AbstractTestBase {
private static Class<? extends AbstractTestBase> testClass;
.....
public void setUp() {
if (this.getClass().equals(testClass)) {
return;
}
// do the setup - once per concrete test class
.....
testClass = this.getClass();
}
}
이것은 하나의 비 정적 setUp()
방법에 대해 작동 하지만 tearDown()
복잡한 반사의 세계로 벗어나지 않고 는 동등한 것을 생산할 수 없습니다 ... 현상금은 할 수있는 사람을 가리 킵니다!
편집 : 디버깅하는 동안 모든 테스트 전에 클래스가 인스턴스화된다는 것을 알았습니다. @BeforeClass 주석이 여기에서 최고라고 생각합니다.
생성자에서도 설정할 수 있으며 테스트 클래스 는 결국 클래스 입니다 . 거의 모든 다른 방법에 주석이 달려 있기 때문에 이것이 나쁜 습관인지 확실하지 않지만 작동합니다. 다음과 같은 생성자를 만들 수 있습니다.
public UT () {
// initialize once here
}
@Test
// Some test here...
ctor는 정적이 아니기 때문에 테스트 전에 호출됩니다.
이 솔루션을 사용해보십시오 : https://stackoverflow.com/a/46274919/907576 :
와 @BeforeAllMethods
/ @AfterAllMethods
주석 모든 주입 값을 사용할 수있는 인스턴스 환경에서 테스트 클래스의 모든 방법을 실행할 수 있습니다.
내 더러운 해결책은 다음과 같습니다.
public class TestCaseExtended extends TestCase {
private boolean isInitialized = false;
private int serId;
@Override
public void setUp() throws Exception {
super.setUp();
if(!isInitialized) {
loadSaveNewSerId();
emptyTestResultsDirectory();
isInitialized = true;
}
}
...
}
모든 testCases의 기본 기반으로 사용합니다.
각 하위 테스트에서 설정되고 확인 된 변수의 선언을 강제하지 않으려면이를 SuperTest에 추가하면됩니다.
public abstract class SuperTest {
private static final ConcurrentHashMap<Class, Boolean> INITIALIZED = new ConcurrentHashMap<>();
protected final boolean initialized() {
final boolean[] absent = {false};
INITIALIZED.computeIfAbsent(this.getClass(), (klass)-> {
return absent[0] = true;
});
return !absent[0];
}
}
public class SubTest extends SuperTest {
@Before
public void before() {
if ( super.initialized() ) return;
... magic ...
}
}
이 문제를 다음과 같이 해결했습니다.
당신에 추가 자료 추상 클래스 (당신이 드라이버를 초기화 I 평균 추상 클래스 setUpDriver () 코드의이 부분 방법) :
private static boolean started = false;
static{
if (!started) {
started = true;
try {
setUpDriver(); //method where you initialize your driver
} catch (MalformedURLException e) {
}
}
}
이제 테스트 클래스가 기본 추상 클래스 에서 확장되는 경우 -> setUpDriver () 메서드가 첫 번째 @Test 전에 실행될 때마다 한 번만 실행됩니다.
Spring의 @PostConstruct 메서드를 사용하여 모든 초기화 작업을 수행하고이 메서드는 @Test가 실행되기 전에 실행됩니다.