执行组

在继续本部分之前,请确保熟悉 TAEF 的基本执行并知道如何使用它 创作测试 。 你可能还需要浏览用户指南中列出的一些数据驱动的测试示例演练。

使用 TAEF 进行基于方案的测试

当你谈论方案级测试时,你实际上是在谈论一系列测试,其中执行下一个测试只有在方案中的上一个测试成功时才有意义。 在某些情况下,如果上一个测试失败,你甚至可能没有执行下一个测试所需的所有信息。 为此,TAEF 支持所谓的“ExecutionGroup”,同时将执行单元保留为测试方法并允许测试方案。 无论是否仍具有其他功能(如数据驱动测试)时,都可以在 TAEF 中使用基于方案的测试。 如果将方案设计为利用数据驱动测试,则可以使用 TAEF 提供的数据驱动类功能在类级别应用数据驱动的支持。 通过在类级别应用数据驱动支持,可以针对每一行按顺序执行类中的所有测试。

本页将重点介绍如何将类中的测试序列指定为“ExecutionGroup”。

执行组

在讨论执行组之前,请务必注意并记住, 在 TAEF 中,类内测试的执行顺序是将其限定为本机代码TEST_METHOD (...) 的顺序,或者在托管代码的情况下在 方法之前添加 [TestMethod] 属性。 TAEF 不保证类本身的执行顺序。

现在,在基于方案的测试中,仅仅保证执行顺序可能是不够的,还需要在继续执行方案中的下一个测试之前,确保方案中的所有先前测试都成功。 在这里,你会发现“ExecutionGroup”的概念很有用。

考虑一个本机示例:

1     class ExecutionDependencyExample
2     {
3         BEGIN_TEST_CLASS(ExecutionDependencyExample)
4             TEST_CLASS_PROPERTY(L"ExecutionGroup", L"DependentTests")
5         END_TEST_CLASS()
6
7         TEST_METHOD(Test1)
8         {
9             Log::Comment(L"Test1 passes.");
10        }
11
12        TEST_METHOD(Test2)
13        {
14            Log::Comment(L"Test2 fails.");
15            VERIFY_ARE_EQUAL(2, 3);
16        }
17
18        TEST_METHOD(Test3)
19        {
20            Log::Comment(L"Test3 is blocked; so you shouldn't see this.");
21        }
22    };

请参阅上面的 C++ 文件片段中的第 4 行。 在此特定情况下,需要将类 ExecutionDependencyExample 中的所有测试限定为属于名为“DependentTests”的“ExecutionGroup”。 这意味着“Test1”、“Test2”和“Test3”是“DependentTests”执行组的一部分。 如前所述,仅当 Test1 成功执行并通过时,Test2 才会执行。 同样,当并且仅当 Test2 成功执行并通过时,Test3 才会执行。

你将看到 Test2 设计为失败, (看到上面的第 14 行和第 15 行) 。

由于 Test2 在“DependentTests”“ExecutionGroup”中失败,Test3 将不会执行,而是被标记为已阻止。 让我们尝试运行上述测试,看看这是否确实如此。

te Examples\CPP.ExecutionDependency.Example.dll
Test Authoring and Execution Framework v2.93k for x86

StartGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test1
Test1 passes.
EndGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test1 
    [Passed]

StartGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test2
Test2 fails.
Error: Verify: AreEqual(2, 3) - Values (2, 3) [File: >f:source\executiondependencyexample\executiondependencyexample.cpp,
Function: WEX::TestExecution::Examples::ExecutionDependencyExample::Test2, Line:21] 
EndGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test2[Failed] 

StartGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test3
Blocked: This test belongs to an execution group and depends on the previous test being executed in the same environment successfully. The dependent test must be selected for execution, must request the same execution environment (e.g. 'ThreadingModel') and must be executed successfully.
EndGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test3 [Blocked]

Non-passing Tests:
    WEX::TestExecution::Examples::ExecutionDependencyExample::Test2 [Failed]
    WEX::TestExecution::Examples::ExecutionDependencyExample::Test3 [Blocked]

Summary: Total=3, Passed=1, Failed=1, Blocked=1, Not Run=0, Skipped=0

请注意,如预测的那样,Test1 通过,Test2 失败,Test3 被阻止。 使用 Test3 时,TAEF 会记录一条消息,指出 Test3 属于执行组,而上一个测试未成功执行。

此错误消息还指示在执行当前测试之前,应选择属于同一 ExecutionGroup 的所有测试。 换句话说,如果尝试在运行时仅使用选择条件运行 Test2,则会发现 Test2 将被阻止,因为它的执行依赖于 Test1,属于同一 ExecutionGroup。

te Examples\CPP.ExecutionDependency.Example.dll /name:*Test2*
Test Authoring and Execution Framework v2.9.3k for x86

StartGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test2
Blocked: This test belongs to an execution group and depends on the previous test being executed in the same environment successfully. The dependent test must be selected for execution, must request the same execution environment (e.g. 'ThreadingModel') and must be executed successfully.

EndGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test2 [Blocked]

Summary: Total=1, Passed=0, Failed=0, Blocked=1, Not Run=0, Skipped=0

但是,如果选择 Test1(这是 ExecutionGroup 中的第一个测试),它将成功运行。

te Examples\CPP.ExecutionDependency.Example.dll /name:*Test1*
Test Authoring and Execution Framework v2.9.3k for x86
StartGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test1
Test1 passes.
EndGroup: WEX::TestExecution::Examples::ExecutionDependencyExample::Test1 [Passed]

Summary: Total=1, Passed=1, Failed=0, Blocked=0, Not Run=0, Skipped=0

此外,如果测试不属于 ExecutionGroup,则无论 ExecutionGroup 中的测试的执行结果如何,它们都将执行。 还可以在一个类中有多个 ExecutionGroup。 但请注意,ExecutionGroup 不能跨类。 如果这样做,它们将被视为两个单独的 ExecutionGroup,每个类中一个。

该消息还指示 Test3 应在与 Test2 相同的环境中运行。 让我们尝试更详细地了解这一方面。 由于成为 ExecutionGroup 的一部分实际上意味着成为基于方案的测试的一部分,因此所有测试请求并因此在同一环境中执行就变得至关重要。 例如,如果 ExecutionGroup 中的线程模型发生更改,你将看到被阻止的测试。 例如,如果在上面的示例中,Test2 设计为成功执行,但“ThreadingModel”属性设置为“MTA”,则仍会阻止 Test3。

让我们考虑另一个示例:Examples\TAEF\CSharp\ExecutionDependentGroupsExample (请参阅最新的 TAEF 发布共享)

1     [TestClass]
2     public class CSharpExecutionDependentGroupsExample
3     {
4         //First Execution Group: Test1, Test2
5         [TestMethod]
6         [TestProperty("ExecutionGroup", "First Execution Group")]
7         public void Test1()
8         {
9             Log.Comment("Part of First Execution Group");
10        }
11        [TestMethod]
12        [TestProperty("ExecutionGroup", "First Execution Group")]
13        public void Test2()
14        {
15            Log.Comment("Part of First Execution Group");
16        }
17
18        //Second Execution Group: Test3, Test4. Test4 fails
19        [TestMethod]
20        [TestProperty("ExecutionGroup", "Second Execution Group")]
21        public void Test3()
22        {
23            Log.Comment("Part of Second Execution Group");
24        }
25        [TestMethod]
26        [TestProperty("ExecutionGroup", "Second Execution Group")]
27        public void Test4()
28        {
29            Log.Comment("Part of Second Execution Group - last in group fails");
30            Verify.IsTrue(false);
31        }
32
33        //Third Execution Group: Test5, Test6, Test7. Test6 fails, Test7 will be blocked.
34        [TestMethod]
35        [TestProperty("ExecutionGroup", "Third Execution Group")]
36        public void Test5()
37        {
38            Log.Comment("Part of Third Execution Group");
39        }
40        [TestMethod]
41        [TestProperty("ExecutionGroup", "Third Execution Group")]
42        public void Test6()
43        {
44            Log.Comment("Part of Third Execution Group - middle in this set of 3 fails");
45            Verify.IsTrue(false);
46        }
47        [TestMethod]
48        [TestProperty("ExecutionGroup", "Third Execution Group")]
49        public void Test7()
50        {
51            Log.Comment("Part of Third Execution Group");
52        }
53
54        //Fourth Execution Group: Test8, Test9
55        [TestMethod]
56        [TestProperty("ExecutionGroup", "Fourth Execution Group")]
57        public void Test8()
58        {
59            Log.Comment("Part of Fourth Execution Group");
60        }
61        [TestMethod]
62        [TestProperty("ExecutionGroup", "Fourth Execution Group")]
63        public void Test9()
64        {
65            Log.Comment("Part of Fourth Execution Group");
66        }
67    }

此示例有 4 个不同的执行组:

  • “第一个执行组”包含 Test1、Test2;这两者都应成功通过。
  • “Second Execution Group”包含 Test3 和 Test4。 Test4 是此 ExecutionGroup 中的最后一个测试,失败。
  • “第三个执行组”包含 Test5、Test6 和 Test7。 尽管上一个 ExecutionGroup 中的 Test4 失败,但 Test5 执行并成功通过。 Test6 设计为失败,这将导致 Test7 被阻止。
  • “第四个执行组”包含 Test8 和 Test9。 同样,尽管上一个 ExecutionGroup 中的 Test7 由于 Test6 失败而被阻止,但 Test8 将成功执行,Test9 也将成功执行。

为了更好地了解此示例中的 ExecutionGroup,让我们列出此示例中的属性。

te Examples\CSharp.ExecutionDependentGroups.Example.dll /listproperties
Test Authoring and Execution Framework v2.9.3k for x86

        F:\ \Examples\CSharp.ExecutionDependentGroups.Example.dll
            WEX.Examples.CSharpExecutionDependentGroupsExample
                WEX.Examples.CSharpExecutionDependentGroupsExample.Test1
                        Property[ExecutionGroup] = First Execution Group
                WEX.Examples.CSharpExecutionDependentGroupsExample.Test2
                        Property[ExecutionGroup] = First Execution Group

                WEX.Examples.CSharpExecutionDependentGroupsExample.Test3
                        Property[ExecutionGroup] = Second Execution Group
                WEX.Examples.CSharpExecutionDependentGroupsExample.Test4
                        Property[ExecutionGroup] = Second Execution Group

                WEX.Examples.CSharpExecutionDependentGroupsExample.Test5
                        Property[ExecutionGroup] = Third Execution Group
                WEX.Examples.CSharpExecutionDependentGroupsExample.Test6
                        Property[ExecutionGroup] = Third Execution Group
                WEX.Examples.CSharpExecutionDependentGroupsExample.Test7
                        Property[ExecutionGroup] = Third Execution Group

                WEX.Examples.CSharpExecutionDependentGroupsExample.Test8
                        Property[ExecutionGroup] = Fourth Execution Group
                WEX.Examples.CSharpExecutionDependentGroupsExample.Test9
                        Property[ExecutionGroup] = Fourth Execution Group

执行上述测试时,以下输出将确认预测的执行顺序。

te Examples\CSharp.ExecutionDependentGroups.Example.dll
Test Authoring and Execution Framework v2.9.3k for x86

StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test1

Part of First Execution Group
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test1 [Passed]
StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test2

Part of First Execution Group
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test2 [Passed]

StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test3

Part of Second Execution Group
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test3 [Passed]
StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test4

Part of Second Execution Group - last in group fails
Error: Verify: IsTrue [File: Need_Symbols, Function: Test4, Line: 0] 
Error: [HRESULT: 0x80131604]. Operation failed: 'WEX.Examples.CSharpExecutionDependentGroupsExample.Test4'.
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test4 [Failed]

StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test5

Part of Third Execution Group
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test5 [Passed]
StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test6

Part of Third Execution Group - middle in this set of 3 fails
Error: Verify: IsTrue [File: Need_Symbols, Function: Test6, Line: 0] 
Error: [HRESULT: 0x80131604]. Operation failed: 'WEX.Examples.CSharpExecutionDependentGroupsExample.Test6'.
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test6 [Failed] 
Error: WEX.Examples.CSharpExecutionDependentGroupsExample.Test7 belongs to an execution group and depends
       on the previous test being executed in the same environment successfully.
Error: Please make sure that the dependent test is selected for execution, requests the same execution .
       environment metadata(e.g. 'ThreadingModel') and that it executed successfully.
StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test7
Blocked EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test7 [Blocked]

StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test8

Part of Fourth Execution Group
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test8 [Passed]
StartGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test9

Part of Fourth Execution Group
EndGroup: WEX.Examples.CSharpExecutionDependentGroupsExample.Test9 [Passed]

Failed Tests:
    WEX.Examples.CSharpExecutionDependentGroupsExample.Test4
    WEX.Examples.CSharpExecutionDependentGroupsExample.Test6

Summary: Total=9, Passed=6, Failed=2, Blocked=1, Not Run=0, Skipped=0

请注意,测试执行顺序与预期一样。