source

Junit - 1회 실행 셋업 방법

factcode 2022. 9. 27. 23:47
반응형

Junit - 1회 실행 셋업 방법

를 사용하여 하고 있습니다.@Before모든 테스트 전에 한 번만 실행하는 셋업 방식을 원합니다.Junit 4.8 jun jun jun?

@assylias를 은 @하지만,@BeforeClass고전적인 솔루션이지만 항상 편리한 것은 아닙니다.이 메서드는 다음과 같이 주석을 달았다.@BeforeClass정적이어야 합니다.테스트 케이스 인스턴스가 필요한 일부 테스트에서는 매우 불편합니다.를 들어, 으로 한 에서는 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철, 봄철,@Autowired스프링 컨텍스트에서 정의된 서비스를 사용할 수 있습니다.

저는 으로 일반을 합니다.setUp()「」라고 하는 코멘트가 .@Before을 커스텀을 합니다.static(!)boolean 삭제:

private static boolean setUpIsDone = false;
.....
@Before
public void setUp() {
    if (setUpIsDone) {
        return;
    }
    // do the setup
    setUpIsDone = true;
}

주석을 사용할 수 있습니다.

@BeforeClass
public static void setUpClass() {
    //executed only once, before the first test
}

JUnit 5에 @BeforeAll 주석이 추가되었습니다.

주석이 달린 메서드가 현재 클래스 또는 클래스 계층의 모든 @Test 메서드보다 먼저 실행되어야 함을 나타냅니다. JUnit 4의 @BeforeClass와 유사합니다.이러한 메서드는 정적이어야 합니다.

JUnit 5의 라이프 사이클 주석이 드디어 제대로 된 것 같습니다!어떤 주석을 사용할 수 있는지 알 수 있습니다(예: @BeforeEach @AfterAll).

setUp() "Superclass")에 속해 있습니다.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는 정적이지 않기 때문에 테스트 전에 호출됩니다.

5 5 @BeforeAll로 을 붙일 수 .@TestInstance(Lifecycle.PER_CLASS).

Spring의 @PostConstruct 메서드를 사용하여 모든 초기화 작업을 수행합니다.이 메서드는 @Test가 실행되기 전에 실행됩니다.

다음 솔루션을 사용해 보십시오.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;
        }
    }

   ...

}

모든 test Case의 베이스로 사용합니다.

각 하위 테스트에서 설정 및 체크된 변수를 강제로 선언하지 않으려면 이를 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 ... 
    }

}

저는 이 문제를 다음과 같이 해결했습니다.

기본 추상 클래스(즉, setUpDriver() 메서드에서 드라이버를 초기화하는 추상 클래스)에 코드의 다음 부분을 추가합니다.

private static boolean started = false;
static{
    if (!started) {
        started = true;
        try {
            setUpDriver();  //method where you initialize your driver
        } catch (MalformedURLException e) {
        }
    }
}

테스트 클래스가 Base Abstract class -> setUpDriver() 메서드에서 확장되는 경우 첫 번째 @Test 실행 전에 실행됩니다.

다음은 대체 제안 1가지입니다.

이 작업을 수행하려면 _warmup 또는 just_라는 이름의 메서드를 만들고 @FixMethodOrder(MethodSorters)를 사용하여 테스트 클래스에 주석을 추가합니다.이름_ASCENDING)

이는 클래스의 모든 테스트를 실행하는 경우에만 해당됩니다.

단점은 추가 테스트가 포함되어 있기 때문에 @Before와 @Accending도 1개 더 실행됩니다.일반적으로 테스트 방법에 대해서는 순서 독립이 권장됩니다만, 다른 사람이 테스트 순서를 랜덤으로 지정하려고 하는 이유는 알 수 없습니다.그렇기 때문에 NAME_ASCANDING은 항상 사용하고 있습니다.

단, 이 문제의 단점은 최소한의 코드로 심플한 셋업으로 클래스/런너 등을 확장할 필요가 없다는 것입니다.모든 설정 시간이 방법 _warmup에 보고되므로 테스트 실행 길이가 더 정확합니다.

한동안 실험해 본 결과 이것이 저의 해결책입니다.이게 스프링 부츠 테스트에 필요했어요.@PostConstructure를 사용해 보았습니다만, 유감스럽게도 모든 테스트에 대해 실행됩니다.

public class TestClass {
    private static TestClass testClass = null;
    @Before
    public void setUp() {
        if (testClass == null) {
            // set up once
            ...
            testClass = this;
        }
    }
    @AfterClass
    public static void cleanUpAfterAll() {
        testClass.cleanUpAfterAllTests();
    }
    private void cleanUpAfterAllTests() {
        // final cleanup after all tests
        ...
    }
    @Test
    public void test1() {
        // test 1
        ...
    }
    @Test
    public void test2() {
        // test 2
        ...
    }
}

@BeforeClass그렇기 의지하고 @Autowired데이터를 제공하는 컨스트럭터는 단순히 작동하지 않습니다. 잘못된 실행 순서입니다.

로, 하 similarly similarly@PostConstruct이치노 컨스트럭터는 oror every and with ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」@Test따라서 이 기능을 사용하면 모든 테스트에서 셋업 기능이 실행됩니다.이는 생성자에서 함수를 호출하는 것과 동일한 효과를 가집니다.

제가 찾은 유일한 해결책은 플래그를 사용하여 이 플래그를 사용하는 것입니다.setUp()메서드가 이미 실행되었습니다.이상적이지는 않지만 각 테스트 전 처리량을 대폭 줄일 수 있습니다.

private static boolean initialized = false;    

@Autowired
public CacheTest( MyBean myBean ){

    this.myBean = myBean;
}


@PostConstruct
public static void setUp(){

    if( initialized ) { return };

    initialized = true;
    
    //do suff with myBean
}

언급URL : https://stackoverflow.com/questions/12087959/junit-run-set-up-method-once

반응형