Pembuatan input menggunakan eksekusi simbolis dinamis
IntelliTest menghasilkan input untuk pengujian unit berparameter dengan menganalisis kondisi cabang dalam program. Input pengujian dipilih berdasarkan apakah mereka dapat memicu perilaku percabangan baru program. Analisisnya adalah proses inkremental. Ini menyempurnakan predikat q: I -> {true, false}
atas parameter I
input pengujian formal. q
mewakili serangkaian perilaku yang telah diamati intelliTest. Awalnya, q := false
, karena belum ada yang diamati.
Langkah-langkah perulangan adalah:
IntelliTest menentukan input
i
sepertiq(i)=false
menggunakan pemecah batasan. Secara konstruksi, inputi
akan mengambil jalur eksekusi yang tidak terlihat sebelumnya. Awalnya, ini berarti bahwai
dapat menjadi input apa pun, karena belum ada jalur eksekusi yang ditemukan.IntelliTest menjalankan pengujian dengan input
i
yang dipilih, dan memantau eksekusi pengujian dan program yang sedang diuji.Selama eksekusi, program ini mengambil jalur tertentu yang ditentukan oleh semua cabang program kondisional. Kumpulan semua kondisi yang menentukan eksekusi disebut kondisi jalur, yang ditulis sebagai predikat
p: I -> {true, false}
atas parameter input formal. IntelliTest menghitung representasi predikat ini.IntelliTest menetapkan
q := (q or p)
. Dengan kata lain, IntelliTest mencatat fakta bahwa ia telah melihat jalur yang diwakili olehp
.Buka langkah 1.
Pemecah batasan IntelliTest dapat menangani nilai semua jenis yang mungkin muncul dalam program .NET:
IntelliTest memfilter input yang melanggar asumsi yang dinyatakan.
Selain input langsung (argumen untuk pengujian unit berparameter), pengujian dapat menarik nilai input lebih lanjut dari kelas statis PexChoose. Pilihannya juga menentukan perilaku tiruan berparameter.
Pemecah batasan
IntelliTest menggunakan pemecah batasan untuk menentukan nilai input yang relevan dari pengujian dan program yang sedang diuji.
IntelliTest menggunakan pemecah batasan Z3.
Cakupan kode dinamis
Sebagai efek samping dari pemantauan runtime, IntelliTest mengumpulkan data cakupan kode dinamis. Ini disebut dinamis karena IntelliTest hanya tahu tentang kode yang telah dijalankan, oleh karena itu tidak dapat memberikan nilai absolut untuk cakupan dengan cara yang sama seperti alat cakupan lainnya yang biasanya dilakukan.
Misalnya, ketika IntelliTest melaporkan cakupan dinamis sebagai blok dasar 5/10, ini berarti bahwa lima blok dari sepuluh tercakup, di mana jumlah total blok di semua metode yang telah dicapai sejauh ini oleh analisis (dibandingkan dengan semua metode yang ada dalam perakitan di bawah pengujian) adalah sepuluh. Kemudian dalam analisis, karena metode yang lebih dapat dijangkau ditemukan, baik pembilang (5 dalam contoh ini) dan penyebut (10) dapat meningkat.
Bilangan bulat dan float
Pemecah batasan IntelliTest menentukan nilai input pengujian jenis primitif seperti byte, int, float, dan lainnya untuk memicu jalur eksekusi yang berbeda untuk pengujian dan program yang sedang diuji.
Objek
IntelliTest dapat membuat instans kelas .NET yang ada, atau Anda dapat menggunakan IntelliTest untuk membuat objek tiruan secara otomatis yang mengimplementasikan antarmuka tertentu dan ber perilaku dengan cara yang berbeda tergantung pada penggunaan.
Membuat instans kelas yang ada
Apa masalahnya?
IntelliTest memantau instruksi yang dijalankan saat menjalankan pengujian dan program yang sedang diuji. Secara khusus, IntelliTest memantau semua akses ke bidang. Kemudian menggunakan pemecah batasan untuk menentukan input pengujian baru, termasuk objek dan nilai bidangnya, sehingga pengujian dan program yang sedang diuji akan menunjukkan reaksi lain.
Ini berarti bahwa IntelliTest harus membuat objek dari jenis tertentu dan mengatur nilai bidangnya. Jika kelas terlihat dan memiliki konstruktor default yang terlihat, IntelliTest dapat membuat instans kelas. Jika semua bidang kelas terlihat, IntelliTest dapat mengatur bidang secara otomatis.
Jika jenisnya tidak terlihat, atau bidang tidak terlihat, IntelliTest memerlukan bantuan untuk membuat objek dan membawanya ke status yang menarik untuk mencapai cakupan kode maksimal. IntelliTest dapat menggunakan refleksi untuk membuat dan menginisialisasi instans dengan cara arbitrer, tetapi ini biasanya tidak diinginkan karena mungkin membawa objek ke dalam keadaan yang tidak pernah dapat terjadi selama eksekusi program normal. Sebaliknya, IntelliTest mengandalkan petunjuk dari pengguna.
Visibilitas
.NET memiliki model visibilitas yang menguraikan: jenis, metode, bidang, dan anggota lainnya dapat bersifat privat, publik, internal, dan banyak lagi.
Ketika IntelliTest menghasilkan pengujian, intelliTest akan mencoba untuk hanya melakukan tindakan (seperti memanggil konstruktor, metode, dan bidang pengaturan) yang legal sehubungan dengan aturan visibilitas .NET dari dalam konteks pengujian yang dihasilkan.
Aturannya adalah sebagai berikut:
Visibilitas anggota internal
- IntelliTest mengasumsikan bahwa pengujian yang dihasilkan akan memiliki akses ke anggota internal yang terlihat oleh PexClass yang mengapit. .NET memiliki InternalsVisibleToAttribute untuk memperluas visibilitas anggota internal ke rakitan lain.
Visibilitas privat dan keluarga (dilindungi dalam C#) anggota PexClass
- IntelliTest selalu menempatkan pengujian yang dihasilkan langsung di PexClass atau ke subkelas. Oleh karena itu, IntelliTest mengasumsikan bahwa intelliTest dapat menggunakan semua anggota keluarga yang terlihat (dilindungi dalam C#).
- Jika pengujian yang dihasilkan ditempatkan langsung ke PexClass (biasanya dengan menggunakan kelas parsial), IntelliTest mengasumsikan bahwa ia juga dapat menggunakan semua anggota privat PexClass.
Visibilitas anggota publik
- IntelliTest mengasumsikan bahwa ia dapat menggunakan semua anggota yang diekspor yang terlihat dalam konteks PexClass.
Tiruan berparameter
Bagaimana cara menguji metode yang memiliki parameter yang berjenis antarmuka? Atau dari kelas yang tidak disegel? IntelliTest tidak tahu implementasi mana yang nantinya akan digunakan ketika metode ini dipanggil. Dan mungkin bahkan tidak ada implementasi nyata yang tersedia pada waktu pengujian.
Jawaban yang lazim adalah menggunakan objek tiruan dengan perilaku eksplisit.
Objek tiruan mengimplementasikan antarmuka (atau memperluas kelas yang tidak disegel). Hal ini tidak mewakili implementasi nyata, tetapi hanya pintasan yang memungkinkan eksekusi pengujian menggunakan objek tiruan. Perilakunya didefinisikan secara manual sebagai bagian dari setiap kasus pengujian tempatnya digunakan. Banyak alat yang ada yang memudahkan untuk mendefinisikan objek tiruan dan perilaku yang diharapkan, tetapi perilaku ini masih harus ditentukan secara manual.
Alih-alih nilai yang dikodekan secara permanen dalam objek tiruan, IntelliTest dapat menghasilkan nilai. Sama seperti memungkinkan pengujian unit berparameter, IntelliTest juga memungkinkan tiruan berparameter.
Tiruan berparameter memiliki dua mode eksekusi yang berbeda:
- memilih: saat menjelajahi kode, tiruan berparameter adalah sumber input pengujian tambahan, dan IntelliTest akan mencoba memilih nilai yang menarik
- memutaran ulang: saat menjalankan pengujian yang dihasilkan sebelumnya, tiruan berparameter berperilaku seperti potong dengan perilaku (dengan kata lain, perilaku yang telah ditentukan sebelumnya).
Gunakan PexChoose untuk mendapatkan nilai untuk tiruan berparameter.
Structs
Penalaran IntelliTest tentang nilai struktur mirip dengan caranya menangani objek.
Array dan string
IntelliTest memantau instruksi yang dijalankan saat menjalankan pengujian dan program yang sedang diuji. Secara khusus, ia mengamati kapan program tergantung pada panjang string atau array (dan batas bawah dan panjang array multidimensi). Ini juga mengamati bagaimana program menggunakan elemen string atau array yang berbeda. Kemudian menggunakan pemecah batasan untuk menentukan panjang dan nilai elemen mana yang dapat menyebabkan pengujian dan program yang sedang diuji ber perilaku dengan cara yang menarik.
IntelliTest mencoba meminimalkan ukuran array dan string yang diperlukan untuk memicu perilaku program yang menarik.
Mendapatkan input tambahan
Kelas statis PexChoose dapat digunakan untuk mendapatkan input tambahan ke pengujian, dan dapat digunakan untuk mengimplementasikan tiruan berparameter.
Ada tanggapan?
Posting ide dan permintaan fitur Anda di Komunitas Pengembang.