首页 > 解决方案 > iOS Swift - 运行特定的 VIPER 模块而无需浏览所有屏幕

问题描述

我想在我的项目中使用特定的 Viper 模块。从技术上讲,现在当我需要打开一个特定的 UIViewController 时,我需要通过一些屏幕输入一些数据等,然后在 20 秒内我就在那个特定的屏幕上。

因此,当我只需要例如测试一些小事情(如 UI 调整、更改一些字符串如何适应屏幕等)时,需要花费大量时间导航。

相反,我想在运行项目时运行特定屏幕。

在这种情况下,模拟和注入肯定会有很大帮助,因为我需要用一些初始数据来满足我的 Viper 模块。这只是一个技术细节。

我想知道如何组织我的项目以运行特定模块而不是运行整个项目。

硬编码解决方案,例如通过添加覆盖初始点的额外代码来使用应用程序委托,这只是一个临时解决方案,您需要在完成后清理应用程序委托。

我可能错了,但我认为应该有一个特定的目标解决方案可以运行不同的模块,无论它是像 HomeViewController 这样的初始点还是带有模拟注入的特定模块。

标签: iosswiftviper-architecture

解决方案


为了设定这个答案的基本规则,https://TheSwiftDev.com/the-ultimate-viper-architecture-tutorial描述了 VIPER 是什么以及它的目的的最规范的原始思想变体完成自律。(在过去的几年中出现了其他派生观点,但出于所有-the-wood-behind-1-arrow 清晰度和教学原因,我将在此答案中使用这种原始的思想流派。)

  • 对于 VIPER,我将礼貌地拒绝 OP 对“模块”的使用。相反,VIPER 是 5个区域{用于 UI 的视图,用于数据存储/网络/传感器的交互器,用于应用程序域“业务”规则的演示者,用于以应用程序域为中心的实体 [不是以数据存储为中心,不是以网络为中心,不是传感器-集中] 数据结构,用于导航的路由器} 隔离和某种程度的分离。有人可能会说 zone 和 module 是 100% 同义词/全等的,但我将把它们分开作为单独的解释。5 个 VIPER 区域都是关于彼此离婚/隔离以消除 Massive View Controller 反模式/code-smell 软件架构https://khanlou.com/2015/12/massive-view-controllerhttps://www.hackingwithswift.com/articles/159/how-to-refactor-massive-view-controllers,它是旧时代 Big Ball of Mud 反模式/code-smell 软件架构的移动应用变体http://www.laputan.org/mud/mud.html#BigBallOfMud

  • 另一方面,模块可以解释为比 5 个 VIPER 区域更细粒度。让我们在这里做。VIPER 的每个区域都可以进一步细分为该区域的类似主题部分的模块,例如包含场景/屏幕/包含视图的所有(子)视图或任何其他用户内心渴望的应用程序子类别。模块划分可以与 5 个 VIPER 区域正交(或忽略)。实际上,设计人员可能会选择在 2 个或更多 VIPER 区域中的每个区域内具有相同的模块划分。或者同样有效,设计师可能会选择在视图区域内与交互器区域内而不是在演示者区域内具有完全不同的模块划分,因为他们每个人都碰巧专注于以一种仅在该区域内合理的方式分解该隔离/离婚/隔离区域的不同方式(并且在其他一些 4 个区域中几乎没有意义)。因此,从这个答案的角度来看,我们将不再提及模块,因为它是每个区域内的本地口味,与 OP 的预期目标无关。

  • 正确完成的 VIPER 架构中的每个区域都已被隔离,因此特定于 UI 的主题永远不会逃出视图区域(例如,进入最诱人的演示者区域或路由器区域或 [通常是较小的诱惑,除非大量模仿传感器或网络的非 VIPER 示例数据采集​​]交互区)。由于这种隔离,OP 的目标实际上是拥有一个完全不同的路由器/导航区域,通过其各种场景/屏幕/模态对话框以一种对人类来说甚至可能不自然的方式驱动应用程序进入测试模式- 应用程序及其路由器导航的用户变体。但整个VIPER 软件架构的长期目标是更换整个区域,因为它具有无可挑剔的隔离/离婚——实际上就像通过婚姻离婚将一个配偶换成另一个。这就是 OP 正在有效寻求的:将(主要)路由器区域的人类用户变体替换为测试模拟路由器区域,该路由器区域通过类似脚本的行进命令来驱动应用程序,从而以以下方式行进 UI通过人类用户 UI 操作来完成令人讨厌的太多努力。模拟/脚本替代路由器区域可以随意“短路”,因为它可以跳过 UI 的某些部分,只要任何本应自然建立的累积状态作为模拟脚本的一部分被回填。

  • 但是,要使用机械/测试/模拟路由器区域来完成这种普通路由器区域的交换,以实现 UI 的类似脚本的导航,交互器区域也必须被模拟出来以驱动罐装数据存储内容、罐装网络内容和以类似脚本的方式以及以与测试/模拟路由器变体合作的方式预设传感器内容/采集。确实,在应用程序的通常应用程序域人类用户变体中如此寻求的隔离/离婚是奖励,但远没有隔离,也许根本没有离婚可能是模拟/测试路由器区域和之间值得称赞的目标模拟/测试交互器区域,它们可能非常紧密地结合在一起,以作为一种思维方式一起完成它们的脚本/罐头模拟功能。

  • 人们希望演示者的业务规则准后端式处理不需要被嘲笑,因为希望这些应用程序域业务规则的执行不会妨碍 UI 1 的机械驱动) 通过替代路由器区域进行模拟/脚本导航,以及 2) 使用来自模拟/脚本传感器、模拟/脚本数据存储和/或模拟/脚本网络的模拟/脚本数据。如果某些应用程序域需要将视图区域中的纯 UI 测试与演示者区域中的纯业务规则/准后端测试分开,则模拟 UI 视图区域将测试/驱动真正的演示者区域和模拟业务-规则演示者区域(可能具有替代现实/模糊业务规则)将更严格地测试/执行真实视图区域。

  • 相反,如果应用程序的开发人员未能 100% 隔离,例如,视图区域内的 UI 主题,那么换出受 UI 污染的非视图区域的能力可能会受到致命的侵蚀,以至于非视图区域无法用测试/模拟该非视图区域的替代品。为了在 VIPER 区域之间实现 100% 严格的隔离区域间隔离,需要公开的自律,以确保 100% 的区域间消息传递/方法调用以纯应用程序域概念表达,不受 Apple-think 或其构造、Android-思考或它的概念,等等。每个 VIPR 区域(除了 E 中相当简单的实体)通常需要在每个区域的外围有一个外观层,以将区域内概念与应用程序域间概念进行交互,

  • 同样,代替全自动脚本导航,路由器导航区域的另一个测试/模拟替代品可以将人类用户快速转发到 UI 的特定部分/屏幕/场景,以进行半自动化测试的手动交互。快进可以是到相对未填充的屏幕/场景。或者,快速转发可以是,例如,一个编辑屏幕,其中包含已加载的预制精细实体进行编辑,如果预制精细实体在执行某些用例或只是正确组合情况时特别有用一个错误的再现。


推荐阅读