数据驱动的类
在继续本部分之前,请确保熟悉 TAEF 的基本执行并知道如何使用它创作测试。 你可能还需要浏览简单的数据驱动测试示例演练。 在本部分中,你将创建基于 表 的数据驱动测试的数据驱动测试类,但相同的方法适用于 基于 WMI 或 基于 PICT 的数据驱动测试。
何时使用数据驱动类?
有时,多个测试可能依赖于相同的输入数据。 测试 API 时,可能需要使用相同的数据运行多个 API 测试,以便获取 API 行为的一致视图。 执行方案级别测试时,可能需要确保方案中的所有步骤都使用相同的数据进行测试。 在这些时候,在类级别指定测试数据很有用。
创作数据驱动的类
指定给定类的数据驱动方式与指定给定测试为数据驱动的方式类似。 在类级别应用 DataSource 元数据。 值标识感兴趣的特定数据源。 以下示例演示如何为数据驱动类指定这些属性:
本机代码
1 class 2 {
2 BEGIN_TEST_CLASS(DataDrivenClassExample)
3 TEST_CLASS_PROPERTY(L"DataSource", L"Table:DataDrivenClassExample.xml#ClassTable")
4 END_TEST_CLASS()
5
6 TEST_METHOD(Test1);
7 {
8 int size;
9 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"size", size)</span>))
10 {
11 VERIFY_ARE_NOT_EQUAL(size, 0);
12 Log::Comment(String().Format(L"Size retrieved was %d", size));
13 }
14
15 String color;
16 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"color", color)</span>))
17 {
18 Log::Comment(L"Color retrieved was " + color);
19 }
20 }
21 TEST_METHOD(Test2);
22 {
23 int size;
24 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"size", size)</span>))
25 {
26 VERIFY_ARE_NOT_EQUAL(size, 0);
27 Log::Comment(String().Format(L"Size retrieved was %d", size));
28 }
29
30 String color;
31 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"color", color)</span>))
32 {
33 Log::Comment(L"Color retrieved was " + color);
34 }
35 }
36 };
托管代码
1 [TestClass]
2 public class CSharpDataDrivenClassExample
3 {
4 [ClassInitialize]
5 [DataSource("Table:CSharpDataDrivenClassExample.xml#ClassTable")]
6 public static void MyClassInitialize(Object testContext)
7 {
8 }
9
10 [TestMethod]
11 public void Test1()
12 {
13 int size = (int)m_testContext.DataRow["Size"];
14 Verify.AreNotEqual(size, 0);
15 Log.Comment("Size is " + size.ToString());
16
18 Log.Comment("Color is " + m_testContext.DataRow["Color"]);
19 }
20
21 [TestMethod]
22 public void Test2()
23 {
24 int size = (int)m_testContext.DataRow["Size"];
25 Verify.AreNotEqual(size, 0);
26 Log.Comment("Size is " + size.ToString());
27
28 Log.Comment("Color is " + m_testContext.DataRow["Color"]);
29 }
30
31 public TestContext TestContext
32 {
33 get { return m_testContext; }
34 set { m_testContext = value; }
35 }
36
37 private TestContext m_testContext;
38 }
在这些示例中, 本机代码示例 中的第 3 行和 托管代码示例 中的第 5 行是指定 TAEF 中数据驱动测试类的数据源的建议方法。
在上面的 托管代码示例 中,第 13、18、24 和 28 行显示了如何将数据提供给托管代码的测试方法。
在下面的代码示例中,第 4、11、20 和 27 行演示如何将数据提供给本机代码的测试方法。 请注意, 在数据驱动类的表中定义的数据 (行) 测试方法 (Test1 和 Test2) 的方式与数据驱动测试完全相同。
为数据驱动类构造 DataSource XML 文件的方式与数据驱动测试完全相同。 以下示例演示本机类和托管类的 XML 文件。
本地
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="ClassTable">
4 <ParameterTypes>
5 <ParameterType Name="Size">int</ParameterType>
6 </ParameterTypes>
7 <Row>
8 <Parameter Name="Size">4</Parameter>
9 <Parameter Name="Color">White</Parameter>
10 </Row>
11 <Row>
12 <Parameter Name="Size">10</Parameter>
13 <Parameter Name="Color">Black</Parameter>
14 </Row>
15 <Row>
16 <Parameter Name="Size">9</Parameter>
17 <Parameter Name="Color">Orange</Parameter>
18 </Row>
19 <Row>
20 <Parameter Name="Size">9</Parameter>
21 <Parameter Name="Color">Blue</Parameter>
22 </Row>
23 </Table>
24</Data>
管理
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="ClassTable">
4 <ParameterTypes>
5 <ParameterType Name="Size">Int32</ParameterType>
6 <ParameterType Name="Color">String</ParameterType>
7 </ParameterTypes>
8 <Row>
9 <Parameter Name="Size">4</Parameter>
10 <Parameter Name="Color">White</Parameter>
11 </Row>
12 <Row>
13 <Parameter Name="Size">10</Parameter>
14 <Parameter Name="Color">Black</Parameter>
15 </Row>
16 <Row>
17 <Parameter Name="Size">9</Parameter>
18 <Parameter Name="Color">Orange</Parameter>
19 </Row>
20 <Row>
21 <Parameter Name="Size">9</Parameter>
22 <Parameter Name="Color">Blue</Parameter>
23 </Row>
24 </Table>
25</Data>
幕后还是期待什么?
默认情况下,在 TAEF 中创作测试时,类中的执行顺序与在类中编写测试方法的顺序相同。 因此,在前面的示例中, Test1 将始终在 Test2 之前执行。 由于包含 Test1 和 Test2 的类是数据驱动的类,因此所有类方法都将针对在 DataSource 中定义的每个数据 ROW 执行一次。 换句话说, Test1 和 Test2 对行 #0 执行。 然后,这些方法按第 1 行等相同的顺序执行,直到 TAEF 执行所有行。
在数据驱动类中执行测试
如果使用 /list 命令选项执行示例测试二进制文件,则上一部分中的执行顺序将变得清晰。
本地
TE.exe Examples\CPP.AdvancedDataDriven.Examples.dll /name:*class* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CPP.AdvancedDataDriven.Examples.dll
WEX::TestExecution::Examples::DataDrivenClassExample#0
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#1
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#2
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#3
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test2
管理
TE.exe Examples\CSharp.AdvancedDataDriven.Examples.dll /name:*class* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CSharp.AdvancedDataDriven.Examples.dll
WEX.Examples.CSharpDataDrivenClassExample#0
WEX.Examples.CSharpDataDrivenClassExample#0.Test1
WEX.Examples.CSharpDataDrivenClassExample#0.Test2
WEX.Examples.CSharpDataDrivenClassExample#1
WEX.Examples.CSharpDataDrivenClassExample#1.Test1
WEX.Examples.CSharpDataDrivenClassExample#1.Test2
WEX.Examples.CSharpDataDrivenClassExample#2
WEX.Examples.CSharpDataDrivenClassExample#2.Test1
WEX.Examples.CSharpDataDrivenClassExample#2.Test2
WEX.Examples.CSharpDataDrivenClassExample#3
WEX.Examples.CSharpDataDrivenClassExample#3.Test1
WEX.Examples.CSharpDataDrivenClassExample#3.Test2
请注意,上述示例中的索引类似于数据驱动测试。 数据驱动类中的每一行由索引标识。 与数据驱动测试一样, 可以选择在 XML 文件中的“行”级别指定元数据,并在列出或执行测试时打印该名称而不是索引,从而为任何行指定更有意义的短 名称 。
同样,使用 /listproperties 选项确认数据确实在类级别指定并可用。
本地
F:\ Examples\CPP.AdvancedDataDriven.Examples.dll
WEX::TestExecution::Examples::DataDrivenClassExample#0
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = White
Data[Size] = 4
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#1
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = Black
Data[Size] = 10
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#2
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = Orange
Data[Size] = 9
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#3
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = Blue
Data[Size] = 9
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test2
管理
F:\ Examples\CSharp.AdvancedDataDriven.Examples.dll
WEX.Examples.CSharpDataDrivenClassExample#0
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = White
Data[Size] = 4
WEX.Examples.CSharpDataDrivenClassExample#0.Test1
WEX.Examples.CSharpDataDrivenClassExample#0.Test2
WEX.Examples.CSharpDataDrivenClassExample#1
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = Black
Data[Size] = 10
WEX.Examples.CSharpDataDrivenClassExample#1.Test1
WEX.Examples.CSharpDataDrivenClassExample#1.Test2
WEX.Examples.CSharpDataDrivenClassExample#2
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = Orange
Data[Size] = 9
WEX.Examples.CSharpDataDrivenClassExample#2.Test1
WEX.Examples.CSharpDataDrivenClassExample#2.Test2
WEX.Examples.CSharpDataDrivenClassExample#3
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = Blue
Data[Size] = 9
WEX.Examples.CSharpDataDrivenClassExample#3.Test1
WEX.Examples.CSharpDataDrivenClassExample#3.Test2
可以将所有执行规则应用于数据驱动的类。 可以将选择查询基于可以在 /listproperties 选项中列出的任何内容。
数据驱动类中的数据驱动测试
在数据驱动的类中拥有数据驱动的测试,你不受任何限制。 编写 API 测试时,此方法非常有用。 可以在类级别 DataSource 上保留类中所有测试的公共数据。 为标记为数据驱动的方法指定 DataSource 元数据中特定于测试方法的数据。
注意:在这种情况下,执行顺序会稍微复杂一些。
以下示例演示了前两个示例二进制文件如何使用 /list 命令选项呈现。
本地
TE.exe Examples\CPP.AdvancedDataDriven.Examples.dll /name:*nested* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CPP.AdvancedDataDriven.Examples.dll
WEX::TestExecution::Examples::NestedDataDrivenExample#0
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#3
WEX::TestExecution::Examples::NestedDataDrivenExample#1
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#3
WEX::TestExecution::Examples::NestedDataDrivenExample#2
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#3
WEX::TestExecution::Examples::NestedDataDrivenExample#3
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#3
管理
TE.exe Examples\CSharp.AdvancedDataDriven.Examples.dll /name:*nested* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CSharp.AdvancedDataDriven.Examples.dll
WEX.Examples.CSharpDataDrivenNestedExample#0
WEX.Examples.CSharpDataDrivenNestedExample#0.Test1
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#3
WEX.Examples.CSharpDataDrivenNestedExample#1
WEX.Examples.CSharpDataDrivenNestedExample#1.Test1
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#3
WEX.Examples.CSharpDataDrivenNestedExample#2
WEX.Examples.CSharpDataDrivenNestedExample#2.Test1
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#3
WEX.Examples.CSharpDataDrivenNestedExample#3
WEX.Examples.CSharpDataDrivenNestedExample#3.Test1
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#3
注意: 在这种情况下,唯一的限制是两个示例的表不能位于同一 DataSource 文件中。 换句话说,数据驱动类的 DataSource 及其包含的数据驱动测试方法必须不同。
请注意,示例中的方法 Test2 是数据驱动类中的数据驱动测试。 例如,在行 WEX 中。Examples.CSharpDataDrivenNestedExample#3.Test2#0, #3 是类的索引, #0 是该类中的数据驱动测试的索引。 Test2 可以访问这两个表:它所属的类实例行中的数据及其自己的 DataSource 表的当前行中的数据。 换句话说, 类级别的数据和测试方法级别的数据将聚合在一起,并在测试方法执行期间可用。
如果数据冲突 - 如果在类级别和方法级别都指定了相同的数据名称,会发生什么情况? TAEF 处理此条件的方式与处理元数据属性的方式相同。 在方法级别的 Row 中指定的数据将替代类级别的 Row 中指定的数据。
例如,假设有一个名为 Size 的参数,该参数同时在类级别和测试方法级别指定。 在类级别,Size 定义为字符串数组类型,但在测试方法级别,它定义为 int。在这种情况下,int 类型在测试方法级别以及测试的 Setup 和 Teardown 方法上重写字符串数组类型。 但是,在类级别的 Setup 和 Teardown 方法中, Size 具有 字符串数组 数据类型。
如果代码中存在任何此类冲突数据,TAEF 在执行期间会显示警告并列出属性,但冲突数据不会导致任何故障。