C#,xunit,fscheck,使用自定义生成器或受约束的随机字符串编写基于简单属性的测试
问题描述:
我正在尝试解决钻石kata以了解如何使用fscheck库编写基于属性的测试。我想用C#编写测试,我正在使用Visual Studio 2017.C#,xunit,fscheck,使用自定义生成器或受约束的随机字符串编写基于简单属性的测试
我想编写一个基于属性的测试,它不会生成任何随机字符作为输入,而只是字母。我不知道如何编写生成器fscheck需要执行此操作以及在哪个文件中放置代码?
我到处搜索和阅读文档,但有麻烦(部分原因是我不能很好地将F#翻译成C#)。
[Property]
如何将输入数据限制为仅字母?
如果有更好的方法,请让我知道。
[编辑:]
我编辑我的代码的例子,其现在包含由库尔特Schelfthout一个工作溶液。
测试
using DiamondKata;
using FsCheck;
using FsCheck.Xunit;
using Xunit;
namespace DiamondKataTests
{
public static class Arbitraries
{
private static readonly string upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static readonly string lowerAlphabet = ""; //upperAlphabet.ToLower();
private static readonly char[] wholeAlphabet = (lowerAlphabet + upperAlphabet).ToCharArray();
public static Arbitrary<char> LetterGenerator()
{
return Gen.Elements(wholeAlphabet).ToArbitrary();
}
}
public class DiamondKataTests
{
// THIS WORKS and is apparently the preferred way of doing things
// also see here: https://*.com/questions/32811322/fscheck-in-c-generate-a-list-of-two-dimension-arrays-with-the-same-shape
[Property()]
public Property shouldReturnStringAssumesValidCharWasProvided()
{
return Prop.ForAll(Arbitraries.LetterGenerator(), letter =>
// test here
Assert.NotNull(Diamond.Create(letter))
);
}
// Second solution ...
// Error here: Arbitraries is a type not valid in the given context
[Property(Arbitrary = new[] { typeof<Arbitraries> })]
public void testThatAssumesValidCharWasProvided(char lettersOnlyHERE)
{
// ?
}
}
}
类来测试
namespace DiamondKata
{
public class Diamond
{
public static string Create(char turningPointCharacter)
{
return "";
}
}
}
答
你不能把限制在ttributes,可以传递给属性的类型仅限于这样做。
您有几个选项。您可以为char
定义一个自定义Arbitrary
实例,即实现Arbitrary<char>
并配置该属性以使用该实例。
public static class Arbitraries
{
public static Arbitrary<char> LetterGenerator()
{
return Gen.Elements(wholeAlphabet).ToArbitrary();
}
}
public class DiamondKataTestClass1
{
[Property(Arbitrary=new[] { typeof<Arbitraries> })]
public void testThatAssumesValidCharWasProvided(char lettersOnlyHERE)
{
// ?
}
}
您还可以使用更灵活的API定制生成在线:
public class DiamondKataTestClass1
{
[Property()]
public Property testThatAssumesValidCharWasProvided()
{
Prop.ForAll(Arbitraries.LetterGenerator()) (letter =>
// test here
)
}
}
非常感谢您的回复,很遗憾,您的解决方案给我的错误。我编辑了上面的帖子,其中包括您的代码和评论,我得到的错误...谢谢! – Shakka
找到了我自己的一个错误的修复方法,你的语法稍微偏离了,我冒昧地修改了你的解决方案,再次感谢你! – Shakka