Kotlin과 새로운 ActivityTestRule : @Rule은 공개되어야합니다


264

Kotlin에서 내 Android 앱의 UI 테스트를 만들려고합니다. ActivityTestRule을 사용하는 새로운 시스템이기 때문에 제대로 작동하지 않습니다 : 올바르게 컴파일되고 런타임에 다음을 얻습니다.

java.lang.Exception: The @Rule 'mActivityRule' must be public.
    at org.junit.internal.runners.rules.RuleFieldValidator.addError(RuleFieldValidator.java:90)
    at org.junit.internal.runners.rules.RuleFieldValidator.validatePublic(RuleFieldValidator.java:67)
    at org.junit.internal.runners.rules.RuleFieldValidator.validateField(RuleFieldValidator.java:55)
    at org.junit.internal.runners.rules.RuleFieldValidator.validate(RuleFieldValidator.java:50)
    at org.junit.runners.BlockJUnit4ClassRunner.validateFields(BlockJUnit4ClassRunner.java:170)
    at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.ParentRunner.validate(ParentRunner.java:344)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:74)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55)
    at android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:38)
    at android.support.test.runner.AndroidJUnit4.<init>(AndroidJUnit4.java:36)
    at java.lang.reflect.Constructor.constructNative(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
    at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.buildAndroidRunner(AndroidAnnotatedBuilder.java:57)
    at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:45)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runner.Computer.getRunner(Computer.java:38)
    at org.junit.runner.Computer$1.runnerForClass(Computer.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:98)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:84)
    at org.junit.runners.Suite.<init>(Suite.java:79)
    at org.junit.runner.Computer.getSuite(Computer.java:26)
    at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:691)
    at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:654)
    at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:329)
    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:226)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)

다음은 mActivityRule을 선언 한 방법입니다.

RunWith(javaClass<AndroidJUnit4>())
LargeTest
public class RadisTest {

    Rule
    public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

   ...
}

이미 공개되었습니다 : /


3
현재 Kotlin은 부동산을 공개적으로 지원하는 필드를 만드는 것을 지원하지 않지만 우리는이를 위해 노력하고 있습니다
Andrey Breslav

이것을 추적하는 버그가 있습니까?
Geob-o-matic

답변:


316

JUnit은 테스트 클래스 필드 또는 getter 메소드를 통해 규칙을 제공 할 수 있습니다.

주석이 달린 것은 Kotlin에 있지만 JUnit이 인식하지 못하는 속성 입니다.

Kotlin에서 JUnit 규칙을 지정하는 가능한 방법은 다음과 같습니다.

주석이 달린 게터 방법을 통해

M13부터 주석 프로세서 는 주석 대상을 지원합니다 . 당신이 쓸 때

@Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

그러나 주석은 property기본적으로 대상을 사용합니다 (Java에는 표시되지 않음).

그러나 속성 getter에 주석을 달 수 있으며 이는 공용이며 따라서 규칙 getter에 대한 JUnit 요구 사항을 충족합니다.

@get:Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

또는 속성 대신 함수를 사용하여 규칙을 정의 할 수 있습니다 (와 동일한 결과를 수동으로 달성 @get:Rule).

주석이 달린 공개 필드를 통해

Kotlin 은 베타 후보 가 속성을 JVM의 필드에 결정적으로 컴파일 할 수 있도록 허용 하며,이 경우 주석과 수정자가 생성 된 필드에 적용됩니다. 이것은 @jkschneider의 답변에@JvmField 따라 Kotlin의 속성 주석을 사용하여 수행됩니다 .


참고 사항 : Rule주석에 @문자로 지원되는 유일한 주석 이므로 주석 앞에 문자 를 붙이고 곧 사라질 것이므로@publicField하십시오 .


그렇습니까? 여전히 오류가 발생하고 M14 (0.14.449)
Geob-o-matic에서

@publicField가 필요하지만 더 이상 사용되지 않으므로 IDE에서 제안한대로 lateinit를 시도했지만 lateinit는 변경 가능 (블로그의 기사는 그렇지 않습니다 ...)에만 적용될 수 있음을
나타냅니다.

1
내 답변을 업데이트했습니다.) lateinit val필드의 불변성을 완전히 강제하지 않았기 때문에 M14에서 제거되었습니다. [M14 릴리스 블로그 게시물] (blog.jetbrains.com/kotlin/2015/10/kotlin- m14-is-out /).
desseim

@get : annotation이란 무엇입니까? 또한 내 상황에서는 작동하지 않습니다.
aleksandrbel

252

Kotlin 1.0.0 이상에서는 다음과 같이 작동합니다.

@Rule @JvmField 
val mActivityRule = ActivityTestRule(MainActivity::class.java)

1
그리고 보푸라기 도구의 문제를 해결하여 대중이 규칙에 대한 자격을 갖추 었다고 불평했다.
Rob

예 \ @JvmField가 중요하거나 오히려 \ @get : Rule을 사용하십시오
Michał Ziobro

최종 필드에서만 작동합니다. 와 같은 규칙에는 작동하지 않습니다 var wireMockRule = WireMockRule(wireMockConfig().dynamicPort()).
Abhijit Sarkar


12

코 틀린 1.0.4 :

val mActivityRule: ...
    @Rule get

이것은 질문에 대한 답변을 제공하지 않습니다. 평판 이 충분 하면 모든 게시물댓글 수 있습니다 . 대신 asker의 설명이 필요없는 답변을 제공하십시오 . - 리뷰에서
Jignesh Ansodariya

10
@JigneshAnsodariya-나는 확인을 했고이 답변은 요청 된 것에 대한 답변을 제공합니다. 이것이 작동하는 방법에 대한 자세한 내용은 다음 링크에서 찾을 수 있습니다 -kotlinlang.org/docs/reference/…
Praveer Gupta

이 방법에는 문제가 있습니다. 테스트중인 활동에 액세스하려는 경우 (예 : assertTrue (activityRule.activity.isFinishing)) getter 특성이 호출되어 새 규칙이 작성됩니다. 이 경우 activityRule.activity는 null입니다.
makovkastar

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.