什么是在 Swift 中构建 CLI 应用程序的好方法或常用方法

Posted

技术标签:

【中文标题】什么是在 Swift 中构建 CLI 应用程序的好方法或常用方法【英文标题】:What is a good or common way to structure a CLI appliction in Swift 【发布时间】:2021-05-20 03:17:56 【问题描述】:

我正在学习 Swift 5,还有什么更好的方法来编写一些练习。但这对我来说有点头疼。这就是我想要做的。

我想编写一个简单的 CLI 应用程序,但我也想包含单元测试。假设该应用名为simple_app

所以我继续,打开 XCode v12.4 并单击新建项目。我选择了使用 Swift 语言的 MacOS 控制台应用程序。这给了我一个名为 simple_app 的文件夹,其中包含一个 .xcodeproj 和另一个带有 simple_appname 的文件夹。第二个文件夹里面是实际的源代码。

似乎 Swift 项目使用约定来寻找 main.swift 文件作为入口点。到现在为止还挺好。现在假设我有这样简单的事情:

func add(_ numA:Int, _ numB:Int) -> Int 
    return numA + numB


func main() 
    print(add(4, 5))


main()

这按预期工作。 所以现在,我想添加单元测试。经过一番阅读,我似乎需要添加一个新目标。我继续使用 Xcode 创建一个新目标,我称之为simple_app_tests。这创建了一些不错的模板。但是当我尝试导入simple_app mmm 目标时?包裹? (不确定现在是什么)它不会再编译了。

进一步阅读我发现我无法将 main.swift 文件链接到测试目标。那种感觉是有道理的。它将有 2 个入口点:用于测试的入口点和我的主文件。 所以多读书。这就是我卡住的地方。 看来我需要将我的应用程序拆分为一个独立于主可执行文件的库/包,然后是另一个包含 main.swift 文件的工件。通过 Xcode 添加一个包会创建另一个具有自己测试的目标。所以我最终得到了 3 个工件(不确定它们实际上是什么):simple_appsimple_app_testssimple_app_package,它们还包含更多目标......对于这样一个简单的应用程序来说,事情变得过于复杂了.

大多数教程/书籍和 *** 问题都与 ios 开发更相关,并且由于某种原因这些解决方案不适用于我的案例或我不清楚。我不断收到链接错误,或者我最终为这样一个简单的应用程序创建了一个臃肿的项目。

所以我的问题是。有没有办法构建simple_app,这样我就可以编写测试和功能,而不会使项目的结构过于复杂?

注意:我知道有时可以将代码拆分为库和可执行文件(Rust 需要这种拆分)以便能够编译和运行测试。只需要一些关于如何在 swift 上正确完成的指导。 谢谢。

【问题讨论】:

我使用 swift 包管理器来执行此操作。我使用swift package init --type executable 创建一个可执行目标和一个测试目标,然后手动创建一个额外的库目标和可选的库测试目标。在我看来,第一个测试目标只是运行编译后的可执行文件——没有引用我编写的任何代码。我为库添加的测试目标可以访问我的代码,因此我可以自己测试小函数和方法。如果您想为 CLI 应用程序编写测试,您将需要一个可执行目标、一个库目标和至少一个测试。 另见swift-argument-parser。我倾向于使用它来编写我的可执行目标。可执行目标可能只有一两个文件,其余功能在库中实现。 【参考方案1】:

您不能对命令行工具主文件进行单元测试,因为它不是可测试的目标。

但是你可以测试一个框架。因此,制作一个框架目标,制作一个随附的单元测试目标,并将可测试的代码放入框架中。

但是,命令行工具不能包含框架;它只是源文件。所以框架的源文件也需要包含在命令行工具目标中。您没有将框架嵌入或链接到命令行工具中;这行不通。

所以命令行工具不把框架看成是一个框架,而只是把它看成与其自身相同的“模块”的一部分。同时,测试目标将框架视为它正在测试的内容。一切都很好。

我应该提到,这也是构建 GUI iOS 应用程序单元测试的好方法,因为测试不需要在模拟器中加载和运行应用程序。

更多讨论请见https://developer.apple.com/forums/thread/52211。

【讨论】:

我创建了一个小 GitHub 存储库示例,您可以下载并试用和学习。 github.com/mattneub/TestingCommandLineTool 很好的例子,谢谢。一个问题提醒。为什么是框架而不是包? 没有真正的原因,打包解决方案也可以!当我开始使用这种技术时,包并不存在。 :) 如果你只想测试一个特定的文件,你也可以在编译的源代码中链接那个文件来测试它们。

以上是关于什么是在 Swift 中构建 CLI 应用程序的好方法或常用方法的主要内容,如果未能解决你的问题,请参考以下文章

heroku 中的 vue-cli-service 构建失败

在构建角度cli时做错误做什么 - 内存不足问题

vue-cli

什么是在 Windows 环境中使用 shell 脚本的好 IDE? [关闭]

什么是在 C++ 中运行算法的内存使用实验的好方法?

DynamoDB 是 Swift 应用程序的好选择吗? [关闭]