Başarısız testlerde hata ayıklama
Başarısızlıkları yeniden üretilebilir hâle getirin, zamanı ve rastgeleliği kaldırın, durumu en küçük örneğe indirgeyin ve hızlı tanılama için doğrulama iletilerini iyileştirin.
Başarısız testlerde hata ayıklama, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 3 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 3 dersten oluşur.
Oyun planı
Başarısız testleri düzeltmek için plan:
- Güvenilir biçimde yeniden üretin
- Kararsızlığı giderin (zaman/rastgelelik G/Ç'si)
- En küçük başarısız duruma kadar küçültün
- Açık doğrulama iletileri ekleyin
Tasarım gereği kararsız
UtcNow ve varsayılan Random kullanmak, davranışın çalıştırmalar arasında değişmesine neden olur → kararsız testler.
using System;
// Demo: occasionally fails because it depends on current second and default Random()
public static class Promo
{
// Gives bonus on even seconds; random adds small jitter
public static int BonusNow()
{
int baseBonus = (DateTime.UtcNow.Second % 2 == 0) ? 10 : 9;
Random r = new Random(); // time-based seed → unpredictable
return baseBonus + (r.Next(0, 2)); // 0 or 1 more
}
}
public class Program
{
public static void Main(string[] args)
{
// Simulated test: sometimes expects exactly 10, but result varies
int got = Promo.BonusNow();
if (got != 10) Console.WriteLine("FAIL (flaky): expected 10 but got " + got);
else Console.WriteLine("PASS (maybe): got " + got);
}
}
Bağımlılıkları denetleme
Zamanı ve Random'ı ekleyin. Sabit bir tohum ve sabit bir zaman damgasıyla başarısızlık yeniden üretilebilir hâle gelir.
using System;
public interface IClock { DateTime NowUtc(); }
public sealed class FakeClock : IClock
{
private readonly DateTime _fixedUtc;
public FakeClock(DateTime fixedUtc) { _fixedUtc = fixedUtc; }
public DateTime NowUtc() { return _fixedUtc; }
}
public sealed class PromoDeterministic
{
private readonly IClock _clock;
private readonly Random _rng;
public PromoDeterministic(IClock clock, Random rng) { _clock = clock; _rng = rng; }
public int BonusNow()
{
int baseBonus = (_clock.NowUtc().Second % 2 == 0) ? 10 : 9;
return baseBonus + _rng.Next(0, 2);
}
}
public static class Assert
{
public static void AreEqual(int expected, int actual, string msg)
{
if (expected != actual) throw new Exception("Expected " + expected + " but got " + actual + " :: " + msg);
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
IClock clock = new FakeClock(new DateTime(2016, 1, 1, 0, 0, 20, DateTimeKind.Utc)); // even second
Random rng = new Random(123); // fixed seed
PromoDeterministic p = new PromoDeterministic(clock, rng);
int got = p.BonusNow(); // predictable now
Assert.AreEqual(10, got, "even second, first draw should be 0");
Console.WriteLine("PASS: deterministic promo");
}
catch (Exception ex)
{
Console.WriteLine("FAIL: " + ex.Message);
}
}
}
En küçük yeniden üretim
Küçük bir örnek başarısız olana kadar girdileri küçültün (burada: boş dizi). Küçük durumlar üzerinde düşünmek daha kolaydır.
using System;
// Buggy function: average of ints, but divides by count without guarding empty input
public static class Stats
{
public static double Average(int[] xs)
{
int sum = 0;
for (int i = 0; i < xs.Length; i++) sum += xs[i];
return sum / xs.Length; // BUG: divide by zero if empty; also int division truncates
}
}
public static class Assert
{
public static void Throws<T>(Action a, string msg) where T : Exception
{
try { a(); }
catch (Exception ex)
{
if (ex is T) return;
throw new Exception("Expected " + typeof(T).Name + " but got " + ex.GetType().Name + " :: " + msg);
}
throw new Exception("Expected " + typeof(T).Name + " but no exception thrown :: " + msg);
}
}
public class Program
{
public static void Main(string[] args)
{
// Minimal failing case: empty array
Assert.Throws<DivideByZeroException>(delegate { Stats.Average(new int[0]); }, "empty input");
Console.WriteLine("Reproduced: empty input triggers the bug.");
}
}
Düzeltme ve ileti kalitesi
Geçersiz girdilere karşı koruma ekleyin ve açıklayıcı doğrulama iletileri kullanın (girdileri, beklenen değeri ve epsilon'u ekleyin).
using System;
public static class Stats
{
public static double Average(int[] xs)
{
if (xs == null) throw new ArgumentNullException("xs");
if (xs.Length == 0) throw new ArgumentException("xs must not be empty", "xs");
double sum = 0.0; // use double to avoid integer truncation
for (int i = 0; i < xs.Length; i++) sum += xs[i];
return sum / xs.Length;
}
}
public static class Assert
{
public static void AreAlmostEqual(double expected, double actual, double eps, string msg)
{
if (Math.Abs(expected - actual) > eps)
throw new Exception("Expected " + expected + " but got " + actual + " (eps " + eps + ") :: " + msg);
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
double a = Stats.Average(new int[] { 2, 4, 6 });
Assert.AreAlmostEqual(4.0, a, 1e-9, "average of 2,4,6");
Console.WriteLine("PASS: fixed average with clear message");
}
catch (Exception ex)
{
Console.WriteLine("FAIL: " + ex.Message);
}
}
}
Hata ayıklama kontrol listesi
Hata ayıklama kontrol listesi:
- Bağımlılıkları kararlı hâle getirin (zaman, rastgelelik, G/Ç)
- Yerel olarak ve art arda yeniden üretin
- En küçük başarısız girdiye kadar küçültün
- Kesin doğrulama iletileri ekleyin
- Saf işlevleri ve koruyucu kontrolleri tercih edin
Kararsız testler için ilk adım
Özet
Özet: Zamanı/rastgeleliği denetleyerek güvenilir biçimde yeniden üretin, girdiyi küçültün ve hatanın yerini hızlıca belirlemek için yararlı doğrulama iletileri yazın.
Sıkça Sorulan Sorular
“Başarısız testlerde hata ayıklama” dersi ücretsiz mi?
Evet — “Başarısız testlerde hata ayıklama” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 3 dersten oluşur.
“Başarısız testlerde hata ayıklama” dersinde ne öğreneceğim?
Başarısızlıkları yeniden üretilebilir hâle getirin, zamanı ve rastgeleliği kaldırın, durumu en küçük örneğe indirgeyin ve hızlı tanılama için doğrulama iletilerini iyileştirin. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C# Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 3 dersinin 3. dersidir.
“Başarısız testlerde hata ayıklama” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- xUnit/MSTest kurulumu ve doğrulamalar
- Arayüzlerle sahte nesneler ve test verisi oluşturucuları
- Başarısız testlerde hata ayıklama