数组支持数据驱动的测试示例

本部分将举例说明数据驱动测试的一些高级功能。 如果还在介绍基础知识,不妨从简单数据驱动示例开始。

参考示例:

  • ArraySupportDataDrivenExample

  • CSharpDataDrivenArraySupportExample

前面的部分已经介绍了数据驱动测试编写和执行的基础知识。 下表讨论了 Arrays 在 TAEF 数据驱动测试意义上的含义:

  • 数组是长度可变、类型相同的元素集合,它们被视为单个参数。
  • 要指定数组类型,需要在 ParameterTypes 块中明确指定参数类型,并添加 Array="true" 属性。

支持的参数类型列于表数据源中的参数类型中。

如果指定了任何其他数据类型,测试会发出警告,并将其视为字符串。 如果是数组,数据类型将被视为 String[] 类型。

以下示例展示了如何指定参数为基本类型之一的数组。 需要注意的是,数组不允许使用默认类型,必须明确指定类型并设置 Array 属性,参数才能为 true。

1  <?xml version="1.0"?>
2  <Data>
3    <Table Id="ArraySupportTable">
4      <ParameterTypes>
5        <ParameterType Name="Size" Array="true">int</ParameterType>
6        <ParameterType Name="Color" Array="true">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">
14         <Value>4</Value>
15         <Value>6</Value>
16         <Value>8</Value>
17       </Parameter>
18       <Parameter Name="Color">
19         <Value>Red</Value>
20         <Value>Green</Value>
21         <Value>Blue</Value>
22       </Parameter>
23     </Row>
24     <Row>
25       <Parameter Name="Size">
26         <Value>9</Value>
27         <Value>12</Value>
28         <Value>16</Value>
29       </Parameter>
30       <Parameter Name="Color">Orange</Parameter>
31     </Row>
32     <Row>
33       <Parameter Name="Size">9</Parameter>
34       <Parameter Name="Color">
35         <Value>White</Value>
36         <Value>Black</Value>
37       </Parameter>
38     </Row>
39   </Table>
40 </Data>

查看上例中的 Value 标记和 Array 属性。 首先,必须显式指定 SizeColor 参数的类型,并通过将 Array 属性设置为 true 来将这些参数指定为数组。 然后在 <Value>...</Value> 标记中指定值。 可以根据需要使用尽可能多的 <Value> 标记,在数组中为给定的行参数指定任意数量的值。

请注意上述 XML 示例中的第 9、10、30 和 33 行。 这些条目是单值数组元素。 换句话说,可以直接在 <Parameter> 标记中指定单值数组元素,而无需额外的 <Value> 标记。此外,即使行中的参数只有一个值,它仍被视为包含一个元素的数组,否则无法检索。

现在来看一看检索 API。

本机检索

通过使用 WEX::TestExecution::TestDataArray<> 模板类,可在本机代码中检索数组元素。 有关详细信息,请参阅发布的标头 TestData.h。 TestDataArray 类管理数组元素的生命周期,并提供有用的 API 来检索数组中的特定值:

1  namespace WEX { namespace TestExecution
2  {
3      template <typename T>
4      class TECOMMON_API TestDataArray sealed
5      {
6         ...
7      public:
8          TestDataArray();
9          ~TestDataArray();
10         const size_t GetSize() const;
11         T& operator[](size_t index);
12
13     private:
14        ...
15     };
16 } /* namespace TestExecution */ } /* namespace WEX */

调用 GetSize 可以获取数组的长度,使用操作符 [] 可以获取特定元素。

下一个示例展示了如何在代码中使用这些函数。 请考虑本地示例中的 cpp 文件:

1  TestDataArray<int> sizes;
2  if (SUCCEEDED(TestData::TryGetValue(L"size", sizes)))
3  {
4      size_t count = sizes.GetSize();
5      for (size_t i = 0; i < count; ++i)
6      {
7          Log::Comment(String().Format(L"Size[%d] retrieved was %d", i, sizes[i]));
8      }
9  }
10
11 TestDataArray<String> colors;
12 if (SUCCEEDED(TestData::TryGetValue(L"color", colors)))
13 {
14     size_t count = colors.GetSize();
15     for (size_t i = 0; i < count; ++i)
16     {
17         Log::Comment(String().Format(L"Color[%d] retrieved was ", i) + colors[i]);
18     }
19 }

首先,定义一个本地数组类型的 TestDataArray。 在这种情况下,sizes 是一个 int 类型的数组,而 colors 是一个 WEX::Common::String 类型的数组。 检索数组的 API 与检索任何变量的 API 类似。 调用 TestData::TryGetValue,要求它检索参数 size,并将该值放入局部变量 sizes

请注意,将非数组指定参数检索到数组中的尝试会导致错误,并且测试失败。 同样,如果尝试将数组检索到非数组变量中,即使该数组只有一个元素,也会导致错误。

如果 XML 行中未指定数组参数,则尝试检索该参数时会失败。 例如,如果一个行如下所示:

       <Row>
         <Parameter Name="Color">
           <Value>White</Value>
           <Value>Black</Value>
         </Parameter>
       </Row>

请注意,参数 Size 是一个数组,未在行中指定。 如果尝试从代码中检索 Size,API 调用将返回失败的返回代码。 可以用它来定义默认数组值。

另一方面,可以通过为 Size 指定一个空参数标记来指定一个空数组,如下所示:

       <Row>
         <Parameter Name="Size"></Parameter>
         <Parameter Name="Color">
           <Value>White</Value>
           <Value>Black</Value>
         </Parameter>
       </Row>

在这种情况下,尝试检索 size 会成功,但数组大小为 0。

托管检索

托管检索与以前几乎相同,只是需要确保将值检索到适当数组类型的本地变量中。 请考虑以下托管示例:

1  Int32[] sizes = m_testContext.DataRow["Size"] as Int32[];
2  foreach (int size in sizes)
3  {
4          Verify.AreNotEqual(size, 0);
5          Console.WriteLine("Size is " + size.ToString());
6  }
7
8  String[] colors = m_testContext.DataRow["Color"] as String[];
9  foreach (String color in colors)
10 {
11         Console.WriteLine("Color is " + color);
12 }

与本机检索类似,如果 XML 行中根本没有指定数组参数,则尝试检索该参数时会返回一个类型为 System.DBNull 的对象。 例如,如果一个行如下所示:

       <Row>
         <Parameter Name="Color">
           <Value>White</Value>
           <Value>Black</Value>
         </Parameter>
       </Row>

请注意,参数 Size 是一个数组,未在行中指定。 如果尝试从代码中检索 Size,API 调用将返回 DBNull 类型的对象。 如果表中有这样的值,可能需要先将它们从上下文中检索到一个对象中,然后将对象类型与 typeof(System.DBNull) 或预期类型进行比较后,再采取适当的步骤。

另一方面,或许可以通过为 Size 指定一个空参数标记来指定一个空数组,如下所示:

       <Row>
         <Parameter Name="Size"></Parameter>
         <Parameter Name="Color">
           <Value>White</Value>
           <Value>Black</Value>
         </Parameter>
       </Row>

在这种情况下,尝试检索 size 会成功返回一个类型为 System.Int32[] 的空数组。

执行

执行支持数组的数据驱动测试与执行其他数据驱动测试没有什么不同。 唯一的主要区别在于在数组数据参数的情况下,选择标准的语义发生了变化,变成了 "contains" 而不是 "equals"。

要了解这意味着什么,假设要选择 Color 数组包含 White 值的所有数据驱动测试。 要执行此操作,请运行:

TE.exe Examples\CSharp.DataDriven.Example.dll /select:"@Name='*Array* And @Data:Color='White'"
TE.exe Examples\CPP.DataDriven.Example.dll /select:"@Name='*Array* And @Data:Color='White'"

此命令在上述两种情况下都运行索引号为 0 和 3 的数据驱动测试。

可以创建更复杂的查询,例如,只选择 color 数组包含 whitecolor 数组包含 black 的测试,这样就只能选择索引号为 3 的数据驱动测试。 作为练习,请尝试自己编写和执行此查询。