当我谷歌如何将单元测试与cabal文件集成时,我发现
如何使用cabal运行所有单元测试(例如,每次我进行"cabal build")?
我正在寻找一个Java工具,可以在我的测试中创建匿名变量(我不关心它的值的变量),类似于.Net中的AutoFixture.这是AutoFixture自述文件的链接,它有很好的例子.
以下是同一自述文件中的简短示例:
[TestMethod]
public void IntroductoryTest()
{
// Fixture setup
Fixture fixture = new Fixture();
int expectedNumber = fixture.CreateAnonymous<int>();
MyClass sut = fixture.CreateAnonymous<MyClass>();
// Exercise system
int result = sut.Echo(expectedNumber);
// Verify outcome
Assert.AreEqual<int>(expectedNumber, result, "Echo");
// Teardown
}
Run Code Online (Sandbox Code Playgroud)
Java世界中有这样的工具吗?
编辑:
我尝试过QuickCheck,虽然它设法做了我想要的事情:
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;
import net.java.quickcheck.generator.support.ObjectGeneratorImpl;
public class Main {
interface Test{
String getTestValue();
}
public static void main(String[] args) {
Generator<String> stringGen = PrimitiveGenerators.strings(5, 100);
Generator<Integer> intGen = PrimitiveGenerators.integers(5, 20);
ObjectGeneratorImpl<Test> g = …Run Code Online (Sandbox Code Playgroud) 我有一组简单的演示程序,它们编码/解码字符串,并希望为它们生成一些quickCheck测试,但是只能将测试限制为可打印的字符串.由于生成和拒绝的测试用例太多,使用防护太慢而失败,因此我想为此域创建一个安全的生成器.
我已经看到了这个引用说:(1)定义了自己的任意实例字符,并用它来生成字符串只可打印字符,或(2)有包装器函数本身的NEWTYPE,写一个任意实例.
但是尝试做(1)它失败了,因为现在在Test.QuickCheck中有这个定义,所以如何做到这一点 - 为新类型创建一个safeChar生成器然后再次必须为测试函数生成一个适配器?(关于此的RWH书籍部分指出,它推荐这个DIY Char定义已过时.)
尝试做(2)似乎我可以只为测试命题添加一个本地化和简单(但失败)的保护,或者编写一个新的包装器和相关的生成器,这似乎更加混乱.
显然这很简单(!)并且提供了所有工具,但有人可能会建议这是否是正确的分析,并举例说明如何做到这一点?
我偶尔会看到有人说QuickCheck中的Gen类型不遵守monad法则,尽管我没有看到很多解释.现在,QuickCheck 2.7的Test.QuickCheck.Gen.Unsafe模块说Gen只是"道德上"的monad,但简短的解释让我挠头.你能否一步一步地说明Gen如何违反monad法律?
我有一个cabal包,可以导出一个NBT可能对其他开发人员有用的类型.我经历了Arbitrary为我的类型定义一个实例的麻烦,如果没有将它提供给其他开发人员来测试他们整合我的工作的代码,那将是一种耻辱.
但是,我想避免我的实例可能妨碍的情况.也许其他开发人员对实例应该是什么有不同的想法Arbitrary.也许我的软件包依赖于特定版本的QuickCheck可能会干扰或不需要客户端项目的依赖项.
我的想法没有特别的顺序,是:
Arbitrary实例保留在类型定义旁边,让客户端处理实例的阴影或覆盖QuickCheck版本号.Arbitrary实例在同一封装内的单独的模块孤儿例如,假设Data.NBT.Arbitrary.QuickCheck对整个包的依赖性仍然存在.Arbitrary在完全独立的包中提供实例,以便可以将其列为客户端项目的单独测试依赖项.Arbitrary在主包中包含实例和QuickCheck依赖项,但仅在-ftest设置了类似标志的情况下.我已经看到所有这些在其他库中使用的组合,但没有找到任何最佳工作的共识.我想在上传到Hackage之前尝试正确使用它.
我写了一个算法来找到Haskell中子集求和问题的解决方案.签名是
subsetSum :: (Ord a, Num a) => [a] -> a -> Maybe [a]
Run Code Online (Sandbox Code Playgroud)
QuickCheck似乎非常适合测试它.例如,我在这里是我可以检查的属性之一:
prop_sumEqualsS l s = case subsetSum l s of
Just solution -> (sum solution) == s
Nothing -> True
Run Code Online (Sandbox Code Playgroud)
问题是该算法计算量很大,运行100个大输入列表的测试需要很长时间才能运行.
我尝试使用QuickCheck 1并且确实运行得很快,但用于测试的数据集非常小.转移到QuickCheck 2后,似乎是相反的问题.有QC 手册,但它似乎很旧(没有日期信息),我不知道QC2还有多少适用.Haskell Wiki上提供了一个教程,但没有太多细节,只有几个关于实例化的文字Arbitrary.
所以我有两个问题:
编辑:更具体地说,我想测试我的解决方案,列表大小从0到100,包含-10000到10000之间的整数.
在使用QuickCheck测试Monadic代码时(Claessen,Hughes 2002),assert有类型:
assert :: (Monad m, Testable a) => a -> PropertyM m ()
Run Code Online (Sandbox Code Playgroud)
但是,在Test.QuickCheck.Monadic,它有类型:
assert :: (Monad m) => Bool -> PropertyM m ()
Run Code Online (Sandbox Code Playgroud)
为什么assert在库中有后一种类型?
我想知道什么是物业测试目标,它的甜点是什么,应该在哪里使用.让'有一个我想测试的示例函数:
f :: [Integer] -> [Integer]
Run Code Online (Sandbox Code Playgroud)
这个函数f采用一个数字列表,并将奇数数字平方并滤除偶数.我可以陈述一些关于函数的属性,比如
没有属性测试,该函数适用于最简单的情况,例如我可以做一个简单的情况,如果我实现f错误将传递这些属性:
f = fmap (+2) . filter odd
Run Code Online (Sandbox Code Playgroud)
所以,如果我想介绍一些简单的情况,看起来我需要在属性规范中重复算法的基本部分,或者我需要使用基于值的测试.重复算法的第一个选项可能是有用的,如果我打算改进算法,如果我计划改变它的实现,例如速度.通过这种方式,我有一个参考实现,我可以用来再次测试.
如果我想检查一下,算法不会因某些微不足道的情况而失败,我不想在规范中重复算法,看起来我需要一些单元测试.我会写例如这些检查:
f ([2,5]) == [25]
f (-8,-3,11,1) == [9,121,1]
Run Code Online (Sandbox Code Playgroud)
现在我对算法有了更多的信心.
我的问题是,基于属性的测试是否意味着要取代单元测试,还是它是互补的?是否有一些一般性的想法,如何编写属性,所以它们是有用的还是完全取决于对函数逻辑的理解?我的意思是,可以说,以某种方式写出属性特别有益吗?
此外,是否应该努力使属性测试算法的每个部分?我可以把算法放在一边,然后在其他地方进行测试,让属性只测试过滤部分,它看起来很好,它可以很好地覆盖它.
f :: (Integer -> Integer) -> [Integer] -> [Integer]
f g = fmap g . filter odd
Run Code Online (Sandbox Code Playgroud)
然后我可以通过单独Prelude.id测试来测试g其他地方.
有没有可以从QuickCheck1转换为QuickCheck2的食谱?
作为一些例子,defaultConfig(替换为Args)trivial并被删除和CoArbitrary介绍.
假设我想为(!!)函数编写一些单元测试.
my_prop xs n = ...
Run Code Online (Sandbox Code Playgroud)
我想将n限制为仅有效的索引,我知道我可以做类似的事情
my_prop xs n = (not.null) (drop n xs) ==> ...
Run Code Online (Sandbox Code Playgroud)
但这使得绝大多数生成的案例都无效并被抛弃.有没有办法我可以设置,以便QuickCheck xs首先生成列表并使用其值只生成有效的情况n?