通过关注正则表达式中定义的边界情况,从正则表达式生成样本数据以验证输入字符串

blo*_*aak 5 c# regex testing code-generation

有几种工具如何为给定的正则表达式生成样本数据.一些包括:

但是,虽然它们可能足以为数据集设定种子,但它对测试依赖于正则表达式本身的代码(例如验证)没有太大帮助.

假设您有一个代码生成器,可以生成带有属性的模型.用户指定正则表达式来验证属性.现在假设代码生成器正在尝试生成测试以确保验证成功并且适当地失败.该工具专注于正则表达式中的边界情况以避免生成不必要的数据似乎是合理的.

例如,考虑一个正则表达式^([a-z]{3,6})$然后边界情况包括:

  • 任何只包含[az]长度等于2的字符串(失败)
  • 任何只包含[az]长度等于3的字符串(成功)
  • 任何只包含[az]长度等于4的字符串(成功)
  • 任何只包含[az]长度等于5的字符串(成功)
  • 任何只包含[az]长度等于6的字符串(成功)
  • 任何只包含[az]长度等于7的字符串(失败)
  • 任何不包含[az]的字符串(失败)
  • 任何不以[az]开头但以[az]结尾的字符串(失败)
  • 任何以[az]开头但不以[az]结尾的字符串(失败)

关注边界情况的原因是任何仅由[az]组成的长度大于6的字符串都会验证正则表达式中定义的字符串长度的上边界.因此,测试长度为7,8,9的字符串实际上只是测试相同(边界)条件.

这是一个因其简单而选择的任意正则表达式,但任何合理的正则表达式都可以作为输入.

是否存在框架/工具,代码生成器可以使用它来为正在生成的系统的不同层的测试用例生成输入字符串.当系统不再在开发周期的后期生成和修改时,测试用例就会出现.

JDB*_*JDB 1

如果我正确理解您的问题,您希望根据验证正则表达式为系统生成输入,以便可以自动化单元测试。

但这是否违背了单元测试的目的?如果有人更改了正则表达式,您难道不希望验证失败吗?

无论如何,简单的答案是从正则表达式生成字符串几乎是不可能的。如果能做到的话,那将是极其复杂的。例如,考虑这个正则表达式:

(?<=\G\d{0,3})(?>[a-z]+)(?<=(?<foo>foo)|)(?(foo)(?!))
Run Code Online (Sandbox Code Playgroud)

对我来说,想到一个可以匹配(和/或生成匹配)的字符串非常简单:

abc123def456ghi789jkl123foo456pqr789stu123vwx456yz

比赛将是:

  • “abc”
  • “定义”
  • “吉”
  • “jkl”

但是如何从表达式生成字符串呢?没有明确的起点 - 它需要一些极端的(对于计算机而言)智力加上一点创造力才能找到解决方案。对于人类来说很简单,但对于计算机来说却非常非常困难。即使您可以想出一种可以生成匹配字符串的计算机算法,它也很容易看起来像这样:

A

这会生成一个匹配项,但它在执行正则表达式方面效果不佳。从未\d{0,3}真正尝试过,并且\G仅用于匹配输入的开头(而不是最后一个匹配的结尾)。(?<=(?<foo>foo))从未测试过(如果测试过,则会导致不匹配)。

生成不匹配的字符串也很容易:

1

但是,这并没有真正让正则表达式发挥作用。

我对计算机理论的了解不足以证明这一点,但我相信这属于P v NP 类问题。生成正则表达式来匹配复杂字符串的集合相对容易,但生成复杂字符串的集合来匹配正则表达式却很困难。