JUnit4에서 특정 순서대로 테스트 방법을 실행하는 방법?
주석을 달은 테스트 방법을 실행하고자 한다.@Test
구체적인 순서로
예를 들면 다음과 같다.
public class MyTest {
@Test public void test1(){}
@Test public void test2(){}
}
나는 반드시 뛰기를 원한다.test1()
전에test2()
달릴 때마다MyTest
, 그러나 나는 다음과 같은 주석을 찾을 수 없었다.@Test(order=xx)
.
JUnit에게 꽤 중요한 기능인 것 같은데 JUnit의 작가가 주문 기능을 원하지 않는다면 왜 그럴까?
JUnit에게 꽤 중요한 기능인 것 같은데 JUnit의 작가가 주문 기능을 원하지 않는다면 왜 그럴까?
JUnit으로 이것을 할 수 있는 깨끗한 방법이 있는지 확실하지 않다. JUnit은 모든 테스트가 임의의 순서로 수행될 수 있다고 가정한다.FAQ:
테스트 고정장치는 어떻게 사용하는 방법
(...) 테스트 방법 호출의 순서가 보장되지 않으므로 testOneItemCollection()을 testPremyCollection() 전에 실행할 수 있다. (...)
그것은 왜 그럴까?글쎄, 나는 시험 순서를 좌우하는 것은 작가들이 홍보하고 싶어하지 않는 관행이라고 생각해.시험은 독립적이어야 하고, 결합되어서는 안 되며, 이를 어기면 유지하기가 더 어려워지고, 개별적으로 (확실히) 시험을 실행하는 능력이 깨질 것이다.
말하자면, 만약 당신이 정말로 이 방향으로 가고 싶다면, TestNG는 어떤 임의의 순서에 따라 (그리고 그 방법을 지정하는 것과 같은 것들은 방법의 그룹에 따라 달라진다) 테스트 방법을 지원하는 것이기 때문에 TestNG를 사용하는 것을 고려해보라.Cedric Beust는 테스트에서 테스트의 실행 순서로 이 작업을 수행하는 방법을 설명한다.
기존 Junit 인스턴스를 제거하고 빌드 경로에서 JUnit 4.11 이상을 다운로드하면 다음 코드가 오름차순으로 정렬된 이름의 순서대로 테스트 방법을 실행한다.
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
@Test
public void testAcreate() {
System.out.println("first");
}
@Test
public void testBupdate() {
System.out.println("second");
}
@Test
public void testCdelete() {
System.out.println("third");
}
}
TestNG로의 마이그레이션이 가장 좋은 방법인 것 같지만 jUnit에 대한 명확한 해결책은 보이지 않는다.jUnit에 대해 내가 찾은 가장 읽기 쉬운 솔루션/형식:
@FixMethodOrder( MethodSorters.NAME_ASCENDING ) // force name ordering
public class SampleTest {
@Test
void stage1_prepareAndTest(){};
@Test
void stage2_checkSomething(){};
@Test
void stage2_checkSomethingElse(){};
@Test
void stage3_thisDependsOnStage2(){};
@Test
void callTimeDoesntMatter(){}
}
이를 통해 1단계 이후와 3단계 이전에 2단계 방법을 호출할 수 있다.
P.S. 나는 이러한 접근방식이 junUnit 5.5 @주석을 주문하는 것이 독자에게 더 나은 표기법을 제공하기 때문에 더 낫다고 느낀다.
순서가 중요하다면 직접 순서를 정해야 한다.
@Test public void test1() { ... }
@Test public void test2() { test1(); ... }
특히 필요한 경우 테스트할 수 있는 일부 또는 모든 주문 순열을 나열해야 한다.
예를 들어,
void test1();
void test2();
void test3();
@Test
public void testOrder1() { test1(); test3(); }
@Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }
@Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }
또는 모든 순열의 전체 테스트:
@Test
public void testAllOrders() {
for (Object[] sample: permute(1, 2, 3)) {
for (Object index: sample) {
switch (((Integer) index).intValue()) {
case 1: test1(); break;
case 2: test2(); break;
case 3: test3(); break;
}
}
}
}
여기.permute()
배열의 집합으로 가능한 모든 순열을 반복하는 간단한 기능이다.
JUnit은 5.5가 허용하기 때문에@TestMethodOrder(OrderAnnotation.class)
수업 중에@Order(1)
시험 삼아
JUnit 이전 버전에서는 클래스 주석을 사용하여 테스트 방법을 실행할 수 있다.
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
@FixMethodOrder(MethodSorters.DEFAULT)
기본적으로 테스트 방법은 알파벳순으로 실행된다.따라서 특정 메서드 순서를 설정하려면 다음과 같이 이름을 지정하십시오.
a_TestWorkUnit_WithContactState_WithDoSomething b_TestWorkUnit_WithContinuity_WithContinuity_WithContinuity_WithContinuallyState_WithDoSomething
아니면
_1_TestWorkUnit_WithContactState_WithDoSomething _2_TestWorkUnit_WithContactState_WithContactState_WithContactState_WithSomethingDoSomething_3_TestWithDoSomethating
여기서 예를 찾아볼 수 있다.
내가 주니트를 작업할 때 직면했던 주요 이슈 중 하나인데, 나는 다음과 같은 해결책을 생각해냈다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> list = super.computeTestMethods();
List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
Collections.sort(copy, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod f1, FrameworkMethod f2) {
Order o1 = f1.getAnnotation(Order.class);
Order o2 = f2.getAnnotation(Order.class);
if (o1 == null || o2 == null) {
return -1;
}
return o1.order() - o2.order();
}
});
return copy;
}
}
또한 다음과 같은 인터페이스를 생성하십시오.
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface Order {
public int order();
}
이제 다음과 같은 몇 가지 테스트 사례를 작성한 클래스 A가 있다고 가정해 보십시오.
(@runWith=OrderRunner.class)
Class A{
@Test
@Order(order = 1)
void method(){
//do something
}
}
따라서 실행은 "method()"라는 이름의 방법에서 시작할 것이다.고마워!
JUnit 5 업데이트(및 내 의견)
JUnit에게 꽤 중요한 기능인 것 같은데 JUnit의 작가가 주문 기능을 원하지 않는다면 왜 그럴까?
기본적으로 단위 테스트 라이브러리는 소스 파일에서 발생하는 순서대로 테스트를 실행하려고 시도하지 않는다.
JUnit 5 as JUnit 4 는 그런 방식으로 작용한다. 왜?왜냐하면 순서가 문제가 된다면 그것은 일부 시험이 그들 사이에 결합되어 있고 그것은 단위 시험에 바람직하지 않다는 것을 의미하기 때문이다.
그래서 더@Nested
JUnit 5에 의해 도입된 특성은 동일한 기본 접근방식을 따른다.
그러나 통합시험의 경우 시험방법이 다른 시험방법에 의해 예상되는 방식으로 적용 상태를 변경할 수 있기 때문에 시험방법의 순서가 문제가 될 수 있다.
예를 들어 e-숍 체크아웃 처리를 위한 통합 테스트를 작성할 때 첫 번째 테스트 방법은 클라이언트를 등록하는 것이고, 두 번째 테스트 방법은 바구니에 항목을 추가하고 마지막 테스트는 체크아웃을 하는 것이다.만약 시험 주자가 그 순서를 존중하지 않는다면, 시험 시나리오는 결함이 있어서 실패할 것이다.
따라서 JUnit 5(5.4 버전부터)에서는 테스트 클래스에 주석을 달거나 순서를 지정하여 실행 순서를 설정할 수 있는 가능성이 모두 동일하다.@Order(numericOrderValue)
명령의 중요성에 대해 말이야
예를 들면 다음과 같다.
@TestMethodOrder(OrderAnnotation.class)
class FooTest {
@Order(3)
@Test
void checkoutOrder() {
System.out.println("checkoutOrder");
}
@Order(2)
@Test
void addItemsInBasket() {
System.out.println("addItemsInBasket");
}
@Order(1)
@Test
void createUserAndLogin() {
System.out.println("createUserAndLogin");
}
}
출력:
createUserAndLogin
AddItemsInBasket
체크아웃 순서
, 그 당시를 지만.@TestMethodOrder(OrderAnnotation.class)
필요 없어 보인다(적어도 내가 테스트한 5.4.0 버전에서는).
사이드노트
질문: JUnit 5가 통합 테스트를 작성하는 가장 좋은 선택인가?나는 그것이 (Cucumber and co가 종종 통합 시험을 위한 더 구체적인 가치와 특징을 가져올 수 있다) 첫번째 고려 도구가 되어야 한다고 생각하지 않지만, 일부 통합 시험의 경우 JUnit 프레임워크는 충분하다.그래서 그것은 그 특징이 존재한다는 좋은 소식이다.
(아직 발표되지 않은) 변경사항 https://github.com/junit-team/junit/pull/386은 다음과 같이 소개하고 있다.@SortMethodsWith
. https://github.com/junit-team/junit/pull/293은 그것 없이 적어도 주문을 예측할 수 있게 만들었다. (Java 7에서는 상당히 무작위적일 수 있다.)
JUnit 보고서를 보십시오.JUnit은 이미 패키지로 구성되어 있다.각 패키지는 TestSuite 클래스를 가지고 있으며(또는 가질 수 있음) 각 클래스는 차례로 여러 개의 TestCase를 실행한다.각 TestCase에는 양식의 여러 가지 테스트 방법이 있을 수 있음public void test*()
각각은 실제로 자신이 속한 TestCase 클래스의 인스턴스가 될 것이다.각 테스트 방법(TestCase 인스턴스)에는 이름과 합격/불합격 기준이 있다.
내 경영진에게 필요한 것은 각각의 합격/불합격 기준을 보고하는 개별 TestStep 항목의 개념이다.시험 단계가 실패하더라도 후속 시험 단계의 실행을 방해해서는 안 된다.
과거에 내 위치에 있는 테스트 개발자들은 테스트케이스 클래스를 테스트 대상 제품의 부품에 해당하는 패키지로 구성하고, 각 테스트에 대한 테스트케이스 클래스를 생성했으며, 각 테스트 방법을 JUnit 출력에 자체 합격/실패 기준과 함께 테스트에서 별도의 "단계"로 만들었다.각 TestCase는 독립형 "테스트"이지만, 개별 방법 또는 TestCase 내의 테스트 "단계"는 특정 순서로 발생해야 한다.
TestCase 방법은 TestCase의 단계였으며, 테스트 설계자는 테스트 단계별로 별도의 합격/불합격 기준을 얻었다.이제 시험 단계는 뒤죽박죽이고, 시험은 물론 실패한다.
예를 들면 다음과 같다.
Class testStateChanges extends TestCase
public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()
각 시험 방법은 별도의 합격/불합격 기준을 주장하고 보고한다.이를 주문하기 위해 "하나의 큰 테스트 방법"으로 축소하면 JUnit 요약 보고서의 각 "단계"에 대한 통과/실패 기준의 세분성을 잃게 되고, 이는 내 매니저들을 화나게 한다.그들은 현재 다른 대안을 요구하고 있다.
스크램블 테스트 방법을 주문하는 JUnit가 위에서 예시하고 내 경영진이 요구하는 바와 같이 각 순차 테스트 단계의 개별 합격/불합격 기준을 어떻게 지원하는지 설명할 수 있는 사람이 있는가?
설명서와 관계없이, 나는 이것이 많은 시험 개발자들의 삶을 어렵게 만드는 JUnit 프레임워크의 심각한 퇴보라고 본다.
동의할 수 없음. '파일 업로드'를 테스트한 다음 '파일 업로드에 의해 삽입된 데이터'를 테스트하려는 경우 이러한 데이터가 서로 독립적이지 않도록 하려면 어떻게 해야 하는가?완벽하게 합리적인 나는 골리앗 테스트 케이스에 둘 다 있기 보다는 따로따로 실행할 수 있다고 생각한다.
테스트 케이스를 스위트룸으로 실행할 때 당신이 원하는 것은 완벽하게 합리적이다.
유감스럽게도 지금 당장 완전한 해결책을 제시할 시간은 없지만, 수업 내용을 살펴보십시오.
org.junit.runners.Suite
특정 순서로 (모든 테스트 클래스에서) 테스트 케이스를 호출할 수 있는 기능.
이것들은 기능, 통합 또는 시스템 시험을 만드는 데 사용될 수 있다.
이렇게 하면 장치 테스트는 특정 순서(권장 사항) 없이 그대로 유지되며, 그렇게 실행하든 그렇지 않든 간에 더 큰 그림의 일부로 테스트를 다시 사용할 수 있다.
우리는 유닛, 통합 및 시스템 테스트에 대해 동일한 코드를 재사용/상속하며, 때로는 데이터 기반, 때로는 커밋 기반, 때로는 스위트룸으로 실행한다.
여기에서 내 솔루션을 참조하십시오: "Junit and Java 7."
이 글에서 나는 "당신의 소스 코드에서와 같이" 정품 검사를 순서대로 실행하는 방법에 대해 설명한다.테스트 방법이 클래스 파일에 나타나는 순서대로 테스트가 실행될 것이다.
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
그러나 파스칼 티벤트가 말했듯이, 이것은 좋은 관행이 아니다.
JUnit 5.4에서는 순서를 지정할 수 있다.
@Test
@Order(2)
public void sendEmailTestGmail() throws MessagingException {
너는 단지 너의 수업에 주석을 달기만 하면 된다.
@TestMethodOrder(OrderAnnotation.class)
https://junit.org/junit5/docs/current/user-guide/#writing-writing-test-rescript-order
나는 이것을 내 프로젝트에 사용하고 있고 그것은 매우 잘 작동한다!
다음 코드 중 하나를 사용하십시오.@FixMethodOrder(MethodSorters.JVM)
OR@FixMethodOrder(MethodSorters.DEFAULT)
OR@FixMethodOrder(MethodSorters.NAME_ASCENDING)
이렇게 시험 수업하기 전에:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BookTest {...}
다른 사람들이 말했듯이, 시험은 이상적으로 실행 순서와 독립적이어야 한다.이는 테스트를 덜 취약하게 하고, 독립적으로 실행할 수 있게 한다(많은 IDE는 다른 테스트와 독립적으로 테스트 방법을 선택하고 실행할 수 있게 한다).
말하자면 통합 시험의 경우 일부 사람들은 방법 순서에 의존하는 것을 선호한다.
JUnit 4.13부터 를 확장하여 테스트를 다시 정렬할 수 있는 자신의 클래스를 정의할 수 있다.자세한 내용은 JUnit wiki를 참조하십시오.기본 제공 기능을 사용한 예Alphanumeric
클래스: 테스트 방법 이름을 사용하여 영숫자로 테스트 순서 지정:
import org.junit.Test;
import org.junit.runner.OrderWith;
import org.junit.runner.manipulation.Alphanumeric;
@OrderWith(Alphanumeric.class)
public class TestMethodOrder {
@Test
public void testA() {
System.out.println("first");
}
@Test
public void testB() {
System.out.println("second");
}
@Test
public void testC() {
System.out.println("third");
}
}
주니트5로 옮길 시간이다.여기 우리가 얻을 수 있는 샘플이 있다.
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderedTests {
@Test
@Order(1)
void nullValues() {}
@Test
@Order(2)
void emptyValues() {}
@Test
@Order(3)
void validValues() {}
}
Junit4의 경우 여러 테스트에서 가지고 있는 논리를 하나의 테스트 방법으로 복사하십시오.
JUnit 4의 경우, 이 주석을 시험 클래스에 올려놓으면 문제가 해결되었다.
@FixMethodOrder(MethodSorters.JVM)
JUnit 4 업데이트
JUnit 4.13을 으로.@OrderWith
5 , JUnit 5를 재현할 수 있다를 할 수 @Order
주석을 달다이 솔루션은 보다 JUnit 4와 더 잘 통합된다.@RunWith
관습BlockJUnit4ClassRunner
실행
메서드 이름 순서를 대체할 수 있는 방법은 다음과 같다.@FixMethodOrder(MethodSorters.NAME_ASCENDING)
주석에 의한 순서 포함.
@OrderWith(OrderAnnotation.class)
public class MyTest {
@Test
@Order(-1)
public void runBeforeNotAnnotatedTests() {}
@Test
public void notAnnotatedTestHasPriority0() {}
@Test
@Order(1)
public void thisTestHasPriority1() {}
@Test
@Order(2)
public void thisTestHasPriority2() {}
}
/**
* JUnit 4 equivalent of JUnit 5's {@code org.junit.jupiter.api.Order}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Order {
/**
* Default order value for elements not explicitly annotated with {@code @Order}.
*
* @see Order#value
*/
int DEFAULT = 0;
/**
* The order value for the annotated element.
* <p>Elements are ordered based on priority where a lower value has greater
* priority than a higher value. For example, {@link Integer#MAX_VALUE} has
* the lowest priority.
*
* @see #DEFAULT
*/
int value();
}
import org.junit.runner.Description;
import org.junit.runner.manipulation.Ordering;
import org.junit.runner.manipulation.Sorter;
/**
* Order test methods by their {@link Order} annotation. The lower value has the highest priority.
* The tests that are not annotated get the default value {@link Order#DEFAULT}.
*/
public class OrderAnnotation extends Sorter implements Ordering.Factory {
public OrderAnnotation() {
super(COMPARATOR);
}
@Override
public Ordering create(Context context) {
return this;
}
private static final Comparator<Description> COMPARATOR = Comparator.comparingInt(
description -> Optional.ofNullable(description.getAnnotation(Order.class))
.map(Order::value)
.orElse(Order.DEFAULT));
}
주석을 달지 않은 테스트는 기본 우선순위가 0이 된다.같은 우선순위를 가진 시험의 순서는 정해지지 않았다.
요지: https://gist.github.com/jcarsique/df98e0bad9e88e8258c4ab34dad3c863
다음에서 영감을 얻음:
나는 몇 개의 답안을 읽었고 그것의 최선의 연습이 아니라 당신의 테스트를 명령하는 가장 쉬운 방법이라는 것에 동의한다. 그리고 JUnit이 기본적으로 시험을 실행하는 방법은 알파벳 이름 오름차순이다.
그러니 원하는 알파벳 순서로 시험의 이름을 대세요.또한 테스트 이름은 단어 테스트로 시작해야 한다.숫자만 조심해.
테스트 12가 테스트 전에 실행됨2
그래서:
testA_MyFirstTest TestC_3차 테스트B_ATestThRunsSecond
https://github.com/TransparentMarket/junit에서 확인하십시오.지정된 순서대로 테스트를 실행한다(컴파일된 클래스 파일에 정의됨).또한 하위 패키지에 의해 정의된 테스트를 먼저 실행할 수 있는 AllTests 제품군을 갖추고 있다.AllTests 구현을 사용하면 속성 필터링에서도 솔루션을 확장할 수 있다(이전에는 @Fast 주석을 사용했지만 아직 게시되지 않음).
다음은 원하는 동작을 만들 수 있는 JUnit에 대한 확장이다. https://github.com/aafuks/aaf-junit
JUnit 철학의 저자들에게 불리하다는 것을 알고 있지만, 엄격한 단위 테스트가 아닌 환경에서 JUnit를 사용할 경우(자바에서 실행된 바와 같이) 이것은 매우 도움이 될 수 있다.
나는 결국 내 시험이 순서대로 진행되지 않았다고 생각했지만, 사실은 내 비동기적인 일에 엉망진창이 되어 있었다.동시성으로 작업할 때는 시험 간 동시성 검사도 수행해야 한다.나의 경우 직무와 시험은 세마포어를 공유하기 때문에 다음 시험은 실행 중인 직무가 잠금을 해제할 때까지 계속된다.
이 질문이 이 문제와 완전히 관련이 있는 것은 아니지만, 올바른 문제를 공략하는 데 도움이 될 수 있을 것이다.
JUnit 5에서 특정 순서로 테스트 방법을 실행하려면 아래 코드를 사용하십시오.
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MyClassTest {
@Test
@Order(1)
public void test1() {}
@Test
@Order(2)
public void test2() {}
}
참조URL: https://stackoverflow.com/questions/3693626/how-to-run-test-methods-in-specific-order-in-junit4
'programing' 카테고리의 다른 글
VueJS - v-bind:스타일 + 호버 (0) | 2022.05.10 |
---|---|
NuxtJS에서 인증된 Axios 글로벌 구성 - VueJs (0) | 2022.05.10 |
Vuejs 2.3 - 동기화 및 요소 Ui 대화상자 (0) | 2022.05.10 |
Eclipse for Java 텍스트 편집기에서 글꼴 크기를 변경하는 방법 (0) | 2022.05.10 |
Vuex - 저장소 항목을 두 번 변환하거나, 새 항목을 커밋하거나, 구성 요소의 변환을 마운트할 때마다 수행하시겠습니까? (0) | 2022.05.10 |