kui*_*ers 6 junit android unit-testing
我正在尝试使用许多测试方法为Activity创建单元测试.但是在大约31次测试之后,应用程序被杀死了,因为堆内存不足.
1152 E SurfaceFlinger createSurface() failed, generateId = -12
1152 W WindowManager OutOfResourcesException creating surface
1152 I WindowManager Out of memory for surface! Looking for leaks...
1152 W WindowManager No leaked surfaces; killing applicatons!
1152 W ActivityManager Killing processes Free memory at adjustment 1
Run Code Online (Sandbox Code Playgroud)
我用40个相同的简单测试用例进行了单元测试,以找出问题所在.但感觉GC在测试期间没有足够快的速度来清理内存.
这是我的leakTest测试用例:
package my.app;
import android.os.Debug;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
public class leakTest extends
ActivityInstrumentationTestCase2<TestActivityAndroid> {
String TAG = "leakTest";
TestActivityAndroid mActivity = null;
public leakTest() {
super(TestActivityAndroid.class);
}
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(false);
mActivity = getActivity();
}
protected void tearDown() throws Exception {
super.tearDown();
}
private void printHeapSize() {
Log.e(TAG,
"NativeHeapAllocatedSize = "
+ Debug.getNativeHeapAllocatedSize());
Log.e(TAG, "NativeHeapFreeSize = " + Debug.getNativeHeapFreeSize());
Log.e(TAG, "NativeHeapSIZE = " + Debug.getNativeHeapSize());
}
public void test_1() {
assertNotNull(mActivity);
}
public void test_2() {
assertNotNull(mActivity);
}
public void test_3() {
assertNotNull(mActivity);
}
public void test_4() {
assertNotNull(mActivity);
}
public void test_5() {
assertNotNull(mActivity);
}
public void test_6() {
assertNotNull(mActivity);
}
public void test_7() {
assertNotNull(mActivity);
}
public void test_8() {
assertNotNull(mActivity);
}
public void test_9() {
assertNotNull(mActivity);
}
public void test_10() {
assertNotNull(mActivity);
}
public void test_11() {
assertNotNull(mActivity);
}
public void test_12() {
assertNotNull(mActivity);
}
public void test_13() {
assertNotNull(mActivity);
}
public void test_14() {
assertNotNull(mActivity);
}
public void test_15() {
assertNotNull(mActivity);
}
public void test_16() {
assertNotNull(mActivity);
}
public void test_17() {
assertNotNull(mActivity);
}
public void test_18() {
assertNotNull(mActivity);
}
public void test_19() {
assertNotNull(mActivity);
}
public void test_20() {
assertNotNull(mActivity);
}
public void test_21() {
assertNotNull(mActivity);
}
public void test_22() {
assertNotNull(mActivity);
}
public void test_23() {
assertNotNull(mActivity);
}
public void test_24() {
assertNotNull(mActivity);
}
public void test_25() {
assertNotNull(mActivity);
}
public void test_26() {
assertNotNull(mActivity);
}
public void test_27() {
assertNotNull(mActivity);
}
public void test_28() {
assertNotNull(mActivity);
}
public void test_29() {
assertNotNull(mActivity);
}
public void test_30() {
assertNotNull(mActivity);
}
public void test_31() {
assertNotNull(mActivity);
}
public void test_32() {
assertNotNull(mActivity);
}
public void test_33() {
assertNotNull(mActivity);
}
public void test_34() {
assertNotNull(mActivity);
}
public void test_35() {
assertNotNull(mActivity);
}
public void test_36() {
assertNotNull(mActivity);
}
public void test_37() {
assertNotNull(mActivity);
}
public void test_38() {
assertNotNull(mActivity);
}
public void test_39() {
assertNotNull(mActivity);
}
public void test_40() {
assertNotNull(mActivity);
}
}
Run Code Online (Sandbox Code Playgroud)
扩展Activity的测试活动:
package my.app;
import android.app.Activity;
import android.os.Bundle;
public class TestActivityAndroid extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是内存使用情况,其中本机可用空间降至30kB以下且应用程序被杀死.
Applications Memory Usage (kB): Uptime: 3804373 Realtime: 3804373
** MEMINFO in pid 7315 [my.app] **
native dalvik other total
size: 4048 3271 N/A 7319
allocated: 3942 2306 N/A 6248
free: 105 965 N/A 1070
(Pss): 844 1590 1806 4240
(shared dirty): 1404 4120 2288 7812
(priv dirty): 736 672 992 2400 Objects
Views: 0 ViewRoots: 0
AppContexts: 0 Activities: 0
Assets: 2 AssetManagers: 2
Local Binders: 11 Proxy Binders: 10
Death Recipients: 0
OpenSSL Sockets: 0
SQL
heap: 0 memoryUsed: 0
pageCacheOverflo: 0 largestMemAlloc: 0
Asset Allocations
zip:/data/app/my.app-1.apk:/resources.arsc: 1K
Run Code Online (Sandbox Code Playgroud)
有人有一个更好的解决方案,2秒睡在tearDown()内?我不喜欢tearDown()里面的睡眠.而且因为我们的测试套件中有大约100个测试,所以2秒将是一个巨大的延迟.
我希望有人可以帮助我,如果我的问题不明确,请告诉我.
提前致谢.
为什么每次单元测试后都需要进行GC?
如果是因为您想要一个干净的测试环境,那么就接受 2 秒的延迟。TeaDown 至少进行 2 次GC 和一些终结。为您的下一次测试留下一个干净的环境。如果你仔细阅读了 android 源代码,有几条注释表明在测试结束时需要调用 TeaDown 。
如果您的测试不需要干净的环境,则将它们结合起来。话虽如此,为了获得测试所提供的保护,在后台运行 200 秒的进程只是一个很小的代价。
我们当前大型项目的自动化测试大约需要 5 分钟才能运行。我从来没有注意到,因为我们已经自动化了我们的系统,在初次签入时运行测试,并在失败时退回提交。
有几次他们失败了,我真的很惊讶我更改的代码弄乱了应用程序的其他部分。通过自动化测试,我们在维护和调试应用程序方面节省了至少几周甚至可能几个月的时间。