Управляемый данными класс
Прежде чем переходить к этому разделу, убедитесь, что вы знакомы с базовым выполнением 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), точно так же, как и для теста, управляемого данными.
Xml-файл DataSource для управляемого данными класса создается точно так же, как и для теста на основе данных. В следующих примерах показаны 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. Другими словами, 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 обрабатывает это условие так же, как и свойства метаданных. Данные, указанные в строке на уровне метода, переопределяют данные, указанные в строке на уровне класса.
Например, рассмотрим случай, когда у вас есть параметр Size , который указан как на уровне класса, так и на уровне метода теста. На уровне класса Size определяется как тип массива строк , но на уровне метода теста он определяется как int. В этом случае тип int переопределяет тип String Array на уровне метода теста, а также в методах Setup и Teardown для теста. Однако в методах Setup и Teardown на уровне класса размер имеет тип данных Массив строк .
Если в коде есть такие конфликтующие данные, TAEF отображает предупреждение во время выполнения и перечисляет свойства, но конфликтующие данные не приведут к сбою.