本文翻译自:构建Instrumented单元测试
水平有限自己感觉很多地方表达的并不到位,但找不到更好的表达方式,如果您觉着有更好的表达方式,帮助我改进!
构建Instrumented单元测试
Instrumented单元测试运行在你的物理设备或模拟器上,而不是你本地机器中的jvm。如果你需要获取instrumentation信息(比如目标App的Context)或者 你需要一个android framework 组件(比如Parcelable or SharedPreferences 对象)的真实实现你就需要创建instrumented单元测试。使用instrumented单元测试也可以帮助减少编写和维护mock代码的工作。你依旧可以自由的使用mocking框架,如果你选择了该框架,就可以用来来模拟建立和各种依赖的关系。Instrumented单元测试可以利用Android框架的Api和supporting api,比如:Android Testing Support Library.
设置你的测试环境
在你构建instrumented单元测试之前,确保你的工程按照开始你的测试中描述的那样配置了你的测试代码目录和工程依赖。
创建一个Instrumented单元测试类
你的instrumented单元测试类应该被写为一个JUnit4测试类。学习更多关于创建JUnit4测试类和使用JUnit4进行断言和注解,参见构建本地单元测试。
为了创建一个instrumented JUnit4测试类,在开始定义你的测试类前添加注解: @RunWith(AndroidJUnit4.class)。你也需要具体声明Android Testing Support Library提供的AndroidJUnitRunner类作为你的默认测试运行器。这个步骤更详细的描述参见:开始你的测试。
下面的例子向你展示了如何编写一个instrumented单元测试来验证LogHistory类对Parcelable接口的实现是否正确:
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.util.Pair;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LogHistoryAndroidUnitTest {
public static final String TEST_STRING = "This is a string";
public static final long TEST_LONG = 12345678L;
private LogHistory mLogHistory;
@Before
public void createLogHistory() {
mLogHistory = new LogHistory();
}
@Test
public void logHistory_ParcelableWriteRead() {
// Set up the Parcelable object to send and receive.
mLogHistory.addEntry(TEST_STRING, TEST_LONG);
// Write the data.
Parcel parcel = Parcel.obtain();
mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());
// After you‘re done with writing, you need to reset the parcel for reading.
parcel.setDataPosition(0);
// Read the data.
LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);
List<Pair<String, Long>> createdFromParcelData = createdFromParcel.getData();
// Verify that the received data is correct.
assertThat(createdFromParcelData.size(), is(1));
assertThat(createdFromParcelData.get(0).first, is(TEST_STRING));
assertThat(createdFromParcelData.get(0).second, is(TEST_LONG));
}
}
创建一个测试套装
为了组织你的instrumented单元测试的执行,你可以收集这些测试类将他们组织为一个测试套装然后一起运行这些测试了。测试套装可以相互嵌套,你的测试套装可以包含其它的测试套装然后一起运行这些测试类。
一个测试套装被包含在一个测试包中,和主应用的包相似。通常,测试套装包的名字一般以.suite扩展名结尾(比如:com.example.android.testing.mysample.suite)
为你的单元测试创建测试套装时,导入JUnit RunWith 和 Suite 类。在你的测试套装中,添加 @RunWith(Suite.class) 和@Suite.SuitClasses() 注解。在@Suite.SuiteClasses() 注解中,列出独立的测试类或者测试套装作为参数。
下面的例子展示了如何实现一个名字为UnitTestSuite的测试套装,它把CalculatorInstrumentationTest和CalculatorAddParameterizedTest测试类组织在一起来运行他们。
import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
import com.example.android.testing.mysample.CalculatorInstrumentationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
// Runs all unit tests.
@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorInstrumentationTest.class,
CalculatorAddParameterizedTest.class})
public class UnitTestSuite {}
运行Instrumented单元测试
按照开始你的测试中所描述的那样来运行你的Instrumented单元测试。