Sumber Data Tabel
Pastikan Anda terbiasa dengan eksekusi dasar TAEF dan tahu cara Menulis Pengujian menggunakannya, sebelum melanjutkan bagian ini.
Sekarang setelah Anda memiliki otomatisasi pengujian dasar yang ditulis dan bekerja dengan TAEF, Anda dapat berkonsentrasi pada skenario di mana kode pengujian yang sama dapat digunakan untuk bekerja pada berbagai set data. Untuk tujuan ini, TAEF menyediakan pendekatan "Berbasis tabel" untuk pengujian berbasis data. Mari kita lihat contoh sederhana untuk memahami cara menulis pengujian berbasis data.
Pertimbangkan contoh sederhana berbasis non-data di mana Anda mencetak ukuran dan tema ke konsol. Dalam latihan ini, Anda akan mengonversi pengujian ini menjadi pengujian berbasis data.
1 namespace WEX { namespace TestExecution { namespace Examples
2 {
3 void DataDrivenTests::FirstTable()
4 {
5 int size = 12;
6 Log::Comment(String().Format(L"Size retrieved was %d", size));
7 }
8
9 void DataDrivenTests::SecondTable()
10 {
11 String theme = "Aero";
12 Log::Comment(L"Theme supplied as " + theme);
13 }
14 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */
Menentukan Data
Sekarang, Anda ingin fungsi di atas berfungsi untuk sekumpulan ukuran dan tema. Dengan kata lain, Anda menginginkan nilai data varian yang dapat digunakan fungsi kami. Untuk melakukan ini, tentukan dua tabel dalam file XML DataDrivenTests.xml :
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id ="Table1">
4 <ParameterTypes>
5 <ParameterType Name="Size">Int32</ParameterType>
6 <ParameterType Name="Color">String</ParameterType>
7 <ParameterType Name="Transparency">Boolean</ParameterType>
8 </ParameterTypes>
9 <Row Priority="1" Owner="C2">
10 <Parameter Name="Size">12</Parameter>
11 <Parameter Name="Color">Blue</Parameter>
12 <Parameter Name="Transparency">True</Parameter>
13 </Row>
14 <Row Priority="2" Owner="wex">
15 <Parameter Name="Size">4</Parameter>
16 <Parameter Name="Color">White</Parameter>
17 <Parameter Name="Transparency">False</Parameter>
18 </Row>
19 <Row Owner="C2">
20 <Parameter Name="Size">9</Parameter>
21 <Parameter Name="Color">Black</Parameter>
22 <Parameter Name="Transparency">True</Parameter>
23 </Row>
24 </Table>
25 <Table id ="Table2">
26 <Row Description="ButtonTest" Owner="C2" Priority="1">
27 <Parameter Name="Control">Button</Parameter>
28 <Parameter Name="Theme">Aero</Parameter>
29 </Row>
30 <Row Description="ComboBoxTest" Priority="2">
31 <Parameter Name="Control">ComboBox</Parameter>
32 <Parameter Name="Theme">Classic</Parameter>
33 </Row>
34 <Row Description="ListviewTest" Owner="wex">
35 <Parameter Name="Control">Listview</Parameter>
36 <Parameter Name="Theme">AeroBasic</Parameter>
37 </Row>
38 </Table>
39 </Data>
Anda sekarang telah menentukan dua tabel, "Table1" dan "Table2". Anda dapat menentukan tabel untuk beberapa metode pengujian dalam file XML yang sama.
Amati bahwa dalam Table1, Anda menentukan ParameterTypes di depan dan memilih "Ukuran" menjadi bilangan bulat. Bagian ParameterTypes bersifat opsional. Secara default, jika informasi jenis parameter tidak disediakan, informasi tersebut akan disimpan sebagai string. Ini adalah kasus untuk semua parameter di "Table2".
Setiap "Baris" yang ditentukan dalam tabel adalah sekumpulan nilai data (parameter) yang Ingin Anda terima fungsi pengujiannya. Baris 9, 14, dan 19 menentukan 3 set data yang akan diterima fungsi FirstTable kami. Demikian pula baris 26, 30 dan 34 menentukan himpunan data untuk SecondTable.
Perhatikan baris 9, 14, 19, 26, 30, dan 34 dalam contoh di atas - Anda dapat menentukan metadata yang khusus untuk Baris. Sekarang ada cara agar informasi metadata berubah dengan himpunan data untuk fungsi yang sama. Prioritas untuk kumpulan data pertama (baris 9) adalah 1, prioritas untuk kumpulan data kedua (baris 14) adalah 2 dan kumpulan data ketiga (baris 19) default ke prioritas fungsi. Semua baris mewarisi metadata dari fungsi yang dikaitkan dengan tabel. Jika metadata yang sama ditentukan lagi di tingkat baris, metadata akan menggantikan nilai metadata yang ditentukan pada tingkat fungsi.
CATATAN: Definisi skema file XML sama untuk native serta kode terkelola, kecuali untuk definisi jenis yang didukung. Lihat bagian awal dari bagian "Pengujian Berbasis Data Terkelola" di bawah ini untuk contoh lain tentang cara menentukan data. Lanjutkan dengan Pengujian Berbasis Data Asli untuk memahami jenis yang diizinkan dalam kode asli.
Pengujian berbasis Data Asli
Dengan himpunan data yang ditentukan dan siap dikonsumsi, Anda sekarang memerlukan cara untuk memenuhi syarat fungsi pengujian sebagai pengujian berbasis data dan mengaitkannya dengan tabel yang menentukan himpunan data. Ini dilakukan dengan cara metadata tambahan saat menulis pengujian:
1 namespace WEX { namespace TestExecution { namespace Examples
2 {
3 class DataDrivenTests
4 {
5 TEST_CLASS(DataDrivenTests);
6
7 BEGIN_TEST_METHOD(SecondTable)
8 TEST_METHOD_PROPERTY(L"DataSource", L"Table:DataDrivenTests.xml#Table2")
9 TEST_METHOD_PROPERTY(L"Priority", L"3")
10 END_TEST_METHOD()
11
12 BEGIN_TEST_METHOD(FirstTable)
13 TEST_METHOD_PROPERTY(L"Priority", L"4")
14 TEST_METHOD_PROPERTY(L"DataSource", L"Table:DataDrivenTests.xml#Table1")
15 END_TEST_METHOD()
16 };
17 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */
Untuk mengaitkan Tabel XML dengan pengujian, tambahkan metadata 'DataSource' ke metode pengujian. Melalui asosiasi ini TAEF akan menggunakan DataSource yang diberikan untuk mendorong pengujian. Nilai DataSource memiliki tiga bagian untuk itu:
- 'Table:' - ini mengidentifikasi sumber data sebagai tabel XML.
- 'DataDrivenTests.xml' - ini adalah file yang berisi tabel XML.
- '#Table2' - Mengikuti pemisah '#', nilai 'Table2' mengidentifikasi tabel tertentu dalam dokumen XML yang akan digunakan. Satu sumber data Tabel XML dapat berisi beberapa tabel. TAEF akan melihat melalui file XML untuk elemen Tabel dengan atribut 'Id' yang cocok dengan nilai yang ditentukan.
Anda mungkin telah mengamati dalam contoh di atas bahwa "SecondTable" ditentukan sebelum "FirstTable". Ini berarti bahwa fungsi "SecondTable" akan dijalankan sebelum fungsi "FirstTable", tetapi Anda menentukan "Table1", tabel yang sesuai dengan "FirstTable", sebelum "Table2", tabel yang sesuai dengan "SecondTable". Hal ini untuk menekankan bahwa urutan definisi tabel tidak relevan selama penemuan dan eksekusi pengujian berbasis data.
Dengan pemetaan sumber data kami ke metode pengujian selesai, Anda sekarang dapat memodifikasi contoh untuk mendapatkan data dari sumbernya. Sebelum melakukan itu, lihat file header yang diterbitkan, TestData.h. Bagian yang menarik adalah:
1 class TestData
2 {
3 public:
4 template <typename T>
5 static HRESULT __stdcall TryGetValue(_In_z_ const wchar_t* pszString, T& result)
6 {
7 return Private::TestData<T>::TryGetValue(pszString, result);
8 }
9 };
Baris 5 menunjukkan API yang akan dipanggil untuk mengambil data dalam fungsi. Lihat Jenis Parameter yang tersedia untuk pengambilan.
Ok - semua diatur untuk menulis ulang contoh kami:
1 namespace WEX { namespace TestExecution { namespace Examples
2 {
3 void DataDrivenTests::FirstTable()
4 {
5 Log::Comment(L"I am in first table");
6 int size;
7 if (SUCCEEDED(TestData::TryGetValue(L"size", size)))
8 {
9 VERIFY_ARE_NOT_EQUAL(size, 0);
10 Log::Comment(String().Format(L"Size retrieved was %d", size));
11 }
12 }
13
14 void DataDrivenTests::SecondTable()
15 {
16 Log::Comment(L"I am in second table.");
17 String theme;
18 if (SUCCEEDED(TestData::TryGetValue(L"theme", theme)))
19 {
20 Log::Comment(L"Theme supplied as " + theme);
21 }
22 }
23 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */
Baris 7 dan 18 adalah bagian utama yang berubah untuk membuat data pengujian didorong. Tidak banyak perubahan. Lihat Menjalankan Pengujian Berbasis Data untuk memahami cara memanfaatkan TAEF selagi menjalankan pengujian berbasis data.
Pengujian berbasis Data Terkelola
Pertimbangkan contoh di mana Anda ingin mencetak koordinat persegi panjang di konsol. Mulailah dengan menentukan koordinat ini sebagai himpunan data dalam file XML.
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="FirstTable">
4 <ParameterTypes>
5 <ParameterType Name="Left">Int32</ParameterType>
6 <ParameterType Name="Right">String</ParameterType>
7 <ParameterType Name="Top">Integer</ParameterType>
8 <ParameterType Name="Bottom">Int32</ParameterType>
9 </ParameterTypes>
10 <Row Priority="1" Owner="C2" Description="Zero rect">
11 <Parameter Name="Left">0</Parameter>
12 <Parameter Name="Right">0</Parameter>
13 <Parameter Name="Top">0</Parameter>
14 <Parameter Name="Bottom">0</Parameter>
15 </Row>
16 <Row Priority="2" Owner="wex" Description="normal rect">
17 <Parameter Name="Left">12</Parameter>
18 <Parameter Name="Right">25</Parameter>
19 <Parameter Name="Top">10</Parameter>
20 <Parameter Name="Bottom">50</Parameter>
21 </Row>
22 <Row Owner="C2" Description="invalid rect">
23 <Parameter Name="Left">30</Parameter>
24 <Parameter Name="Right">15</Parameter>
25 <Parameter Name="Top">40</Parameter>
26 <Parameter Name="Bottom">10</Parameter>
27 </Row>
28 </Table>
29 </Data>
Tentukan himpunan data dalam cakupan Tabel, dalam hal ini "FirstTable", yang ditentukan dalam baris 3 di atas. Anda dapat menentukan tabel untuk beberapa metode pengujian dalam file XML yang sama.
Amati bahwa FirstTable mendefinisikan ParameterTypes di muka dan memanggil "Kiri" menjadi "Int32". Bagian ParameterTypes bersifat opsional. Secara default, jika informasi jenis parameter tidak disediakan, informasi tersebut akan disimpan sebagai String.
Lihat daftar Jenis Parameter yang didukung.
Jika ada jenis data lain yang ditentukan, pengujian akan melemparkan peringatan dan menganggapnya sebagai String.
CATATAN: String jenis tidak peka huruf besar/kecil tetapi harus mengeja persis seperti yang ditunjukkan di atas.
Setiap "Baris" yang ditentukan dalam tabel, adalah sekumpulan nilai data (parameter) yang Ingin Anda terima fungsi pengujiannya. Baris 10, 16, dan 22 mendefinisikan 3 set data yang fungsi kita.
Perhatikan baris 10, 16, dan 22 dalam contoh di atas - Anda dapat menentukan metadata khusus untuk Baris. Anda sekarang memiliki cara agar informasi metadata berubah dengan himpunan data untuk fungsi yang sama. Prioritas untuk kumpulan data pertama (baris 10) adalah 1, prioritas untuk kumpulan data kedua (baris 16) adalah 2 dan kumpulan data ketiga (baris 22) default ke prioritas fungsi. Semua baris mewarisi metadata dari fungsi yang dikaitkan dengan tabel. Jika metadata yang sama ditentukan lagi di tingkat baris, metadata akan menggantikan nilai metadata yang ditentukan pada tingkat fungsi.
CATATAN: Definisi skema file XML sama untuk native serta kode terkelola, kecuali untuk definisi jenis yang didukung. Lihat bagian "Mendefinisikan Data" di bagian atas halaman ini untuk contoh lain tentang cara menentukan ini.
Sekarang, Anda memiliki semua data yang ditentukan. Contoh berikut menunjukkan cara mengaksesnya.
1 namespace WEX.Examples
2 {
3 using Microsoft.VisualStudio.TestTools.UnitTesting;
4 using System;
5 using System.Collections;
6 using WEX.Logging.Interop;
7 using WEX.TestExecution;
8
9 [TestClass]
10 public class CSharpDataDrivenTests
11 {
12 [TestMethod]
15 [DataSource("Table:CSharpDataDrivenTests.xml#FirstTable")]
16 public void First()
17 {
18 Console.WriteLine("Left is " + m_testContext.DataRow["Left"].ToString());
19
20 Log.Comment("In CSharpDataDrivenTests.First");
21 }
22
23 [TestMethod]
24 public void Second()
25 {
26 Log.Comment("In CSharpDataDrivenTests.Second");
27 Verify.IsTrue(true);
28 }
29
30 public TestContext TestContext
31 {
32 get { return m_testContext; }
33 set { m_testContext = value; }
34 }
35
36 private TestContext m_testContext;
37 }
38 }
Mengaitkan Tabel XML dengan metode pengujian tertentu dalam kode terkelola sangat mirip dengan kode asli; cukup terapkan metadata 'DataSource'. Seperti sebelumnya, terdiri dari tiga bagian:
- 'Table:' - untuk mengidentifikasi sumber data sebagai tabel XML.
- 'CSharpDataDrivenTests.xml' - file yang berisi tabel XML.
- '#FirstTable' - Mengikuti pemisah '#', nilai 'FirstTable' mengidentifikasi tabel tertentu dalam dokumen XML yang akan digunakan. TAEF akan melihat melalui file XML untuk elemen Tabel dengan atribut 'Id' yang cocok dengan nilai yang ditentukan.
Perhatikan bahwa fungsi Kedua tidak digerakkan oleh data. Anda dapat memilih untuk hanya memiliki beberapa pengujian anda untuk didorong oleh data. Anda juga memiliki opsi untuk meminta setiap pengujian memiliki tabel yang ditentukan dalam file XML yang berbeda.
Di Baris 36, Anda menentukan properti TestContext privat - seperti VSTS merekomendasikan Kelas TestContext. Anda juga menentukan penilai publik ke properti ini (baris 30 hingga 34). TAEF secara internal memuat properti kamus TestContext dengan himpunan data yang sesuai dalam fokus.
TestContext didefinisikan dalam Microsoft.VisualStudio.TestTools.UnitTesting. Lihat baris 3 dalam contoh di atas. Anda harus sudah menyertakan ini sebagai referensi dalam penulisan pengujian terkelola Anda. Jadi, tidak ada referensi tambahan yang diperlukan untuk menulis pengujian berbasis data.
Pada baris 18 dari contoh di atas, Anda menunjukkan cara mengambil data dalam fungsi. Perhatikan bahwa data tersedia di m_testContext.DataRow.
Nama alih-alih Indeks untuk Mengidentifikasi DataRow
TAEF memungkinkan Anda memiliki properti 'Nama' yang lebih bermakna alih-alih Indeks untuk mengidentifikasi DataRow apa pun di DataSource Anda. Untuk melakukan ini, cukup tambahkan metadata 'Nama' di tingkat Baris di DataSource Anda. Contoh pertama kami di halaman ini dapat dimodifikasi untuk menggunakan fitur ini sebagai berikut:
1 <?xml version="1.0"?>
2 <Data>
3 <Table id ="Table1">
4 <ParameterTypes>
5 <ParameterType Name="Size">Int32</ParameterType>
6 <ParameterType Name="Color">String</ParameterType>
7 <ParameterType Name="Transparency">Boolean</ParameterType>
8 </ParameterTypes>
9 <Row Name='BlueTransparent' Priority="1" Owner="C2">
10 <Parameter Name="Size">12</Parameter>
11 <Parameter Name="Color">Blue</Parameter>
12 <Parameter Name="Transparency">True</Parameter>
13 </Row>
14 <Row Priority="2" Owner="wex">
15 <Parameter Name="Size">4</Parameter>
16 <Parameter Name="Color">White</Parameter>
17 <Parameter Name="Transparency">False</Parameter>
18 </Row>
19 <Row Name='BlackTransparent' Owner="C2">
20 <Parameter Name="Size">9</Parameter>
21 <Parameter Name="Color">Black</Parameter>
22 <Parameter Name="Transparency">True</Parameter>
23 </Row>
24 </Table>
25 ...
39 </Data>
Dalam contoh yang dimodifikasi di atas, 'BlueTransparent' sesuai dengan indeks 0. Baris dengan indeks 1 tidak memiliki nama khusus yang diberikan padanya dan Baris dengan indeks 2 memiliki Nama 'BlackTransparent yang terkait dengannya. Anda masih bisa menggunakan kueri pilihan untuk mencari indeks 0 atau 2 di 'Table1', dan itu akan menemukan Baris yang benar. Tetapi, saat menjalankan atau mencantumkan dll, alih-alih melihat:
<qualified name of the test method>#<index>
Anda akan melihat:
<qualified name of the test method>#<name property provided at Row level>
untuk Baris tempat atribut "Nama" disediakan di tingkat Baris. Jika properti "Nama" tidak disediakan untuk Baris apa pun, seperti dalam kasus indeks 1 di atas, secara default akan memiliki #<index> pada nama metode yang memenuhi syarat.
PERHATIKAN bahwa dengan cara menyediakan atribut "Nama" di tingkat Baris, Anda pada dasarnya mengubah cara TAEF menginterpretasikan nama instans pemanggilan metode dengan data Baris yang sesuai.
DataSource sebagai parameter Runtime
TAEF mendukung penyediaan sumber data sebagai parameter runtime. Sintaks untuk ini adalah sebagai berikut:
te <test dll names> /p:<DataSource runtime name>=Table:<DataSoure XML file>#<Table Id>
Saat menulis pengujian yang bersangkutan, Anda harus menentukan "nama> runtime p:<DataSource" sebagai Sumber Data Anda. Perlu diingat bahwa Anda harus menentukan string lengkap - nama file XML serta id tabel bersama-sama - saat runtime. TableId tidak diharapkan disediakan sebagai metadata pengujian jika sumber data Anda disediakan saat runtime. Awalan "Tabel:" menentukan bahwa Anda mencari sumber data tabel.
Anda dapat mencoba ini dengan salah satu contoh yang tersedia pada berbagi rilis:
te Examples\CPP.RuntimeDataSource.Example.dll /p:MyDataSource=Table:RuntimeDataSourceExample.xml#SimpleTable
DataSource sebagai Sumber Daya
TAEF memungkinkan Anda menambahkan DataSource sebagai sumber daya modul pengujian selama sesuai dengan yang berikut:
Dalam kasus modul pengujian asli, Anda dapat melakukan ini dengan menentukan DataSource Anda sebagai id sumber daya atau nama sumber daya. Berikut adalah contoh kode:
BEGIN_TEST_METHOD(ResourceNameDataSource)
TEST_METHOD_PROPERTY(L"DataSource", L"Table:MyResourceName#SimpleTable")
END_TEST_METHOD()
"MyResourceName" adalah nama sumber daya seperti yang didefinisikan dalam file ResourceDataSource.rc dalam hal ini:
MyResourceName DATASOURCE_XML "ResourceDataSource.xml"
Dalam kasus modul pengujian terkelola, sumber daya hanya dapat ditentukan dengan cara tertentu seperti yang ditunjukkan pada cuplikan file sumber yang ditunjukkan di bawah ini:
LANGUAGE_NEUTRAL_MANAGED_RESOURCES = CSharpAdvancedDataDrivenTests.xml
Spesifikasi metadata DataSource akan tetap sama seperti yang terjadi jika menentukan file XML DataSource. Mirip dengan kasus dalam kode terkelola, Anda dapat membuat nama sumber daya sama dengan nama file XML. Oleh karena itu, penting untuk dipahami bahwa TAEF akan terlebih dahulu mencari keberadaan file aktual dengan nama DataSource. Jika file XML seperti itu tidak ditemukan, hanya kemudian akan dilanjutkan dengan mencari sumber daya pengujian dalam modul pengujian dengan nama sumber daya atau id yang diberikan. Karena menentukan DataSource sebagai sumber daya memerlukan kompilasi ulang, Anda dapat memanfaatkan desain ini dengan menyalin file XML DataSource ke lokasi yang sama dengan dll pengujian saat mengembangkan (dan menamai nama sumber daya agar sama dengan nama file XML). Setelah Anda selesai menguji, salin XML kembali ke direktori kode dan kompilasi ulang sebagai sumber daya. Jangan lupa untuk menghapus file XML dari direktori eksekusi! :)
Contoh Panduan
Untuk memahami berbagai aspek pengujian berbasis data berbasis tabel, baca beberapa contoh panduan lainnya: