Android TV应用WebView的onReceivedError回调如何测试?
嘿,这个问题我刚好有经验,给你分几种实用的测试方法,覆盖手动和自动化场景,完美适配Android TV的WebView错误处理逻辑:
一、手动快速验证(适合前期调试)
直接在Android TV模拟器或真机上操作,快速验证逻辑是否生效:
- 断网测试:关闭设备的WiFi(TV设备一般只有WiFi),然后让WebView加载一个需要网络的URL(比如
https://example.com),看是否弹出带有错误描述的Toast,并且页面跳转到本地的error.html。 - 无效URL测试:让WebView加载一个不存在的地址,比如
https://this-is-a-fake-url-123.com,或者格式错误的URL(比如只写http://),验证错误回调是否触发。 - 服务器错误模拟:如果有自己的测试服务,可以返回404/500等错误状态码,看WebView是否会触发错误处理逻辑。
二、自动化Instrumented测试(适合持续集成)
用Android的Instrumented测试框架(比如Espresso)编写自动化用例,在真实设备或模拟器上运行,保证每次代码变更后逻辑都正常:
首先,确保你的测试依赖里包含Espresso相关库(在build.gradle的androidTestImplementation中添加),然后编写测试类:
@RunWith(AndroidJUnit4.class) public class WebViewErrorHandlingTest { @Rule public ActivityScenarioRule<YourWebViewActivity> activityRule = new ActivityScenarioRule<>(YourWebViewActivity.class); @Test public void testErrorHandlingOnNoNetwork() { // 第一步:模拟TV设备断网 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand( "svc wifi disable" ); // 第二步:触发WebView加载网络URL onView(withId(R.id.your_tv_webview_id)).perform((webView) -> { webView.loadUrl("https://example.com"); }); // 第三步:验证Toast是否弹出(Toast是系统级弹窗,需要指定查找范围) onView(withText(containsString("Oh no!"))) .inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))) .check(matches(isDisplayed())); // 第四步:验证WebView是否加载了本地错误页 onView(withId(R.id.your_tv_webview_id)).check((webView, viewAssertion) -> { assertEquals("file:///android_asset/error.html", webView.getUrl()); }); // 最后恢复网络状态 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand( "svc wifi enable" ); } // 辅助方法获取当前Activity实例 private Activity getActivity() { final Activity[] activityHolder = new Activity[1]; activityRule.getScenario().onActivity(activity -> activityHolder[0] = activity); return activityHolder[0]; } }
注意事项:
- 测试需要
CHANGE_NETWORK_STATE权限,记得在src/androidTest/AndroidManifest.xml中添加:<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> - Android TV的WebView测试要确保模拟器/设备是TV环境,避免手机环境的差异。
三、单元测试(快速验证逻辑正确性)
用Mockito等Mock框架,不需要真实设备,直接测试onReceivedError的逻辑是否符合预期:
@RunWith(MockitoJUnitRunner.class) public class WebViewErrorCallbackUnitTest { @Mock private WebView mockWebView; @Mock private Context mockContext; @Test public void testOnReceivedErrorTriggersCorrectActions() { // 创建你的WebViewClient实例 WebViewClient webViewClient = new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Toast.makeText(mockContext, "Oh no! " + description, Toast.LENGTH_SHORT).show(); mockWebView.loadUrl("file:///android_asset/error.html"); } }; // 模拟错误场景:比如域名解析失败 String testErrorDesc = "Host lookup failed"; webViewClient.onReceivedError(mockWebView, WebViewClient.ERROR_HOST_LOOKUP, testErrorDesc, "https://example.com"); // 验证Toast是否被正确调用 verify(mockContext).makeText( eq(mockContext), eq("Oh no! " + testErrorDesc), eq(Toast.LENGTH_SHORT) ); // 验证是否正确加载了本地错误页 verify(mockWebView).loadUrl(eq("file:///android_asset/error.html")); } }
这种方式可以快速验证回调方法里的逻辑有没有写错,比如Toast的文案、错误页的URL是否正确,不需要启动设备,适合开发过程中的快速测试。
内容的提问来源于stack exchange,提问作者CWright
相关产品推荐
相关产品推荐

