代码之家  ›  专栏  ›  技术社区  ›  Tomtom

与testmethods匹配的regex

  •  2
  • Tomtom  · 技术社区  · 7 年前

    对于我们的应用程序,我们有大约4000个单元测试,如果我们将代码签入到TFS,这些测试将自动执行。

    我们在构建定义上已经改变了很多,所以现在要求所有单元测试都必须具有属性 [TestCategory(TestCategories.GatedCheckin)] 在封闭签入中执行。

    不幸的是,4000个单元中只有700个单元测试具有此属性。现在我必须将属性添加到其余的单元测试中。

    因此,我编写了一个小的VisualStudio扩展名,可以在其中打开源文件并搜索以下正则表达式:

    ^([\t]|[ ])*\[TestMethod\]([\t]|[ ]|[\w\/äÄüÜöÖß])*([\r\n]+)([\t]|[ ])*public
    

    这个正则表达式对单元测试很有用,比如:

    [TestMethod]
    public void PathIsValidTest1()
    {...}
    

    [TestMethod] // another test
    public void Calculator_Add_3_And_3_Equals_6_Test()
    {...}
    

    但对于还包含其他属性的UnitTest,例如:

    [TestMethod]
    [ExpectedException(typeof(ArgumentException))]
    public void ThrowOnInputTooLongTest2()
    {...}
    

    正则表达式不起作用。

    如何修改正则表达式,使其与 [TestMethod] 属性而不是 [测试类别(testcategories.gatedcheckin)]

    我想到了一个消极的展望 ?! 但我没有让它工作。

    有什么想法吗?


    我已经修改了Addison提供的解决方案,因此它看起来像:

    ^[\t ]*\[TestMethod\][ \t\w\/äÄüÜöÖß]*(\n([ \t]*)\[(?!TestCategory\(TestCategories\.GatedCheckin\)).+\][ \t\w\/äÄüÜöÖß]*)?\s+public
    

    如果我在Regex101中使用这个,它会很好地工作,正如你所看到的。 here

    但是,如果我在C中使用这个regex的话:

    string content = File.ReadAllText(file);    
    Regex regex = new Regex(pattern, RegexOptions.Multiline);
    int matchCount = regex.Matches(content).Count;  
    

    我只有两场比赛。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Addison    7 年前

    好问题!

    我设法做到了:

    ^[\t ]*\[TestMethod\][ \t\w\/äÄüÜöÖß]*(\n\[(?!TestCategory\(TestCategories\.GatedCheckin\)).+\][ \t\w\/äÄüÜöÖß]*)*\s+public
    

    我添加了另一个捕获字段(并简化了regex的其余部分),这样它现在可以检查其他任何数量的 [] 第一次之后 [TestMethod] ,并且只有当它们都不是时才会接受它们 [TestCategory(TestCategories.GatedCheckin)] .

    Test it online

    下面是一些C代码:

    using System;
    using System.Text.RegularExpressions;
    
    namespace Programming {
        class Program {
            static void Main() {
                string content = "namespace MyNameSpace1\n{\n    [TestClass]\n    public class GetMapPathActionTests\n    {\n        [TestMethod] // 1\n        public void GetMapPath_with_All_Attibutes()\n        {\n            ...\n        }\n        [TestMethod] // 2\n        [ExpectedException(typeof(DBInstallInfoConverterCrossCheckerRequiredChildNotFoundException))]\n        public void GetMapPath_with_Empty_Input()\n        {\n           \n        }\n        [TestMethod] // 3\n        [ExpectedException(typeof(DBInstallInfoConverterCrossCheckerRequiredChildNotFoundException))]\n        public void GetMapPath_with_Empty_Output()\n        {\n            \n        }\n        [TestMethod] // 4\n        public void GetMapPath_with_Empty()\n        {\n            \n        }\n        [TestMethod] // 5\n        [ExpectedException(typeof(DBInstallInfoConverterCrossCheckerRequiredChildNotFoundException))]\n        public void GetMapPath_with_All_Attibutes_Empty()\n        {\n            \n        }\n    }\n}\n";
                Regex regex = new Regex(@"^[\t ]*\[TestMethod\][ \t\w\/äÄüÜöÖß]*(\s+\[(?!TestCategory\(TestCategories\.GatedCheckin\)).+\][ \t\w\/äÄüÜöÖß]*)?\s+public", RegexOptions.Multiline);
                MatchCollection matches = regex.Matches(content);
    
                foreach (Match match in matches) {
                    foreach (Capture capture in match.Captures) {
                        Console.WriteLine(capture.Value);
                    }
                }
            }
        }
    }