UI组件移动开发设计系统【免费下载链接】material-components-android[MAINTENANCE MODE] Modular and customizable Material Design UI components for Android项目地址https://gitcode.com/gh_mirrors/ma/material-components-android点击查看免费下载本篇技术指南聚焦 material-components-android 仓库中的模拟器测试模块tests目录承载该库全部真机/模拟器emulator测试源码testing目录则提供被测试应用fixtures、Activity 与应用。读完本文你将掌握这套测试体系测试代码与被测宿主分离的工程组织方式、基于AndroidJUnitRunner的 instrumentation 配置方法、动态布局ViewStub测试基类与通用测试工具类的设计模式并能对照真实用例独立编写与运行面向 Material 组件的模拟器测试。一、仓库中三个测试相关目录的定位在动手阅读代码之前先理清 material-components-android 仓库中三个容易混淆的目录各自承担的角色目录作用关键说明tests/模拟器测试的实际测试代码Test Code全部*Test.java用例、测试辅助类与测试用AndroidManifest.xml都位于此testing/测试夹具与宿主应用Test Fixtures / Test App存放被测 Activity、布局资源、主题样式等 fixture不含任何*Test.javacatalog/组件目录演示应用面向用户展示各组件用法的独立演示工程并非测试专用tests/README.md 原文给出了最核心的定义This directory contains the sources for the emulator tests for this library, which exercises a test application located in the testing directory.这句话明确了两个关键事实tests 目录下是模拟器测试emulator tests——即在真实设备或模拟器上运行的 instrumentation 测试而非纯 JVM 的 Robolectric 单元测试测试通过驱动testing目录中的测试应用test application来执行——被测宿主与测试代码物理分离属于典型的测试 APK 驱动被测 APK模式。与之对应testing/README.md 也做了镜像式说明该目录包含模拟器测试使用的 test fixtures、activities 和应用源码但实际的测试代码位于 tests/即根目录下的tests/两段文档互为补充共同勾勒出完整的测试拓扑。二、tests 目录的整体结构按组件分包的组织方式从文件树可以看到tests/javatests/com/google/android/material/下按 Material 组件划分出 16 个测试包tests/javatests/com/google/android/material/ ├── AndroidManifest.xml # 顶层测试清单 ├── animation/ # MotionSpecTest ├── appbar/ # AppBar 系列测试8 个 ├── bottomappbar/ # BottomAppBarBehaviorTest ├── bottomnavigation/ # BottomNavigationViewTest 等 ├── bottomsheet/ # BottomSheetBehavior 系列5 个 ├── datepicker/ # MaterialDatePickerPagesTest 测试工具 ├── floatingactionbutton/ # FloatingActionButtonTest、FabTransformationBehaviorTest ├── internal/ # BaseDynamicCoordinatorLayoutTest测试基类 ├── navigation/ # NavigationViewTest ├── shape/ # CutCornerTreatmentTest、MaterialShapeDrawable 系列 ├── snackbar/ # SnackbarTest、SnackbarTouchTest 等6 个 ├── tabs/ # TabLayoutTest、TabLayoutPoolingTest 等 ├── testutils/ # 通用测试工具类26 个 ├── textfield/ # TextInputLayoutTest、ExposedDropdownMenuTest 等 └── theme/ # MaterialComponentsViewInflaterTest这种按组件分包、每个包自带清单的排布与库源码lib/java/com/google/android/material/下的包结构一一对应方便开发者按组件定位测试。几乎所有组件测试包appbar、bottomappbar、bottomsheet、snackbar、tabs等都带有一份独立的AndroidManifest.xml用于声明该包测试运行所需的 instrumentation 配置。每个测试包的 manifest 配置各包内的AndroidManifest.xml结构高度一致以 appbar 包清单 为例manifest xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:toolshttp://schemas.android.com/tools packagecom.google.android.material.appbar uses-sdk tools:overrideLibraryandroidx.test, android.app, androidx.test.rule, androidx.test.espresso, androidx.test.espresso.idling/ application uses-library android:nameandroid.test.runner/ /application instrumentation android:nameandroidx.test.runner.AndroidJUnitRunner android:targetPackagecom.google.android.material.testapp/ /manifest三个要点值得注意android:nameandroidx.test.runner.AndroidJUnitRunner测试运行器统一使用 AndroidX Test 的 JUnit4 runnerandroid:targetPackagecom.google.android.material.testappinstrumentation 的目标包是testing模块中定义的测试应用包名见 测试应用清单这正是测试代码驱动测试应用的声明式绑定tools:overrideLibrary允许测试模块直接引用androidx.test、espresso 等库的 Android 资源与 Activity避免清单合并冲突。顶层 tests 主清单 与此同构同样指向com.google.android.material.testapp。三、被测宿主testing 模块中的测试应用testapptests目录的测试不自己搭建界面而是全部运行在testing模块的测试应用中。该应用的核心工程入口位于 testing/java/com/google/android/material/testapp/并在 settings.gradle 中以:testing:java:com:google:android:material:testapp及其animation、base、custom、theme子模块注册。3.1 测试应用清单与 Activity 注册测试应用清单注册了大量测试专用 Activity例如application android:supportsRtltrue android:themestyle/Theme.MaterialComponents.Light activity android:name.AppBarHorizontalScrollingActivity .../ activity android:name.AppBarLayoutCollapsePinActivity .../ activity android:name.BottomNavigationViewActivity .../ activity android:name.BottomSheetBehaviorActivity .../ activity android:name.DynamicCoordinatorLayoutActivity .../ activity android:name.FloatingActionButtonActivity .../ activity android:name.SnackbarActivity .../ activity android:name.TabLayoutWithViewPagerActivity .../ activity android:name.TextInputLayoutActivity .../ ... /application这些 Activity 各自对应一组测试关注点横向滚动、CollapsingToolbar 状态恢复、BottomSheet 触摸交互、Snackbar 与 FAB 的避让、TabLayout 池化复用等。每个 Activity 都从测试应用的base子模块基类如com.google.android.material.testapp.base.BaseTestActivity派生并指定getContentViewLayoutResId()返回对应布局资源。以 DynamicCoordinatorLayoutActivity.java 为例它只做一件事——返回R.layout.dynamic_coordinator_layout作为内容布局而该布局的核心是一个ViewStub!-- ViewStub that will be inflated to a CoordinatorLayout at test runtime. -- ViewStub android:idid/coordinator_stub ... /这是整套测试框架最精妙的设计之一测试运行时动态决定要 inflate 哪套布局从而实现一个 Activity 宿主、多个组件场景的复用。3.2 动态布局机制测试基类中的 ViewStub 注入BaseDynamicCoordinatorLayoutTest.java 是 CoordinatorLayout 相关测试AppBar、Snackbar、FAB 等的公共基类它通过ActivityTestRuleDynamicCoordinatorLayoutActivity启动宿主 Activity并暴露一个inflateViewStub(layoutResId)的 EspressoViewActionprotected ViewAction inflateViewStub(final LayoutRes int layoutResId) { return new ViewAction() { Override public void perform(UiController uiController, View view) { uiController.loopMainThreadUntilIdle(); ViewStub viewStub (ViewStub) view; viewStub.setLayoutResource(layoutResId); viewStub.inflate(); mCoordinatorLayout activityTestRule.getActivity().findViewById(viewStub.getInflatedId()); uiController.loopMainThreadUntilIdle(); } }; }派生测试类如 AppBarLayoutBaseTest.java随后通过onView(withId(R.id.coordinator_stub)).perform(inflateViewStub(layoutResId))注入各自场景的布局再findViewById拿到AppBarLayout、CollapsingToolbarLayout、Toolbar等被测视图进行断言。基类的After tearDown()会把 Activity 内容视图还原为 ViewStub保证测试用例之间互不污染。基类中还提供了两个体现工程经验的细节TouchSlop 补偿Before中读取ViewConfiguration.getScaledTouchSlop()并额外 6确保手势滑动量一定超过系统触摸阈值源码注释直言usages dont seem to be totally accurate方向切换支持setLayoutDirection(layoutDir)ViewAction 用于在测试中切换 RTL/LTR配合ViewCompat.setLayoutDirection覆盖布局方向相关场景。四、通用测试工具类testutils 包tests/javatests/com/google/android/material/testutils/ 是 26 个工具类组成的测试工具箱被各组件测试广泛静态导入使用。下表是其中高价值工具的职责速览工具类用途DisableAnimationsRule.java通过UiAutomation.executeShellCommand将系统窗口/过渡/属性动画缩放全部置 0消除动画导致的测试不稳定ActivityUtils.javaActivity 启动、状态恢复等操作的封装PollingCheck.java轮询等待某个条件成立的断言工具SwipeUtils.javaswipeUp/swipeDown等精细手势封装TestUtilsActions.javasetText、setTitle、setLayoutDirection等自定义 Espresso ViewActionTestUtilsMatchers.java自定义 Hamcrest MatcherNightModeRule.java昼夜模式切换的 JUnit RuleCheeses.java 与 Shakespeare.java标准测试文本数据集长文本滚动、文字截断场景AccessibilityUtils.java无障碍节点AccessibilityNodeInfo断言辅助ViewStructureImpl.javaAutofill / ViewStructure 场景的桩实现以 DisableAnimationsRule.java 为例其核心实现展示了如何在 instrumentation 中关闭系统动画UiAutomation uiAutomation getInstrumentation().getUiAutomation(); uiAutomation.executeShellCommand(settings put global window_animation_scale 0); uiAutomation.executeShellCommand(settings put global transition_animation_scale 0); uiAutomation.executeShellCommand(settings put global animator_duration_scale 0); base.evaluate();该 Rule 实现了 JUnit 的TestRule接口在evaluate()前后通过settings put关闭三类动画从而保证依赖动画完成的组件如 Snackbar 滑入滑出、CollapsingToolbar 折叠能被 Espresso 稳定同步。五、代表性测试用例解读5.1 Snackbar真实交互驱动 Mockito 验证SnackbarTest.java442 行以RunWith(AndroidJUnit4.class)运行通过ActivityTestRuleSnackbarActivity启动被测宿主。其断言手法具有代表性private void verifySnackbarContent( final Snackbar snackbar, final String expectedMessage, final String expectedAction) { SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); withText(expectedMessage) .matches(allOf( isDescendantOfA(isAssignableFrom(Snackbar.SnackbarLayout.class)), isCompletelyDisplayed())); ... SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(snackbar); }要点通过withText(...)isDescendantOfA(isAssignableFrom(Snackbar.SnackbarLayout.class))限定断言对象必须是 Snackbar 内部布局中的文本避免误匹配页面其他 TextView消息与 Action 文本均同时以字符串常量和资源 ID 两种方式提供覆盖直接传字符串与传StringRes两条 API 路径展示/消失阶段分别调用SnackbarUtils的等待完全展示/完全消失辅助方法规避动画时序问题文件同时导入了org.mockito.Mockito的mock、spy、verify用于验证 Snackbar 回调监听器如 dismiss 监听的触发次数与交互顺序。5.2 DatePickerIdlingResource 处理异步加载MaterialDatePickerPagesTest.java 展示了处理异步数据加载的经典方案——自定义 IdlingResource。该包内置了 ListenerIdlingResource.java 与 RecyclerIdlingResource.java分别等待监听器回调与 RecyclerView 完成首屏绘制测试通过IdlingRegistry注册它们使 Espresso 在日历页Month异步生成期间保持同步。此外它还配合InstantTaskExecutorRule处理 LiveData/协程任务调度并通过MaterialDatePickerTestUtils.findFirstVisibleItem定位月份网格中的首个可见日期单元。5.3 ViewInflater验证主题注入组件替换MaterialComponentsViewInflaterTest.java 是一类特殊的静态验证测试它启动MaterialComponentsViewInflaterActivity用 Truth 断言布局中声明的普通控件被 Material 主题的ViewInflater自动替换成了对应 Material 组件Test public void ensureThatInflaterCreatesMaterialButton() { View view testActivity.findViewById(R.id.test_button); assertThat(view).isInstanceOf(MaterialButton.class); }同文件中还包含MaterialCheckBox、MaterialRadioButton、MaterialTextView、MaterialAutoCompleteTextView等断言——这是对Theme.MaterialComponents 自动替换 View这一核心主题机制的直接回归验证也解释了为什么测试应用清单中的主题统一使用style/Theme.MaterialComponents.Light。六、测试依赖与版本管理模拟器测试依赖统一收敛在 gradle/libs.versions.toml 中与测试直接相关的关键项包括AndroidX Testandroidx-test-corerunner/rules/core版本1.4.0Espressoandroidx-espresso-core/contrib/accessibility版本3.1.0断言与 Mocktruth0.45、junit4.13.2、mockito-core2.25.0、dexmaker与dexmaker-mokito1.2用于在 Dalvik 上生成 mock本地 JVM 测试robolectric4.13Android Gradle Plugin8.11.1。值得留意的是truth版本0.45明显早于库内其他依赖这是库方为保持稳定发布约束而锁定的版本侧面说明该仓库处于维护模式、依赖版本趋于保守。七、如何运行这套模拟器测试模拟器测试属于 instrumentation 测试需要真实设备或模拟器。在仓库根目录下通过 Gradle Wrapper 执行# 运行全部组件测试需要已连接设备/模拟器 ./gradlew connectedAndroidTest # 或按模块运行 ./gradlew :tests-javatests-com-google-android-material:connectedAndroidTest注意由于 settings.gradle 将每个子项目按路径重命名形如:java-io-material-catalog、:tests-javatests-...实际模块名以./gradlew projects输出为准。仓库根目录同时提供了android-wait-for-emulator脚本可在 CI 场景下等待模拟器就绪后再触发测试。运行前请确认已具备安装了 Android SDK 的模拟器或已连接设备、项目根目录 gradle.properties 中配置的 SDK 路径有效以及依赖仓库可访问依赖从 Google Maven 拉取。八、文档与 Javadoc 生成策略tests/NO_DOCS 文件说明了测试工程的文档策略该文件的存在会阻止 Android Javadoc 工具为该目录下的 Java 文件生成文档This is especially useful for test projects——即测试代码不参与公开 API 文档产出避免污染库的 API 文档空间。这也是仓库中tests、testing均带有NO_DOCS的原因。结语material-components-android 的模拟器测试体系是一套高度工程化的范例tests与testing的职责分离保证了测试代码的纯净每个组件包独立的 instrumentation 清单 统一的AndroidJUnitRunner与targetPackage绑定构成了可扩展的执行底座ViewStub动态注入、DisableAnimationsRule、IdlingResource 与 26 个 testutils 工具类则解决了组件测试中最棘手的时序与状态问题。理解这套结构不仅有助于为 Material 组件贡献回归测试也能为大型 Android 组件库设计自己的测试基建提供直接可复用的参考模板。赞分享UI组件移动开发设计系统【免费下载链接】material-components-android[MAINTENANCE MODE] Modular and customizable Material Design UI components for Android项目地址https://gitcode.com/gh_mirrors/ma/material-components-android点击查看免费下载相关推荐理解 Material Components for Android 的目录结构lib 库、组件包与 internal 受保护 API理解 Material Components for Android 的目录结构lib 库、组件包与 internal 受保护 API 本篇技术指南围绕 MaUI组件移动开发设计系统Material Components for Android 从源码构建指南Material Components for Android 从源码构建指南 前言 Material Components for Android 是 GooUI组件移动开发设计系统在 Android 模拟器中运行 Matter Java 控制器层测试connectedhomeip 的 Android Emulator Tests 实操指南在 Android 模拟器中运行 Matter Java 控制器层测试connectedhomeip 的 Android Emulator Tests 实操指物联网智能家居嵌入式通信上一篇技术深度解析robot_localization状态估计与GPS融合的协方差矩阵调优方法下一篇Masa Mods中文汉化资源包5分钟快速告别英文困扰的终极指南 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考