在 android 测试时重新启动应用程序
Restarting application on android test
我正在制作一个库,它将根据用户默认设置处理信息并将其保存在 SharedPreferences 上,开发人员可以在初始化我的库之前在他们的应用程序中修改它。
SDK 每个应用程序实例只能初始化一次,否则会触发 RuntimeError。所以在应用程序方面,Application class 应该是这样的:
public class SampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//Here I can do something that will change the default configs
//Here I initialize the SDK singleton method
Sdk.initialize();
}
}
sdk抽象实现:
public class Sdk {
private static SampleApplication sInstance;
private void Sdk(){
}
public static SampleApplication getInstance() throws RuntimeException {
if (sInstance == null) {
throw new RuntimeException();
}
return sInstance;
}
public static void initialize() {
if (sInstance == null) {
sInstance = new Sdk();
//save some information according to what is on the default configurations
} else {
throw new RuntimeException("Method was already initialized");
}
}
}
当我想测试几个场景来调用这个方法(每个应用程序实例只能调用一次)时,问题就来了。
所以我创建了一个 Android 扩展 ApplicationTest
的测试
应用程序测试:
public class ApplicationTest extends ApplicationTestCase<SampleApplication> {
public ApplicationTest() {
super(SampleApplication.class);
}
}
Android 测试样本:
public class SampleTest extends ApplicationTest {
@Override
protected void setUp() throws Exception {
// Here I restart the user preferences although I need to restart the application
// terminateApplication();
// createApplication();
super.setUp();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testDefaultSettings() {
// Here is where I want to restart application input
// some values on the user preferences settings in order
// to test the output on sharedpreferences by the initialized method
}
}
我尝试再次终止并创建应用程序,但没有成功。
我的问题是可以重新启动 Android 测试的应用程序吗?
我在这里做错了什么吗?
我相信,您真正遇到的问题是 InstrumentationTestRunner
的问题:How to prevent ActivityUnitTestCase from calling Application.onCreate?(显然,没有明显的解决方法)
即无论如何,TestRunner 将在其初始化期间调用 onCreate()
,因此一旦您调用 createApplication()
,您的 Sdk
已经初始化。
关于问题本身 - 我相信,唯一的选择是重新考虑 Sdk
class 的体系结构(或添加一些 "reset" 功能等)
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Sdk.terminate(); - If you specify TestApplication as an
// application class in AndroidManifest,
// you'll have to uncomment this(due to issue with test runner)
Sdk.initialize();
}
@Override
public void onTerminate() {
super.onTerminate();
Sdk.terminate();
}
}
Sdk
class
public class Sdk {
private static Sdk sInstance;
private void Sdk(){
}
public static Sdk getInstance() throws RuntimeException {
if (sInstance == null) {
throw new RuntimeException();
}
return sInstance;
}
public static void terminate() {
sInstance = null;
}
public static void initialize() {
if (sInstance == null) {
sInstance = new Sdk();
//save some information according to what is on the default configurations
} else {
throw new RuntimeException("Method was already initialized");
}
}
}
测试:
public class MyApplicationTest extends ApplicationTestCase<TestApplication> {
public MyApplicationTest() {
super(TestApplication.class);
}
public void testMultiplicationTests() {
createApplication();
int answer = 42;
assertEquals(42, answer);
terminateApplication();
}
public void testDefaultSettings() {
createApplication();
assertNotNull(Sdk.getInstance());
terminateApplication();
}
}
NB! 如果你为 androidTest 应用特殊的 AndroidManifest,你可以让它不那么痛苦。然后,当 TestRunner 在测试开始之前自行调用 onCreate() 时,您就不会为 TestRunner 的问题而苦恼了。
希望对你有所帮助
我正在制作一个库,它将根据用户默认设置处理信息并将其保存在 SharedPreferences 上,开发人员可以在初始化我的库之前在他们的应用程序中修改它。
SDK 每个应用程序实例只能初始化一次,否则会触发 RuntimeError。所以在应用程序方面,Application class 应该是这样的:
public class SampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//Here I can do something that will change the default configs
//Here I initialize the SDK singleton method
Sdk.initialize();
}
}
sdk抽象实现:
public class Sdk {
private static SampleApplication sInstance;
private void Sdk(){
}
public static SampleApplication getInstance() throws RuntimeException {
if (sInstance == null) {
throw new RuntimeException();
}
return sInstance;
}
public static void initialize() {
if (sInstance == null) {
sInstance = new Sdk();
//save some information according to what is on the default configurations
} else {
throw new RuntimeException("Method was already initialized");
}
}
}
当我想测试几个场景来调用这个方法(每个应用程序实例只能调用一次)时,问题就来了。
所以我创建了一个 Android 扩展 ApplicationTest
的测试应用程序测试:
public class ApplicationTest extends ApplicationTestCase<SampleApplication> {
public ApplicationTest() {
super(SampleApplication.class);
}
}
Android 测试样本:
public class SampleTest extends ApplicationTest {
@Override
protected void setUp() throws Exception {
// Here I restart the user preferences although I need to restart the application
// terminateApplication();
// createApplication();
super.setUp();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testDefaultSettings() {
// Here is where I want to restart application input
// some values on the user preferences settings in order
// to test the output on sharedpreferences by the initialized method
}
}
我尝试再次终止并创建应用程序,但没有成功。 我的问题是可以重新启动 Android 测试的应用程序吗? 我在这里做错了什么吗?
我相信,您真正遇到的问题是 InstrumentationTestRunner
的问题:How to prevent ActivityUnitTestCase from calling Application.onCreate?(显然,没有明显的解决方法)
即无论如何,TestRunner 将在其初始化期间调用 onCreate()
,因此一旦您调用 createApplication()
,您的 Sdk
已经初始化。
关于问题本身 - 我相信,唯一的选择是重新考虑 Sdk
class 的体系结构(或添加一些 "reset" 功能等)
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Sdk.terminate(); - If you specify TestApplication as an
// application class in AndroidManifest,
// you'll have to uncomment this(due to issue with test runner)
Sdk.initialize();
}
@Override
public void onTerminate() {
super.onTerminate();
Sdk.terminate();
}
}
Sdk
class
public class Sdk {
private static Sdk sInstance;
private void Sdk(){
}
public static Sdk getInstance() throws RuntimeException {
if (sInstance == null) {
throw new RuntimeException();
}
return sInstance;
}
public static void terminate() {
sInstance = null;
}
public static void initialize() {
if (sInstance == null) {
sInstance = new Sdk();
//save some information according to what is on the default configurations
} else {
throw new RuntimeException("Method was already initialized");
}
}
}
测试:
public class MyApplicationTest extends ApplicationTestCase<TestApplication> {
public MyApplicationTest() {
super(TestApplication.class);
}
public void testMultiplicationTests() {
createApplication();
int answer = 42;
assertEquals(42, answer);
terminateApplication();
}
public void testDefaultSettings() {
createApplication();
assertNotNull(Sdk.getInstance());
terminateApplication();
}
}
NB! 如果你为 androidTest 应用特殊的 AndroidManifest,你可以让它不那么痛苦。然后,当 TestRunner 在测试开始之前自行调用 onCreate() 时,您就不会为 TestRunner 的问题而苦恼了。
希望对你有所帮助