MSTest 4.4 ile Native AOT Uygulamalarını Test Etmek
Native AOT ile yayımlanan bir uygulamada yönetilen ortamda başarılı olan testler, dağıtım sırasında çıkabilecek her sorunu göstermeyebilir. MSTest 4.4 ile test projeleri Native AOT yürütülebilirleri olarak yayımlanıp çalıştırılabilir. Böylece testler, uygulamanın yayımlanacağı derleme ve çalışma modeline daha yakın bir ortamda doğrulanır.
Yönetilen testler dağıtım sorunlarını gizleyebilir
Native AOT, uygulamayı önceden derler, kullanılmayan kodları kaldırır ve çalışma zamanında kod üretimiyle sınırsız yansıma kullanımına alternatifler gerektirir. Bu yüzden yönetilen test sürecinde kullanılan kodun davranışıyla Native AOT olarak yayımlanan uygulamanın davranışı farklı olabilir.
Örneğin aşağıdaki test, System.Text.Json ile bir makbuz nesnesini JSON’a dönüştürüyor:
[TestClass]
public class ReceiptFormatterTests
{
[TestMethod]
public void ReceiptIsSerialized()
{
var json = JsonSerializer.Serialize(new Receipt(42));
StringAssert.Contains(json, "\"Total\":42");
}
}
public sealed record Receipt(decimal Total);
Test normal yönetilen çalıştırmada başarılı olabilir; System.Text.Json türü yansıma yoluyla keşfedebilir. Ancak kırpılmış veya Native AOT olarak yayımlanmış bir uygulamada yansıma tabanlı serileştirme varsayılan olarak devre dışıdır. Aynı kod şu hatayı üretebilir:
System.InvalidOperationException:
Reflection-based serialization has been disabled for this application.
Bu hata test altyapısında değil, uygulamanın dağıtım modelinde bir sorun olduğunu gösterir. Uygulama tarafında JSON meta verileri kaynak üretimiyle sağlanabilir:
[JsonSerializable(typeof(Receipt))]
internal partial class AppJsonContext : JsonSerializerContext
{
}
var json = JsonSerializer.Serialize(
new Receipt(42),
AppJsonContext.Default.Receipt);
System.Text.Json kaynak üretimi, serileştirmede kullanılabilecek üretim modlarını ve davranışı açıklar. Serileştirme bunun yalnızca bir örneği. Native AOT testi, desteklenmeyen çalışma zamanı kod üretimini, eksik yansıma meta verilerini ve uyumsuz bağımlılıkları da ortaya çıkarabilir.
Burada iki ayrı sorumluluk vardır: MSTest kaynak üretimi, testlerin kırpma sonrasında keşfedilip çalıştırılmasını sağlar; JSON kaynak üretimi ise testin kullandığı uygulama yolunu Native AOT ile uyumlu hale getirir. MSTest uygulamadaki sorunu gizlemez, yerel test sürecinin bu sorunu dağıtımdan önce göstermesine yardımcı olur.
MSTest Native AOT test yürütülebilirini nasıl oluşturuyor?
MSTest’in ilk Native AOT önizlemesi Nisan 2024’te yayımlandı. Bu çalışma, bir MSTest projesinin yerel bir yürütülebilir dosyaya dönüştürülebileceğini gösterdi; ancak deneysel test motorunun ve kaynak üreticisinin kapsamı sınırlıydı.
MSTest 4.4 ile kaynak üretimi MSTest araç zincirine ekleniyor. Derleme sırasında kaynak üreticisi şunları oluşturuyor:
- Derlemedeki test sınıflarının kaydı
- Desteklenen test üyelerine ait öznitelik bilgileri
- Test sınıflarını oluşturan ve test metotlarını çağıran temsilciler
- Kırpma sırasında keşfedilen test sınıflarını ve desteklenen temel sınıfları koruyan başvurular
Buradaki temel kazanım, üretilen koddan çok testlerin varlığının ve nasıl çalıştırılacağının kırpma işleminden önce kaydedilmesidir. Test sınıfları ve metotları yine normal [TestClass] ve [TestMethod] kodu olarak yazılır. Kaynak üretimi programlama modelini değil, derleme ve çalıştırma yolunu değiştirir.
Bir MSTest projesini Native AOT için yapılandırma
Temel proje yapılandırması için küçük bir değişiklik yeterlidir:
<Project Sdk="MSTest.Sdk/4.4.0">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<PublishAot>true</PublishAot>
</PropertyGroup>
<!-- Keep your existing ItemGroup elements and project references. -->
</Project>
MSTest.Sdk, varsayılan olarak Microsoft Testing Platform’u kullanır. PublishAot özelliği etkinleştirildiğinde MSTest kaynak üretimi ve yerel yürütülebilir dosya yolu açılır.
VSTest kullanan projelerin Microsoft Testing Platform’a geçiş kılavuzuna bakması gerekir. Komut satırı bağımsız değişkenleri, CI entegrasyonu ve desteklenen .runsettings girdileri farklı olabilir.
Test projesi, uygulamanın yayımlanacağı işletim sistemi ve mimariyle aynı hedef için yayımlanmalıdır:
dotnet publish./MyProject.Tests/MyProject.Tests.csproj \
-c Release -r linux-x64 -o./artifacts/native-tests
./artifacts/native-tests/MyProject.Tests
Bu örnekte linux-x64 çalışma zamanı tanımlayıcısı kullanılıyor. Dağıtım hedefinize göre win-x64 veya osx-arm64 gibi uygun RID değerini seçin. Windows üzerinde oluşturulan yürütülebilir dosya MyProject.Tests.exe olarak çalıştırılır. Proje yolunu da kullandığınız test projesine göre değiştirmeniz gerekir.
Yönetilen ve Native AOT test katmanlarını birlikte çalıştırın
Yönetilen testler hızlı geliştirme geri bildirimi sağlar. Native AOT test katmanı ise uygulamanın dağıtım modelini kontrol eder. İki süreç farklı sorulara yanıt verdiğinden birlikte kullanıldıklarında daha anlamlı bir sonuç verir.
CI sürecinde önce tek bir temsili test projesiyle başlanabilir:
- Mevcut yönetilen test çalıştırmasını koruyun.
- Temsili bir test projesini Native AOT olarak yayımlayıp çalıştırın.
- Her iki katmanın da beklenen test sayısını ve sonuçlarını aynı şekilde keşfettiğini doğrulayın.
- Native AOT yayımlama ve çalıştırma süresini test yürütme süresinden ayrı kaydedin.
- Ek güven CI maliyetini haklı çıkarıyorsa kapsamı genişletin.
Bu çalışmaya zamanlanmış bir işte veya sürüm doğrulama sürecinde başlanabilir. Native AOT hattının geri bildirim değeri ve yayımlama süresi uygunsa hat her pull request’e taşınabilir.
Temsili proje; serileştirme, bağımlılık ekleme, yapılandırma bağlama, yansıma tabanlı eklentiler veya Native AOT desteğinin doğrulanması gereken bir bağımlılık gibi dağıtıma duyarlı yolları içermelidir. Yalnızca aritmetik işlemleri test eden bir proje çalıştırıcının işlediğini gösterebilir, ancak yayımlanan uygulama hakkında sınırlı bilgi verir.
Test sayılarının eşleşmesi bir sürüm kapısı olarak kullanılmalıdır. Bir test sınıfı oluşturulan kayda giremediğinde kayıtlı alt küme başarılı olabilir ve süreç yine de başarıyla tamamlanabilir. Bu durum, sınıfın yalnızca [TestClass] sınıfından kalıtım alması, erişilemez veya dosyaya özel olması, statik ya da açık generic bir tür olması gibi nedenlerle ortaya çıkabilir. İlgili tanıların yok sayılması veya bastırılması da test sayısı farkını gizleyebilir.
Native AOT yolundaki sınırlar
Kaynak üretimi sıfır yansıma anlamına gelmez. Varsayılan ReflectionFree modu, desteklenen oluşturma ve çağırma işlemleri için üretilmiş öznitelikleri ve temsilcileri kullanır; ancak bazı işlemlerde yansıma tabanlı geri dönüş yolları bulunabilir.
Uyumluluğu incelemek için aşağıdaki yapılandırma kullanılabilir:
<PropertyGroup>
<MSTestSourceGenMode>Rooting</MSTestSourceGenMode>
</PropertyGroup>
Rooting modu keşfedilen test üyelerini korur, ancak yürütme sırasında yansıma kullanır.
Başlıca geçiş sınırlamaları şunlardır:
[TestClass]sınıfından yalnızca kalıtım alan sınıflar için öznitelik doğrudan bildirilmelidir.MSTEST0069tanısı bu yapıyı belirler.- Test sınıfı erişilebilir, somut ve statik olmayan kapalı bir tür olmalıdır. Soyut temel fikstürler, somut bir türetilmiş test sınıfı üzerinden desteklenmeye devam eder.
- Generic test metotları ile
ref,outveyainparametreleri kullanan metotlar desteklenen bir imzaya taşınmalıdır. [AssemblyFixtureProvider]kullanan projeler, Native AOT çalıştırmasına güvenmeden önce desteklenen bir fikstür modeline geçmelidir.- Bazı MSTest SDK entegrasyonları, Microsoft Testing Platform uzantıları ve CI raporlayıcıları Native AOT yolunda kullanılamayabilir. TRX ve Code Coverage desteklenmeye devam eder.
Derleyici ve analizör tanıları bastırılacak uyarılar olarak değil, geçiş kapıları olarak ele alınmalıdır. Güncel destek kapsamı için MSTest SDK belgelerine bakılmalıdır.
Performans değil, dağıtım benzerliği öncelikli
Kaynak üretimi, tüm derlemede Assembly.GetTypes() taramasını ve desteklenen testler için yansıma tabanlı oluşturma ve çağırma işlemlerini önleyebilir. Bu, başlangıç ve keşif çalışmalarını azaltabilir; ancak uçtan uca çalışmanın kesin olarak hızlanacağı anlamına gelmez. Toplam süreyi test yürütme, süreç başlangıcı, yayımlama ve kalan yansıma işlemleri belirleyebilir.
Bu nedenle performans, Native AOT altında test çalıştırmanın temel gerekçesi değildir. Buradaki değer, testin ve uygulamanın aynı kırpma ve önceden derleme modelini kullanmasıdır. Native AOT testleri son uygulama paketinin uçtan uca üretim doğrulamasının yerini almaz; yapılandırma, işletim sistemi, mimari, dış servisler ve paketleme yine farklı olabilir.
En uygun başlangıç, Native AOT ile yayımlanan kod yollarını kullanan tek bir projedir. Ortaya çıkan dağıtıma özgü hata, test sayısı uyuşmazlığı veya sorunsuz yerel çalıştırma, bu hattın ek güven sağlayıp sağlamadığını değerlendirmeye yardımcı olur. Sonrasında kapsam genişletilebilir, yaklaşım iyileştirilebilir veya pilot durdurulabilir.
Kaynaklar ve İleri Okuma
- MSTest kaynak üretimi ve Native AOT testi
- .NET Native AOT dağıtımı
- Kendi içinde çalışan uygulamaları kırpma
- System.Text.Json kaynak üretimi
- Native AOT.NET uygulamalarını test etme
- VSTest’ten Microsoft Testing Platform’a geçiş
- MSTEST0069 analizörü
- MSTest SDK belgeleri







Yorum gönder