数据列表作为specflow测试步骤中的参数

时间:2014-05-20 11:31:47

标签: c# regex bdd specflow acceptance-testing

我正在寻找一种方法来进行步骤定义,例如:

给出一组数字1,2,3,4

并使用int [],List或IEnumerable

将其映射到步骤定义

正则表达式(\ d +(,\ d +)*)匹配,但意味着我需要两个参数。

目前我有

[Given(@"a collection of numbers (\d+(,\d+)*)")]
public void givencollectionofnumbers(string p0, string p1)
{
    //p0 is "1,2,3,4"
    //p1 is ",4"
}

我有一个简单的工作流程

[Given(@"a collection of numbers (.*)")]
public void givencollectionofnumbers(string p0)
{
    var numbers = p0.Split(',').Select(x => int.Parse(x));
}

但是我希望以更优雅的方式执行此操作,可能会将数字类型更改为双精度数,并确保正则表达式仅匹配数字列表。

我也不想使用表格,因为对于简单的数据列表来说它似乎过多了

任何人都可以帮忙解决这个问题。

2 个答案:

答案 0 :(得分:5)

我只是在我的项目中解决了同样的问题:这将解决问题

((?:.,\d+)*(?:.\d+))

如果你也想接受单个int,请改用:

((?:.,\d+)*(?:.+))

你的命题存在两个问题:

  • 当您只需要1时,Specflow会尝试将其匹配为2个参数。但我无法在文档中找到明确说明原因的原因

  • 你肯定需要一个StepArgumentTransformation来转换任何可枚举的输入字符串

所以你的最后一步功能将是这样的:

[Given(@"foo ((?:.,\d+)*(?:.+))")]
public void Foo(IEnumerable<int> ints)
{
}

[StepArgumentTransformation(@"((?:.,\d+)*(?:.+))")]
public static IEnumerable<int> ListIntTransform(string ints)
{
    return ints.Split(new[] { ',' }).Select(int.Parse);
}

你在Foo函数中收到一个Enumerable int。

希望它有所帮助。

答案 1 :(得分:1)

我碰到了类似的东西,这就是我们想出来的。关键问题是每个'('SpecFlow看到会创建一个新参数。在这种情况下,你只需要添加一个非捕获组,'(?:'。

My RegEx Cookbook

正如Ouzrzy在他的回答中写道,你可以添加一个步骤arg变换来保持签名更简单,或者在我下面记录的步骤中进行。

<强>句

Scenario: All of these sentences match below definition
    Then The quick red fox jumped over '10, 20, 30' lazy dogs
    Then the quick brown fox jumped over '10,20' lazy dogs
    Then the quick brown fox jumped over '1' lazy dog

最佳实践:所有参数(包括整数)都应该用单引号括起来。这增加了可读性并减少了模糊匹配的可能性。

<强>定义

[Then(@"(?i)t(?-i)he quick (?:brown|red) fox jumped over '(?x)((?:\d+,)*\d+)(?-x)' lazy dogs?")]
public void ThenTheQuickBrownFoxJumpedOverLazyDog(string countCsv)
{
    Console.WriteLine("sum of " + countCsv + " = ");
    var countCollection = countCsv.Split(',').Select(int.Parse);
    Console.WriteLine(countCollection.Sum());
}

最佳实践:永远不要保留自动定义的参数名称。您的参数名称不仅应该描述其类型(int,string等),还应该描述您期望的数据类型(计数,文件名等)。