Generování testů
V tradičním testování jednotek se test skládá z několika věcí:
- Posloupnost volání metod
- Argumenty, se kterými se metody volají; argumenty jsou testovací vstupy.
- Ověření zamýšleného chování testované aplikace uvedením sady kontrolních výrazů
Následuje příklad testovací struktury:
[Test]
void MyTest() {
// data
ArrayList a = new ArrayList();
// method sequence
a.Add(5);
// assertions
Assert.IsTrue(a.Count==1);
Assert.AreEqual(a[0], 5);
}
IntelliTest často dokáže automaticky určit relevantní hodnoty argumentů pro obecnější parametrizované testy jednotek, které poskytují posloupnost volání metod a kontrolních výrazů.
Generátory testů
IntelliTest generuje testovací případy výběrem posloupnosti metod implementace, která se má provést, a následným generováním vstupů pro metody při kontrole kontrolních výrazů na odvozených datech.
Parametrizovaný test jednotek přímo uvádí posloupnost volání metody v těle.
Pokud IntelliTest potřebuje sestavit objekty, volání konstruktorů a metod továrny se automaticky přidá do sekvence podle potřeby.
Parametrizované testování částí
Parametrizované testy jednotek (PUT) jsou testy, které přebírají parametry. Na rozdíl od tradičních testů jednotek, které jsou obvykle uzavřené metody, put používají libovolnou sadu parametrů. Je to jednoduché? Ano – Odsud se IntelliTest pokusí vygenerovat (minimální) sadu vstupů , které plně pokrývají kód dostupný z testu.
PuTs jsou definovány pomocí vlastního atributu PexMethod podobným způsobem jako MSTest (nebo NUnit, xUnit). PUTs jsou metody instancí logicky seskupeny ve třídách označených PexClass. Následující příklad ukazuje jednoduchou PUT uloženou ve třídě MyPexTest :
[PexMethod]
void ReplaceFirstChar(string target, char c) {
string result = StringHelper.ReplaceFirstChar(target, c);
Assert.AreEqual(result[0], c);
}
where ReplaceFirstChar je metoda, která nahrazuje první znak řetězce:
class StringHelper {
static string ReplaceFirstChar(string target, char c) {
if (target == null) throw new ArgumentNullException();
if (target.Length == 0) throw new ArgumentOutOfRangeException();
return c + target.Substring(1);
}
}
Z tohoto testu může IntelliTest automaticky generovat vstupy put, které pokrývají mnoho cest spuštění testovaného kódu. Každý vstup, který pokrývá jinou cestu spuštění, získá serializovaný jako test jednotek:
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
void ReplaceFirstChar0() {
this.ReplaceFirstChar(null, 0);
}
...
[TestMethod]
void ReplaceFirstChar10() {
this.ReplaceFirstChar("a", 'c');
}
Parametrizované testování částí
Parametrizované testy jednotek mohou být obecné metody. V tomto případě musí uživatel zadat typy použité k vytvoření instance metody pomocí PexGenericArguments.
[PexClass]
public partial class ListTest {
[PexMethod]
[PexGenericArguments(typeof(int))]
[PexGenericArguments(typeof(object))]
public void AddItem<T>(List<T> list, T value)
{ ... }
}
Povolení výjimek
IntelliTest poskytuje celou řadu ověřovacích atributů, které pomáhají při třídění výjimek do očekávaných výjimek a neočekávaných výjimek.
Očekávané výjimky generují negativní testovací případy s příslušnou poznámkou, jako je ExpectedException(typeof(xxx)), zatímco neočekávané výjimky generují neúspěšné testovací případy.
[PexMethod, PexAllowedException(typeof(ArgumentNullException))]
void SomeTest() {...}
Validátory jsou:
- PexAllowedException: umožňuje konkrétní typ výjimky odkudkoli
- PexAllowedExceptionFromAssembly: umožňuje konkrétní typ výjimky ze zadaného sestavení.
- PexAllowedExceptionFromType: umožňuje konkrétní typ výjimky ze zadaného typu.
- PexAllowedExceptionFromTypeUnderTest: Umožňuje konkrétní typ výjimky z typu pod testem.
Testování vnitřních typů
IntelliTest dokáže "testovat" interní typy, pokud je uvidí. Aby nástroj IntelliTest viděl typy, přidá se do vašeho produktu nebo testovacího projektu pomocí průvodců Visual Studio IntelliTest následující atribut:
[assembly: InternalsVisibleTo("Microsoft.Pex, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
Předpoklady a kontrolní výrazy
Uživatelé mohou pomocí předpokladů a kontrolních výrazů vyjádřit předpoklady (předpoklady) a postconditions (kontrolní výrazy) o svých testech . Když IntelliTest vygeneruje sadu hodnot parametrů a kód "prozkoumá", může narušit předpoklad testu. Když k tomu dojde, nevygeneruje test pro tuto cestu, ale bezobslužně ji ignoruje.
Kontrolní výrazy jsou dobře známým konceptem v rámci pravidelných testů jednotek, takže IntelliTest už "rozumí" předdefinované třídy Assert poskytované jednotlivými podporovanými testovacími architekturami. Většina architektur však neposkytuje třídu Assume . V takovém případě IntelliTest poskytuje třídu PexAssume . Pokud nechcete použít existující testovací architekturu, IntelliTest má také PexAssert třída.
[PexMethod]
public void Test1(object o) {
// precondition: o should not be null
PexAssume.IsNotNull(o);
...
}
Konkrétně lze předpoklad bez hodnoty null zakódovat jako vlastní atribut:
[PexMethod]
public void Test2([PexAssumeNotNull] object o)
// precondition: o should not be null
{
...
}
Předběžná podmínka
Předběžná podmínka metody vyjadřuje podmínky, za kterých bude metoda úspěšná.
Podmínku obvykle vynucuje kontrola parametrů a stav objektu a vyvolání argumentException nebo InvalidOperationException , pokud je porušen.
V IntelliTestu je předběžná podmínka parametrizovaného testu jednotek vyjádřena pomocí PexAssume.
Následná podmínka
Postcondition metody vyjadřuje podmínky, které by měly být v průběhu a po provedení metody za předpokladu, že jeho předpoklady byly původně platné.
Obvykle se postcondition vynucuje voláními metod Assert .
V IntelliTestu je postcondition parametrizovaného testu jednotek vyjádřen pomocí PexAssert.
Neúspěšné testy
Kdy vygenerovaný testovací případ selže?
Pokud se neukončí v mezích nakonfigurované cesty, považuje se za selhání, pokud není nastavena možnost TestExcludePathBoundsExceeded.
Pokud test vyvolá výjimku PexAssumeFailedException, proběhne úspěšně. Obvykle se ale vyfiltruje, pokud není testEmissionFilter nastavený na Hodnotu Vše.
Pokud test porušuje kontrolní výraz, například vyvoláním výjimky porušení kontrolního výrazu architektury testování jednotek selže.
Pokud žádná z výše uvedených možností nevyvolá rozhodnutí, test bude úspěšný, pouze pokud nevyvolá výjimku. Porušení kontrolních výrazů se zachází stejným způsobem jako s výjimkami.
Nastavení a úplné ukončení
V rámci integrace s testovacími architekturami podporuje IntelliTest zjišťování a spouštění metod nastavení a odstraňování.
Příklad
using Microsoft.Pex.Framework;
using NUnit.Framework;
namespace MyTests
{
[PexClass]
[TestFixture]
public partial class MyTestClass
{
[SetUp]
public void Init()
{
// monitored
}
[PexMethod]
public void MyTest(int i)
{
}
[TearDown]
public void Dispose()
{
// monitored
}
}
}
Další texty
Máte zpětnou vazbu?
Své nápady a žádosti o funkce můžete zadávat na webu Developer Community.