我是TDD的新手,我发现RegExp非常特殊.是否有任何特殊的单元测试方法,或者我可以将它们视为常规功能?
你应该总是测试你的regexen,就像任何其他代码块一样.它们是一个最简单的函数,它接受一个字符串并返回一个bool,或者返回一个值数组.
以下是关于为regexen设计单元测试时要考虑什么的一些建议.这些并不是单元测试设计的硬性和快速处方,而是一些塑造您思路的指导方针.与往常一样,将测试需求与故障成本进行权衡,并与实施所有测试所需的时间进行权衡.(我发现"实施"测试很容易!: - ])
需要考虑的要点:
将每个组(括号)视为大括号.
想想每一个| 作为一个条件.确保测试每个分支.
将每个修饰符(*,+,?)视为不同的路径.
(注意以上事项:记住*,+,?和*?,+?和??之间的区别.)
对于\ d,\ s,\ w和它们的否定,尝试在每个范围中给出几个.
对于*和+,您需要测试每个的"无值","其中一个"和"一个或多个".
对于重要的"控制"字符(例如,你要查找的正则表达式中的字符串)测试,看看如果它们出现在错误的地方会发生什么.这可能会让你感到惊讶
如果您有真实世界的数据,请尽可能多地使用它.
如果不这样做,请确保测试应该有效的简单和复杂表单.
确保在插入时测试正则表达式控制字符的作用.
确保验证空字符串是否被正确接受/拒绝.
确保验证是否正确接受或拒绝了每种不同类型的空格字符的字符串.
确保正确处理不区分大小写(i标志).在文本解析(除了空格)之外,这几乎比其他任何东西都要多.
如果您有x,m或s选项,请确保您了解它们的作用并进行测试(此处的行为可能不同)
对于返回列表的正则表达式,还要记住:
验证您期望的数据是否以正确的顺序返回到正确的字段中.
验证轻微修改不会返回良好数据.
验证混合匿名组和命名组是否正确解析(例如(?
) - 根据您正在使用的正则表达式引擎,此行为可能会有所不同.
再一次,进行大量的真实世界试验.
如果您使用任何高级功能(例如非回溯组),请确保完全了解该功能的工作原理,并使用上述指南,构建适用于每个功能的示例字符串.
根据您的正则表达式库实现,捕获组的方式也可能不同.Perl 5有一个'open paren order'排序,C#部分除了命名组等等.确保尝试你的味道,以确切知道它的作用.
然后,将它们与其他单元测试集成在一起,可以放在自己的模块中,也可以放在包含正则表达式的模块旁边.对于特别讨厌的regexen,您可能会发现需要大量的测试来验证您使用的模式和所有功能是否正确.如果正则表达式构成了该方法正在进行的大量(或几乎所有)工作,我将使用上面的建议来设置输入以测试该函数而不是直接使用正则表达式.这样,如果您以后决定正则表达式不是要走的路,或者您想要将其分解,您可以捕获正则表达式提供的行为而无需更改接口 - 即调用正则表达式的方法.
只要您真正了解正则表达式功能如何适用于您的正则表达式,您应该能够为它开发合适的测试用例.只要确保你真的,真的,真的了解这个功能是如何工作的!
只需抛出一堆值,检查您是否得到了正确的结果(无论是匹配/不匹配还是特定的替换值等).
重要的是,如果有任何角落情况,您怀疑它们是否有效,请在单元测试中捕获它们并在注释中解释它们的工作原理.这样,想要更改正则表达式的其他人将能够检查角落案例是否仍然有效,并且它会给出一个提示,如果它破坏了如何解决它.
据推测,您的正则表达式包含在类的方法中.例如:
public bool ValidateEmailAddress( string emailAddr ) { // Validate the email address using regular expression. return RegExProvider.Match( this.ValidEmailRegEx, emailAddr ); }
您现在可以为此方法编写测试.我想关键是正则表达式是一个实现细节 - 您的测试需要测试接口,在这种情况下只是验证电子邮件方法.