iOS Swift - 运行特定的 VIPER 模块而无需浏览所有屏幕

问题描述

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

因此,当我只需要测试一些小东西(例如 UI 调整、更改某些字符串使其适合屏幕的方式等)时,需要花费大量时间来导航。

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

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

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

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

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

解决方法

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

  • 我将礼貌地拒绝 OP 在 VIPER 方面使用“模块”。相反,VIPER 是 5 zones {view for UI,interactor for datastore/networking/sensors,presenter for app-domain'business' rules,entity for app-domain-centric [not datastore-centric,not以网络为中心,而非以传感器为中心] 数据结构,导航路由器} 隔离和某种程度的分离。有人可能只是说 zone 和 module 是 100% 同义词/一致的,但我将把它们分开作为单独的解释。 5 个 VIPER 区域都是关于彼此分离/隔离以消除大规模视图控制器反模式/代码气味软件架构 https://khanlou.com/2015/12/massive-view-controllerhttps://www.hackingwithswift.com/articles/159/how-to-refactor-massive-view-controllers,这是旧版本的移动应用变体-era Big Ball of Mud antipattern/code-smell software-architecture http://www.laputan.org/mud/mud.html#BigBallOfMud

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

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

  • 但是要使用机械/测试/模拟路由器区域来实现对普通路由器区域的这种替换,以实现 UI 的脚本式导航,尤其是交互器区域也必须被模拟出来以驱动罐装数据存储内容、罐头网络内容和罐头传感器内容/采集以类似脚本的方式以及与测试/模拟路由器变体合作的方式。事实上,在应用程序的通常应用程序域人类用户变体中如此受欢迎的隔离/离婚是奖品,但远没有隔离可能根本没有离婚可能是模拟/测试路由器区域和模拟/测试交互器区域,它们可能会非常密切地共同完成他们的脚本/罐头模拟功能,作为一种思维方式。因此,对于应用程序的人类用户主要变体来说,什么是好的离婚/隔离关注点分离可能是应用程序的 OP 模拟/测试变体中的灾难性分离,因为实际上在应用程序之间没有这种关注点分离脚本/模拟路由器区域被替换,脚本/模拟交互器区域被替换。

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

  • 相反,如果应用程序的开发人员未能 100% 隔离视图区域内的 UI 主题,那么换出受 UI 污染的非视图区域的能力可能会被致命地侵蚀到非视图区域不能用该非视区的测试/模拟替代品换掉。要在 VIPER 区域之间实现这种 100% 严格的隔离区之间的隔离,需要公开的自律,以确保 100% 的区域间消息传递/方法调用以纯粹的应用程序域概念表达,而不会受到 Apple-think 或其构造、Android-思考或它的概念,等等。每个 VIPR 区域(除了 E 中相当简单的实体)通常需要在每个区域的外围有一个外观层,以将区域内概念与应用程序域间概念进行交互,例如隔离所有 Apple-think UI 构造或 Android-think UI 概念在视图区域内,以便只有高级思想的应用程序域概念在区域间交换——同样在交互器区域的外围有一个立面,用于互通以数据存储为中心或以传感器为中心或以网络为中心的构造的隔离区内远离更高层-order-thought 应用程序域概念 interzone。

  • 同样,代替全自动脚本导航,路由器导航区域的另一个测试/模拟替代品可以将人类用户快进到 UI 的特定部分/屏幕/场景,以进行半自动的手动交互测试。快进可以是相对未填充的屏幕/场景。或者快进可以是,比如说,一个编辑的东西屏幕,其中包含要编辑的精心制作的罐头实体来编辑已经加载,如果罐头精细实体在执行某些用例或恰到好处的情况组合时特别有害,这将特别有用重现错误。