0Pricing
C# Academy · Ders

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

Hızlı kontrol: Aralıklı olarak başarısız olan bir test DateTime.UtcNow ve new Random() kullanıyor. En iyi ilk adım nedir?

Ö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

  1. xUnit/MSTest kurulumu ve doğrulamalar
  2. Arayüzlerle sahte nesneler ve test verisi oluşturucuları
  3. Başarısız testlerde hata ayıklama
← C# Academy Sayfasına Dön