运行 espresso 测试多次
Run espresso test multiple times
有时我的应用程序会遇到罕见的错误。但我无法复制它,因为它非常罕见。所以,我决定写一个简单的浓缩咖啡测试:
@RunWith(AndroidJUnit4::class)
@LargeTest
class MainActivityTest {
val password = "1234"
@Rule @JvmField
var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)
@Test
fun checkNotesListNotEmpty() {
onView(withId(R.id.password_edit_text)).perform(typeText(password))
onView(withId(R.id.notes_recycler_view)).check { view, noMatchingViewException ->
if (noMatchingViewException != null) throw noMatchingViewException
assertThat((view as RecyclerView).adapter.itemCount, Matchers.`is`(1))
}
}
}
如何循环此测试并在匹配失败时停止它?
使用@Repeat
注释:
@RunWith(AndroidJUnit4.class)
public class MyTest {
@Rule
public RepeatRule repeatRule = new RepeatRule();
@Test
@Repeat(100)
fun checkNotesListNotEmpty() {
}
但是你必须自己实现:
Repeat.java:
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target({ METHOD, ANNOTATION_TYPE })
public @interface Repeat {
int value() default 1;
}
RepeatRule.java:
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class RepeatRule implements TestRule {
private static class RepeatStatement extends Statement {
private final Statement statement;
private final int repeat;
public RepeatStatement(Statement statement, int repeat) {
this.statement = statement;
this.repeat = repeat;
}
@Override
public void evaluate() throws Throwable {
for (int i = 0; i < repeat; i++) {
statement.evaluate();
}
}
}
@Override
public Statement apply(Statement statement, Description description) {
Statement result = statement;
Repeat repeat = description.getAnnotation(Repeat.class);
if (repeat != null) {
int times = repeat.value();
result = new RepeatStatement(statement, times);
}
return result;
}
}
你不能有一个单独的测试来循环那个吗? (如果是独一无二的情况):
@RunWith(AndroidJUnit4::class)
@LargeTest
class MainActivityTest {
...
@Test fun checkNotesListNotEmpty() {...}
@Test fun loopCheckNotesListNotEmpty() {
while(true)
checkNotesListNotEmpty()
}
}
@mklimek 在 Kotlin 中提出的解决方案。
使用方法:
@Rule @JvmField
var repeatRule: RepeatRule = RepeatRule()
@Test
@RepeatTest(100)
fun checkNotesListNotEmpty() {
RepeatRule.kt
class RepeatRule : TestRule {
private class RepeatStatement(private val statement: Statement, private val repeat: Int) : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
for (i in 0 until repeat) {
statement.evaluate()
}
}
}
override fun apply(statement: Statement, description: Description): Statement {
var result = statement
val repeat = description.getAnnotation(RepeatTest::class.java)
if (repeat != null) {
val times = repeat.value
result = RepeatStatement(statement, times)
}
return result
}
}
RepeatTest.kt
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS)
annotation class RepeatTest(val value: Int = 1)
Android Studio 允许您 运行 测试 N 次或 运行 直到失败。单击 "Edit configurations" 作为您的测试规则并搜索 "Repeat:" 设置。
我遇到了同样的问题,因此我创建了一个库来 运行 多次测试:https://github.com/stepstone-tech/AndroidTestXRunner
一旦你运行它,你可以检查测试结果是否有任何失败。
有时我的应用程序会遇到罕见的错误。但我无法复制它,因为它非常罕见。所以,我决定写一个简单的浓缩咖啡测试:
@RunWith(AndroidJUnit4::class)
@LargeTest
class MainActivityTest {
val password = "1234"
@Rule @JvmField
var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)
@Test
fun checkNotesListNotEmpty() {
onView(withId(R.id.password_edit_text)).perform(typeText(password))
onView(withId(R.id.notes_recycler_view)).check { view, noMatchingViewException ->
if (noMatchingViewException != null) throw noMatchingViewException
assertThat((view as RecyclerView).adapter.itemCount, Matchers.`is`(1))
}
}
}
如何循环此测试并在匹配失败时停止它?
使用@Repeat
注释:
@RunWith(AndroidJUnit4.class)
public class MyTest {
@Rule
public RepeatRule repeatRule = new RepeatRule();
@Test
@Repeat(100)
fun checkNotesListNotEmpty() {
}
但是你必须自己实现:
Repeat.java:
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target({ METHOD, ANNOTATION_TYPE })
public @interface Repeat {
int value() default 1;
}
RepeatRule.java:
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class RepeatRule implements TestRule {
private static class RepeatStatement extends Statement {
private final Statement statement;
private final int repeat;
public RepeatStatement(Statement statement, int repeat) {
this.statement = statement;
this.repeat = repeat;
}
@Override
public void evaluate() throws Throwable {
for (int i = 0; i < repeat; i++) {
statement.evaluate();
}
}
}
@Override
public Statement apply(Statement statement, Description description) {
Statement result = statement;
Repeat repeat = description.getAnnotation(Repeat.class);
if (repeat != null) {
int times = repeat.value();
result = new RepeatStatement(statement, times);
}
return result;
}
}
你不能有一个单独的测试来循环那个吗? (如果是独一无二的情况):
@RunWith(AndroidJUnit4::class)
@LargeTest
class MainActivityTest {
...
@Test fun checkNotesListNotEmpty() {...}
@Test fun loopCheckNotesListNotEmpty() {
while(true)
checkNotesListNotEmpty()
}
}
@mklimek 在 Kotlin 中提出的解决方案。
使用方法:
@Rule @JvmField
var repeatRule: RepeatRule = RepeatRule()
@Test
@RepeatTest(100)
fun checkNotesListNotEmpty() {
RepeatRule.kt
class RepeatRule : TestRule {
private class RepeatStatement(private val statement: Statement, private val repeat: Int) : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
for (i in 0 until repeat) {
statement.evaluate()
}
}
}
override fun apply(statement: Statement, description: Description): Statement {
var result = statement
val repeat = description.getAnnotation(RepeatTest::class.java)
if (repeat != null) {
val times = repeat.value
result = RepeatStatement(statement, times)
}
return result
}
}
RepeatTest.kt
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS)
annotation class RepeatTest(val value: Int = 1)
Android Studio 允许您 运行 测试 N 次或 运行 直到失败。单击 "Edit configurations" 作为您的测试规则并搜索 "Repeat:" 设置。
我遇到了同样的问题,因此我创建了一个库来 运行 多次测试:https://github.com/stepstone-tech/AndroidTestXRunner
一旦你运行它,你可以检查测试结果是否有任何失败。