如何反复运行单元测试+浓咖啡?
我需要收集我当前的应用程序的一些数据,以便通过检查活动启动期间的平均经过时间来分析性能速度。我想运行一个测试电池,活动开始10,100,1000和5000次。对于每个测试,它应该保持打开至少10秒(收集异步发生的所有数据所需的时间)。我想正是这种行为,而无需编写这些方法很多:如何反复运行单元测试+浓咖啡?
@RunWith(AndroidJUnit4.class)
@LargeTest
public class TestStreamLoadingPerformance {
private static final long TIME_OUT = 2;
private static final long WAITING_TIME = 10000;
@Rule
public ActivityTestRule mActivityRule = new ActivityTestRule(HomepageActivity.class);
private ElapsedTimeIdlingResource mIdleRes = new ElapsedTimeIdlingResource(WAITING_TIME);
@Before
public void setUp() {
IdlingPolicies.setMasterPolicyTimeout(TIME_OUT, TimeUnit.HOURS);
IdlingPolicies.setIdlingResourceTimeout(TIME_OUT, TimeUnit.HOURS);
Espresso.registerIdlingResources(mIdleRes);
}
@After
public void tearDown() {
Espresso.unregisterIdlingResources(mIdleRes);
}
@Test
public void test01() {
}
@Test
public void test02() {
}
@Test
public void test03() {
}
@Test
public void test04() {
}
@Test
public void test05() {
}
@Test
public void test06() {
}
@Test
public void test07() {
}
@Test
public void test08() {
}
@Test
public void test09() {
}
}
随着@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;
}
}
我想知道,如果不是按回来,你可以做'mActivityRule.getActivity()。finish()' –
不,我测试过了,这不起作用 –
要做到这一点,最简单的方法就是将测试作为参数化测试运行(用@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注释,那么您确实需要编写自己的运行程序,该运行程序正确地委派给该运行程序并运行它10次。
请注意,还有其他方法可能可以解决此问题(如Theories跑步者),但他们都需要跑步者。不幸的是,JUnit目前不支持多层跑步者。这是一个与其他跑步者联系在一起的跑步者。
http://*.com/q/1492856/4879701包含少数关于如何多次运行相同的junit测试的解决方案。 –
我确实尝试了其中的大部分,但都失败了:当它试图重复测试时,它无法启动意图,并因超时而失败。这是Espresso生命周期的某种方式。 –
啊,这可能是因为测试规则。只需向launchActivity()提供false布尔值并从测试中手动启动 –