- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 SmallCheck测试 Haskell 程序,但我不明白如何使用该库来测试我自己的数据类型。显然,我需要使用 Test.SmallCheck.Series .但是,我发现它的文档非常困惑。我对菜谱式的解决方案和对逻辑(monadic?)结构的可理解解释都感兴趣。以下是我的一些问题(所有相关问题):
如果我有一个数据类型 data Person = SnowWhite | Dwarf Integer
,我该如何解释smallCheck
有效值为 Dwarf 1
通过Dwarf 7
(或 SnowWhite
)?如果我有一个复杂的 FairyTale
怎么办?数据结构和构造函数 makeTale :: [Person] -> FairyTale
,我想要 smallCheck
使用构造函数从 Person-s 列表中创建 FairyTale-s?
我设法做到了 quickCheck
通过使用 Control.Monad.liftM
的明智应用,这样不会弄脏我的手像makeTale
这样的功能.我想不出用 smallCheck
来做到这一点的方法(请向我解释一下!)。
类型之间有什么关系Serial
, Series
等等?
(可选)coSeries
的意义是什么? ?我如何使用 Positive
从 SmallCheck.Series
输入?
(可选)任何关于在 smallCheck 上下文中什么是单子(monad)表达式背后的逻辑以及什么只是常规函数的说明,我们将不胜感激。
如果有任何使用 smallCheck
的介绍/教程,我会很感激一个链接。非常感谢!
更新:我应该补充说,我为 smallCheck
找到的最有用和最易读的文档是this paper (PDF) .乍一看,我找不到问题的答案;它更像是一个有说服力的广告,而不是一个教程。
更新 2: 我提出了关于奇怪的 Identity
的问题以 Test.SmallCheck.list
的类型显示和其他地方到separate question .
最佳答案
注意:此答案描述的是 SmallCheck 1.0 之前的版本。参见 this blog post了解 SmallCheck 0.6 和 1.0 之间的重要区别。
SmallCheck 与 QuickCheck 相似,因为它测试可能类型空间的某些部分上的属性。不同之处在于,它试图详尽列举一系列所有“小”值,而不是小值的任意子集。
正如我所暗示的,SmallCheck 的 Serial
就像 QuickCheck 的 Arbitrary
。
现在 Serial
非常简单:Serial
类型 a
有一种方法 (series
) 可以生成一个Series
类型,它只是 Depth -> [a]
中的一个函数。或者,要解包,Serial
对象是我们知道如何枚举一些“小”值的对象。我们还获得了一个 Depth
参数,它控制我们应该生成多少小值,但让我们暂时忽略它。
instance Serial Bool where series _ = [False, True]
instance Serial Char where series _ = "abcdefghijklmnopqrstuvwxyz"
instance Serial a => Serial (Maybe a) where
series d = Nothing : map Just (series d)
在这些情况下,我们只是忽略 Depth
参数,然后为每种类型枚举“所有”可能的值。我们甚至可以为某些类型自动执行此操作
instance (Enum a, Bounded a) => Serial a where series _ = [minBound .. maxBound]
这是一种非常简单的彻底测试属性的方法——逐字逐句地测试每一个可能的输入!显然,至少存在两个主要缺陷:(1) 无限数据类型在测试时会导致无限循环,以及 (2) 嵌套类型导致需要查看的示例空间呈指数增长。在这两种情况下,SmallCheck 都会很快变大。
这就是 Depth
参数的要点——它让系统要求我们保持 Series
较小。从文档中,Depth
是
Maximum depth of generated test values
For data values, it is the depth of nested constructor applications.
For functional values, it is both the depth of nested case analysis and the depth of results.
所以让我们修改我们的例子以保持它们的小。
instance Serial Bool where
series 0 = []
series 1 = [False]
series _ = [False, True]
instance Serial Char where
series d = take d "abcdefghijklmnopqrstuvwxyz"
instance Serial a => Serial (Maybe a) where
-- we shrink d by one since we're adding Nothing
series d = Nothing : map Just (series (d-1))
instance (Enum a, Bounded a) => Serial a where series d = take d [minBound .. maxBound]
好多了。
那么什么是系列
?就像 QuickCheck 的 Arbitrary
类型类中的 coarbitrary
一样,它让我们构建了一系列“小”函数。请注意,我们在输入类型上编写实例——结果类型在另一个 Serial
参数中传递给我们(我在下面调用 results
)。
instance Serial Bool where
coseries results d = [\cond -> if cond then r1 else r2 |
r1 <- results d
r2 <- results d]
这些需要更多的独创性来编写,实际上我会推荐你使用我将在下面简要描述的 alts
方法。
那么我们如何制作一些 Series
的 Person
呢?这部分很简单
instance Series Person where
series d = SnowWhite : take (d-1) (map Dwarf [1..7])
...
但是我们的 coseries
函数需要生成从 Person
到其他东西的所有可能的函数。这可以使用 SmallCheck 提供的 altsN
系列函数来完成。这是一种写法
coseries results d = [\person ->
case person of
SnowWhite -> f 0
Dwarf n -> f n
| f <- alts1 results d ]
基本思想是 altsN results
从 N
值生成 Series
的 N
元函数Serial
实例到 Results
的 Serial
实例。所以我们用它来创建一个函数,从 [0..7],一个先前定义的 Serial
值,到我们需要的任何东西,然后我们将我们的 Person
映射到数字和把它们传进去。
现在我们有了 Person
的 Serial
实例,我们可以用它来构建更复杂的嵌套 Serial
实例。对于“实例”,如果 FairyTale
是 Person
的列表,我们可以在我们的旁边使用 Serial a => Serial [a]
实例Serial Person
实例轻松创建Serial FairyTale
:
instance Serial FairyTale where
series = map makeFairyTale . series
coseries results = map (makeFairyTale .) . coseries results
((makeFairyTale .)
将 makeFairyTale
与 coseries
生成的每个函数组合在一起,这有点令人困惑)
关于testing - 如何在 Haskell 中使用 SmallCheck?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16555291/
我使用 apt-get install libgtest-dev 安装了 gtest 我正在尝试检查它是否有效。 所以我在 eclipse 中编写了简单的测试代码。 但是有错误, undefined
($test) = (@test); $test = @test; 用一个括号括住变量,它访问数组的第一个元素。我找不到有关数组括号的信息。 最佳答案 ($test) = (@test); 这会将@t
在 clojure.test 中有一个允许同时测试多个设备的宏: are . 在 clojure.test 中,可以结合 are宏与 testing ? IE。就像是: (are [scenario
通常,Rust 中的单元测试被赋予一个单独的模块,该模块使用 #[cfg(test)] 进行条件编译: #[cfg(test)] mod tests { #[test] fn test
在过去,编程很少涉及猜测。我会写几行代码,一眼就能 100% 确定代码做什么和不做什么。错误主要是拼写错误,但与功能无关。 我相信在过去的几年中存在这种“试错”编程的趋势:编写代码(就像在草稿中一样)
在building the Kotlin compiler之后(在提交e80a01a处): ./gradlew dist 测试未成功通过: ./gradlew compiler:test 由于很少有测
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
最近一直在思考模糊测试和猴子测试的区别。根据 wiki,猴子测试似乎“只是”一个单元测试,而模糊测试则不是。安卓有 UI/Application Exerciser monkey而且它看起来不像是单元
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
现在我正在使用 CMake 设置一个 C++ 测试环境。其实我已经意识到我想做什么,但我对两种不同的测试输出风格感到困惑。在我下面的示例中,“make test”实际上做了什么?我认为“make te
在 VS2012 中运行单个测试时,测试资源管理器底部会显示一个窗口,其中包括(假设失败)旁边带有“测试失败”的红色图标。紧随其后的是带有“已用时间”的失败消息。 我想简单地知道是否有办法清除这个窗口
bash 是否可以从 shell 执行命令,如果它返回某个值(或空值)则执行命令? if [ "echo test" == "test"]; then echo "echo test output
这个问题在这里已经有了答案: 8年前关闭。 Possible Duplicate: What is a smoke testing and what will it do for me? 为什么“冒烟
x86 下的并行编程可能很困难,尤其是在多核 CPU 下。假设我们有多核 x86 CPU 和更多不同的多线程通信组合。 单一作者和单一读者 单个读者多个作者 多个读者和单个作者 多个读者和多个作者 那
我使用Ctest来运行一堆使用add_test()注册的Google测试。当前,这些测试没有任何参数。但是,我想在运行--gtest_output=xml时为它们提供所有参数(所有参数都通用,特别是c
我有下表和数据: CREATE TABLE `test` ( `id` int(11) NOT NULL auto_increment, `name` varchar(8) NOT NULL,
go test 的两个标志 -parallel 和 -test.parallel 之间的区别以及哪个标志优先? -parallel n Allow parallel execu
在我的组件 AudioPlayer 中,我有一个 download() 方法: download() { this.audio.pause(); window.open(this.file,
您必须承认,对于 Rails 和数据库的新手来说,rubyonrails.org 上的官方解释使所有这四个任务听起来完全一样。引用: rake db:test:clone Recreate the
我过去曾讨论过这个话题,我想我可能知道答案,但我无法正确地表达出来。 这是我认为我所知道的: 如果您在编写测试之前已经有了关于事情如何工作的想法,那么我怀疑您是测试优先而不是测试驱动,因此您首先编写测
我是一名优秀的程序员,十分优秀!