我需要在当前应用上收集一些数据,以便通过检查活动启动期间的平均经过时间来分析性能速度。我想运行一个测试电池,活动开始10,100,1000和5000次。对于每个测试,它应保持打开至少10秒(收集异步发生的所有数据所需的时间)。我想要的就是这种行为,而不必编写这么多方法:
type A struct {
X string
Y int
Z *A
}
答案 0 :(得分:2)
借助@Be_negative评论,this博文和this回答,我能够使用以下代码解决问题:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class TestStreamLoadingPerformance {
@Rule
public ActivityTestRule mActivityRule = new ActivityTestRule(HomepageActivity.class, false, false);
@Rule
public RepeatRule mRepeatRule = new RepeatRule();
@After
public void tearDown() {
closeActivity();
}
private void closeActivity() {
final int N = 10;
try {
for (int i = 0; i < N; i++) {
Espresso.pressBack();
}
} catch (NoActivityResumedException e) {
Log.e(TestStreamLoadingPerformance.class.getSimpleName(), "Unable to close activities", e);
}
}
@Test
@RepeatRule.Repeat(times = 10)
public void collectData() {
mActivityRule.launchActivity(null);
}
}
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class RepeatRule implements TestRule {
@Retention(RetentionPolicy.RUNTIME)
@Target({
java.lang.annotation.ElementType.METHOD
})
public @interface Repeat {
public abstract int times();
}
private static class RepeatStatement extends Statement {
private final int times;
private final Statement statement;
private RepeatStatement(int times, Statement statement) {
this.times = times;
this.statement = statement;
}
@Override
public void evaluate() throws Throwable {
for (int i = 0; i < times; 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.times();
result = new RepeatStatement(times, statement);
}
return result;
}
}
答案 1 :(得分:2)
最简单(至少需要新代码的数量)方法是将测试作为参数化测试运行(使用@RunWith(Parameterized.class)进行注释并添加一个方法以提供10个空参数)。这样,框架将运行测试10次。
这个测试需要是课堂上唯一的测试,或者更好的是所有的测试方法都需要在课堂上运行10次。
以下是一个例子:
@RunWith(Parameterized.class)
public class RunTenTimes {
@Parameterized.Parameters
public static List<Object[]> data() {
return Arrays.asList(new Object[10][0]);
}
public RunTenTimes() {
}
@Test
public void runsTenTimes() {
System.out.println("run");
}
}
通过上述内容,甚至可以使用无参数构造函数来完成它,但我不确定框架作者是否打算这样做,或者将来是否会破坏。
如果您正在实施自己的跑步者,那么您可以让跑步者进行10次测试。如果您正在使用第三方运行程序,那么使用4.7,您可以使用新的@Rule注释并实现MethodRule接口,以便它获取语句并在for循环中执行10次。这种方法目前的缺点是@Before和@After只运行一次。这可能会在JUnit的下一个版本中发生变化(@Before将在@Rule之后运行),但是无论你是在同一个对象实例上行动(参数化运行器都不是这样)。这假设您正在运行该类的任何跑步者正确识别@Rule注释。只有当它委托给JUnit跑步者时才会这样。
如果你使用的是不能识别@Rule注释的自定义运行器,那么你真的不得不编写自己的运行器,它适当地委托给Runner并运行它10次。
请注意,还有其他方法可以解决此问题(例如Theories runner),但它们都需要跑步者。不幸的是,JUnit目前不支持跑步者层。这是一个连锁其他选手的跑步者。
答案 2 :(得分:0)
我遇到了一个非常相似的问题,因此,我创建了一个库来多次运行Android UI测试。在您的情况下可能有用:https://github.com/stepstone-tech/AndroidTestXRunner