haskell - 使用来自 Tasty 的 Warp 的 `testWithApplication`
问题描述
Tasty只有withResource功能来管理测试中的资源。
该函数将资源初始化和清理函数作为参数:
withResource :: IO a -> (a -> IO ()) -> TestTree -> TestTree
我正在尝试测试一个仆人应用程序,所以我想使用Warp.testWithApplication
每个仆人的测试教程,但这是一个with*
风格的函数(一个调用你的动作并为你管理资源的函数),即类型是:
testWithApplication :: IO Application -> (Port -> IO a) -> IO a
考虑到我没有初始化程序/清理函数而是包装with...
函数,我是否遗漏了一些东西,或者真的很难将两者粘合在一起?
笔记
我知道我可以用testWithApplication
(in main
) 包装整个测试套件,但如果 API 仅针对需要它的 TestTree 启动,我更愿意。
解决方案
我知道我可以用 testWithApplication (在 main 中)包装整个测试套件,但如果 API 仅针对需要它的 TestTree 启动,我更愿意。
是的,所以有两种不同的方法可以实现这一点。
一种方法是链接教程对 Hspec 的作用around
:为每个单独的测试启动和停止您的应用程序。
Tasty 没有为此用例提供单独的实用程序,因为自己做这件事相当简单:只需testWithApplication
在每个内部调用testCase
(或者您可以为组合定义一个别名testCase
并testWithApplication
节省一些输入)。但是,如果您对同一个应用程序有多个测试,您可能会认为为每个单独的测试启动和停止它有点浪费。
这就是美味withResource
(或 HSpec aroundAll
)的用武之地。当您使用它时,应用程序会在需要它的第一个测试之前启动,并在最后一次此类测试之后立即停止。
但这主要依赖于资源的动态范围——即我们事先不知道资源将按什么顺序分配或取消分配。(如果您将执行测试套件视为遍历测试树并按顺序运行所有测试,这可能看起来令人惊讶。但由于并行测试执行和测试之间的依赖关系,实际情况更加复杂,因此实际执行顺序可以是任意的。 )
并且该动态范围与“with”风格的函数不兼容,后者通常只创建嵌套的、类似堆栈的范围。
所以你的选择是:
- 在顶层启动一个应用程序并让它在整个测试套件期间运行(您在问题中描述的内容)。
- 在底层(即在每个
testCase
)启动和停止应用程序,这是链接教程对 Hspec 所做的。 - 不要使用
testWithApplication
,而是编写单独的函数来启动和停止应用程序。testWithApplication
与单独的获取/释放函数相比,它的吸引力在于它为您处理异常并确保释放操作将运行,但美味已经处理好了。 - 最后,我在Decompose ContT中描述了一个技巧,它使用线程通过“with”风格的函数(相当于 ContT 值)实现动态范围。
testWithApplication
如果分解成单独的获取/释放操作太麻烦,这可能是最实用的解决方案。HSpec 的aroundAll似乎也在使用类似的和基于线程的东西。
推荐阅读
- angular - Primeng P-calendar issue (UTC)
- php - Slim 框架给出了一个令人困惑的未捕获类型错误
- php - MySQL数据库的PHP编辑表单
- c++ - grpc builder.BuildAndStart() 挂在 aarch64 但不是 x86_64
- bash - 将参数的值传递给 shell 函数只打印参数的名称
- python - __init__ 中的成员分配和引用计数
- mysql - 从下面给出的示例数据中,删除姓名和年龄组合上的重复项并打印结果
- javascript - 我想在 javascript 中计算数据的众数、中位数和标准差
- python-3.x - ValueError:必须是坐标对或点
- c# - 是否可以从来自 webjob 的 webapp 获取环境变量