在反应性香蕉中进行测试

2024-03-21

有没有办法对用反应性香蕉创建的网络进行单元测试?假设我已经使用一些输入事件建立了一些网络 - 是否可以验证事件已产生一些输出流/行为在一定数量的输入事件之后具有一定的价值。这样做有意义吗?

我注意到有各种interpret*功能,但似乎无法弄清楚如何使用它们。还有Model模块看起来非常适合测试,但与实际实现的类型完全不同。


当你说“单元测试”时,我想象的是类似的东西QuickCheck,您可以将多个输入注入网络并检查输出。为了做到这一点,我们需要一个类似以下的函数:

evalNetwork :: Network a b -> [a] -> IO [b]

在这个答案的最后,我展示了其中一个的变体interpret*对于特定类型的“网络”,具有类似类型的函数。

胡言乱语reactive-banana网络类型

这样的功能与实际使用的“整个网络”类型不兼容reactive-banana。对比类型actual涉及网络的函数:

compile :: (forall t. Frameworks t => Moment t ()) -> IO EventNetwork

所以任意网络的类型都是forall t. Frameworks t => Moment t ()。没有类型变量;没有输入或输出。同样,EventNetwork类型没有参数。这告诉我们所有的输入和输出都是通过副作用来处理的IO。这也意味着不可能有像这样的函数

interpret? :: EventNetwork -> [a] -> IO [b]

因为什么会a and b be?

这是设计的一个重要方面reactive-banana。例如,它使得编写到命令式 GUI 框架的绑定变得容易。的魔力reactive-banana就是将所有副作用混入文档中所说的“一个巨大的回调函数”。

此外,事件网络通常与 GUI 本身密切相关。考虑Arithmetic example https://github.com/HeinrichApfelmus/reactive-banana/blob/master/reactive-banana-wx/src/Arithmetic.hs, where bInput1 and bInput2都是使用实际的输入小部件构建的,并且输出绑定到output,另一个小部件。

可以像其他语言一样使用“模拟”技术来构建测试工具。您可以将实际的 GUI 绑定替换为类似的绑定pipes-concurrency。我还没听说有人这样做。

如何进行单元测试:抽象出逻辑

更好的是,您可以而且应该在单独的函数中编写尽可能多的程序逻辑。如果您有两个输入,类型inA and inB,以及一个类型的输出out,也许你可以写一个像这样的函数

logic :: Event t inA -> Event t inB -> Behavior t out

这几乎是正确的使用类型interpretFrameworks:

interpretFrameworks :: (forall t. Event t a -> Event t b) ->
                       [a] -> IO [[b]]

您可以组合两个输入Events using split(或者更确切地说,将输入分成两个Events 所要求的logic)。现在你会有logic' :: Event t (Either inA inB) -> Behavior t out.

你有点阻碍转换输出Behavior to an Event。在 0.7 版本中,changes函数于Reactive.Banana.Frameworks有类型Frameworks t => Behavior t a -> Moment t (Event t a),你可以用它来打开Behavior,尽管你必须在Moment单子。然而,在 0.8 版本中,a被包裹成Future a, where Future是未导出的类型。 (有一个Github 重新导出的问题Future https://github.com/HeinrichApfelmus/reactive-banana/issues/70.)

最简单的解开方法Behavior可能只是重新实现interpretFrameworks使用适当的类型。 (请注意,它返回一个包含初始值和后续值列表的元组。)Future没有导出,您可以使用它Functor实例:

interpretFrameworks' :: (forall t. Event t a -> Behavior t b) 
                        -> [a] -> IO (b, [[b]])
interpretFrameworks' f xs = do
    output                    <- newIORef []
    init                      <- newIORef undefined
    (addHandler, runHandlers) <- newAddHandler
    network                   <- compile $ do
        e <- fromAddHandler addHandler
        o <- changes $ f e
        i <- initial $ f e
        liftIO $ writeIORef init i
        reactimate' $ (fmap . fmap) (\b -> modifyIORef output (++[b])) o

    actuate network
    bs <- forM xs $ \x -> do
        runHandlers x
        bs <- readIORef output
        writeIORef output []
        return bs
    i <- readIORef init
    return (i, bs)

这应该可以解决问题。

与其他FRP框架的比较

将此与 Gabriel Gonzalez 等其他框架进行对比mvc http://hackage.haskell.org/package/mvc或 Ertugrul Söylemez 的netwire http://hackage.haskell.org/package/netwire. mvc要求您将程序逻辑编写为有状态但纯粹的Pipe a b (State s) (), and netwire网络有类型Wire s e m a b;在这两种情况下的类型a and b公开网络的输入和输出。这使您可以轻松进行测试,但排除了可用的“内联”GUI 绑定reactive-banana。这是一个权衡。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在反应性香蕉中进行测试 的相关文章

随机推荐

  • 使用具有大数据集的 SciPy 曲线拟合库时出现运行时错误

    如何使用 SciPy 曲线拟合函数拟合高斯曲线来关闭此错误 换句话说 如果它不适合模型峰值 那么它就不是峰值 所以我不想返回任何东西 另外 有没有更快的方法 curve fit 对于我的应用程序查看大量数据来说可能太慢 运行时错误 未找到最
  • 根据同级值与 XPath 匹配节点

    有一个像这样的 XML 文档
  • static >

    我有以下带有一个静态方法的类 public class Helper public static
  • React js onclick 地图函数中的切换类

    如何处理映射列表 dom 中的切换类 onclick 函数 this state data map function el i var className self state condition list row active inact
  • 将变量数组转换为字符串

    我正在尝试使用 vba 将变量数组转换为字符串 我尝试了两种方法 但都不起作用 它们似乎都在同一点上阻塞 Dim cell As Range Dim val As Variant For Each cell In Range packing
  • 将 JavaScript 类导入另一个类时出现意外的标识符 {classname}

    我正在使用 Node v10 11 0 并从 Ubuntu 18 04 运行此脚本 我的文件设置如下所示 main js import Login from Login mjs class Main constructor const lo
  • 将:click 事件传递到动态创建的

    我基本上需要能够触发一个或多个组件中的某些内容 即 当父级中的图标 按钮时通过 svelte component 动态添加 单击组件 例如我需要挂钩下面用 表示的部分 each charts as chart i div class wra
  • 具有链接时代码生成功能的 MSVC 能否跨 C 和 C++ 进行优化?

    If 链接时代码生成 LTCG https learn microsoft com en us cpp build reference ltcg link time code generation与 MSVC 一起使用时 是否可以跨 C 和
  • 使用 Facebook Graph API 和 HybridAuth 获取好友位置

    Problem 我想得到friends location来自 Facebook Graph API 我正在使用以下方式访问 API混合认证 http hybridauth sourceforge net 框架 如何返回朋友的位置 家乡等 我
  • 带箭头刻度的 Matplotlib 曲线

    我想知道是否可以绘制一条曲线matplotlib带有箭头刻度 就像是 from pylab import y linspace 0 10 0 01 x cos y plot x y gt 应该有这样的曲线 gt gt gt 当 x 增加时
  • JPA 检查实体是否可以删除

    如何检查JPA中的实体是否可以删除并且不会抛出数据完整性异常 我想到的唯一方法是一一检查所有引用的实体 或者尝试在事务中删除然后回滚 但是还有其他更简单的方法吗 如果 可以删除 的意思是 如果实体存在于持久性上下文中 那么您已经回答了您的问
  • iPhone ASIHTTP - 区分 API 调用?

    我目前有一个视图控制器 它实现 ASIHTTP 来处理 API 调用 我的视图控制器触发了 2 个单独的调用 我需要能够区分 requestFinished ASIHTTPRequest request 方法中的两个调用 这样我就可以相应地
  • AWS Step Functions:使用 JsonPath 过滤数组

    我需要在 AWS Step Functions 状态下过滤数组 这似乎是我应该可以使用 JsonPath 轻松实现的目标 但由于某种原因我正在努力 我想要处理的状态如下所示 items id A id B id C 我想通过删除其中的条目来
  • 将表数据存储到 jquery 变量

    我想将表中的数据存储到 jquery 变量中 我使用的代码如下 但此代码将所有表标签 如 tr td 和所有内容 存储到变量中 因为我只需要将数据存储在 td 中以文本格式标记到 jquery 变量 有人可以帮忙吗 var table my
  • 检查 Firebase 实时数据库中是否已存在用户

    我得到了亚历克斯 马莫的解决方案 https stackoverflow com a 47893879 4176989为了检查我的数据库中是否存在唯一值 但快照始终为空 解决方案在这里 DatabaseReference rootRef F
  • WebConfigurationManager.AppSettings 的缓存?

    我有很多读取我的 Web 配置文件的请求 variable WebConfigurationManager AppSettings BLAH Do WebConfigurationManager AppSettings每次都从磁盘读取 还是
  • Go中从IP地址获取域名

    我正在尝试从 IP 地址解析主机名 这显然比我想象的更具挑战性 我尝试过使用几个函数 包括net LookupHost方法 但它们似乎都只是返回我输入的IP地址 这是我正在使用的代码 package main import fmt net
  • 作用域 bean:将一个 bean 注入另一个 bean

    如何在没有代理的情况下将会话范围 bean 注入另一个会话范围 bean Component Scope session class Foo Inject Bar bar Component Scope session class Bar
  • 如何在Python中浏览内存中的sqlite数据库

    我需要使用内存中的 sqlite 数据库和以下构造函数 db sqlite3 connect memory 但在调试时 我发现它非常不方便 因为与基于文件的数据库不同 我无法在调试器中浏览数据库 有没有办法即时浏览这个数据库 您可以在调试器
  • 在反应性香蕉中进行测试

    有没有办法对用反应性香蕉创建的网络进行单元测试 假设我已经使用一些输入事件建立了一些网络 是否可以验证事件已产生一些输出流 行为在一定数量的输入事件之后具有一定的价值 这样做有意义吗 我注意到有各种interpret 功能 但似乎无法弄清楚