Gerçek bir koşu

Spectre.Console'da gerçek bir değişiklik (commit 01027ef), kapsam haritasından job summary'ye kadar. Bu sayfadaki her çıktı elle yazılmadı, o koşudan kopyalandı.

Değişiklik

Rule widget'ında tek satırlık bir refactoring. Davranışı değiştirmez, ama bir kod değişikliğidir; bu yüzden normal bir pipeline 141 sınıftaki 787 testin tamamını her hedef framework'te çalıştırırdı.

// src/Spectre.Console/Widgets/Rule.cs, GetLineWithoutTitle
 var text = border.GetPart(BoxBorderPart.Top).Repeat(maxWidth);
+var style = Style ?? Spectre.Console.Style.Plain;

 return
 [
-    new Segment(text, Style ?? Spectre.Console.Style.Plain),
+    new Segment(text, style),
     Segment.LineBreak
 ];

Koşu

Harita main üzerinde td record ile kaydedildi. Ardından pull request şunu çalıştırır:

$ td test --base main -- -f net10.0td: 1 changed file(s), 1 affected test project(s).Tests to run:  filtered src/Spectre.Console.Tests/Spectre.Console.Tests.csproj    (14 of 141 test class(es) run or reference the changed code, 0.6 s of 3.0 s (80% saved))Recorded test time: 0.6 s of 3.4 s (83% saved).Passed!  - Failed:     0, Passed:   156, Skipped:     0, Total:   156 - Spectre.Console.Tests.dll (net10.0)td summary:  passed  src/Spectre.Console.Tests/Spectre.Console.Tests.csproj  (14 class(es), 4.6 s)1 project(s) run, 0 failed, 0 skipped.Recorded test time: 0.6 s of 3.4 s (83% saved).

141 sınıftaki 787 test yerine 14 sınıftaki 156 test çalıştı. Spectre.Console.Ansi.Tests projesi derlenmedi bile: bağımlı olduğu hiçbir şey değişmedi.

Doğru 14 sınıf bunlar mıydı?

Kontrol etmek için GetLineWithoutTitle metodunun exception fırlatmasını sağladık ve tüm test paketini çalıştırdık. Tam olarak 14 sınıf başarısız oldu ve bunlar TestDetta'nın seçtiği 14 sınıfın ta kendisi: AlignTests+Center, +Left, +Right, CanvasTests, ColumnsTests, ExceptionTests, LayoutTests, PadderTests, PanelTests, RecorderTests, RowsTests, RuleTests, TableTests ve TextPathTests. Bunların çoğu Rule'dan hiç bahsetmez: ona layout'lar ve panel'ler üzerinden ulaşır; kapsam haritası bunu bilir, isimle arama ise bilemezdi.

Job summary

--summary-file "$GITHUB_STEP_SUMMARY" ile (GitHub Action bunu sizin için ayarlar) her pull request şu özeti alır: neyin çalıştığı, her sınıfın neden çalıştığı ve neyin atlandığı.

TestDetta test selection

1 changed file(s) compared with main.

  • 1 of 1 affected test project(s) ran, 0 skipped.
  • Recorded test time: 0.6 s of 3.4 s (83% saved).
  • All selected tests passed.
  • src/Spectre.Console.Tests/Spectre.Console.Tests.csproj: passed, 14 test class(es), recorded time 0.6 s of 3.0 s (80% saved)
    • why: 14 of 141 test class(es) run or reference the changed code
    • classes:
      • AlignTests+Center: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • AlignTests+Left: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • AlignTests+Right: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • CanvasTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • ColumnsTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • ExceptionTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • LayoutTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • PadderTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • PanelTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • RecorderTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • RowsTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • RuleTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • TableTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
      • TextPathTests: ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)
    • skipped: 127 class(es) that ran none of the changed code and name none of it

Sınıf adları burada kısaltılmıştır; özet onları tam haliyle yazdırır (Spectre.Console.Tests.Unit.RuleTests).

Nedenini sormak

Her kararın okuyabileceğiniz bir gerekçesi vardır. -v bu izi stderr'e yazar:

[DBG] CodeChangeDetector: src/Spectre.Console/Widgets/Rule.cs: Modified Spectre.Console.Rule GetLineWithoutTitle(RenderOptions,int)
[DBG] CodeChangeDetector: src/Spectre.Console/Widgets/Rule.cs: 1 changed symbol(s), affects whole project: False
[DBG] TestSelector: Spectre.Console.Rule GetLineWithoutTitle(RenderOptions,int) is affected because it changed
[DBG] TestSelector: Spectre.Console.Rule Render(RenderOptions,int) is affected because GetLineWithoutTitle
[DBG] TestSelector: Spectre.Console.Rule GetLineWithoutTitle(RenderOptions,int): test classes taken from coverage

--format json ise script'ler ve dashboard'lar için her sınıfın kararını, kanıtı ve bir süre tahminiyle birlikte verir:

{
  "project": "src/Spectre.Console.Tests/Spectre.Console.Tests.csproj",
  "mode": "Filtered",
  "reason": "14 of 141 test class(es) run or reference the changed code",
  "estimate": {
    "fullSeconds": 3,
    "selectedSeconds": 0.6,
    "savedSeconds": 2.4
  },
  "decisions": [
    {
      "class": "Spectre.Console.Tests.Unit.AlignTests+Center",
      "selected": true,
      "kind": "coverage",
      "evidence": "ran Spectre.Console.Rule.GetLineWithoutTitle(RenderOptions,int), which changed (map 01027efcd6c4)"
    },
    {
      "class": "Spectre.Console.Tests.PublicApiTests",
      "selected": false,
      "kind": "skipped",
      "evidence": "ran none of the changed code and names none of it (map 01027efcd6c4)"
    },
    "…139 more"
  ]
}

Testleri kendi yönteminizle çalıştırmak

td affected --format commands, TestDetta'nın yapacağı dotnet test çağrısını yazdırır; böylece onu kendi script'inizde çalıştırabilirsiniz:

dotnet test src/Spectre.Console.Tests/Spectre.Console.Tests.csproj --filter 'FullyQualifiedName~Spectre.Console.Tests.Unit.AlignTests+Center.|FullyQualifiedName~Spectre.Console.Tests.Unit.AlignTests+Left.|FullyQualifiedName~Spectre.Console.Tests.Unit.AlignTests+Right.|FullyQualifiedName~Spectre.Console.Tests.Unit.CanvasTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.ColumnsTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.ExceptionTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.LayoutTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.PadderTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.PanelTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.RecorderTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.RowsTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.RuleTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.TableTests.|FullyQualifiedName~Spectre.Console.Tests.Unit.TextPathTests.'

40 depo genelinde

Tek bir değişiklik tek bir veri noktasıdır. Değerlendirme korpusunda 40 açık kaynak kütüphanenin üyeleri tek tek değiştirilir; tek bir üyedeki değişiklik için TestDetta test sınıflarının medyan %28 kadarını çalıştırdı, 40 deponun 18'inde ise dörtte bir ya da daha azını. Neredeyse her testin çekirdeğe dokunduğu kütüphaneler (Scriban, Markdig) az kazanır; en çok katmanlı kod kazanır. Başarısız olan her sınıf seçimle karşılaştırıldı: testleri bozan 2,941 değişiklikte 3 kaçırma oldu ve her biri düzeltildi.

Depoya göre, değişiklik başına çalıştırılan test sınıfı oranı Değerlendirme korpusunun 1. turu: 40 deponun her biri için, tek bir üyedeki değişiklikte TestDetta tarafından seçilen test sınıflarının ortalama oranı. Medyan %28. 0% 25% 50% 75% 100% opentelemetry-dotnet: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %6opentelemetry-dotnet6% polly: testleri bozan 65 değişiklikte ortalama çalıştırılan test sınıfı oranı %7polly7% roslynator: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %8roslynator8% spectre: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %9spectre9% swashbuckle: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %12swashbuckle12% nsec: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %13nsec13% aspnetcore-odata: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %13aspnetcore-odata13% guardclauses: testleri bozan 24 değişiklikte ortalama çalıştırılan test sınıfı oranı %13guardclauses13% mimekit: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %14mimekit14% autofixture: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %16autofixture16% communitytoolkit: testleri bozan 76 değişiklikte ortalama çalıştırılan test sınıfı oranı %18communitytoolkit18% libgit2sharp: testleri bozan 57 değişiklikte ortalama çalıştırılan test sınıfı oranı %19libgit2sharp19% castle-core: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %19castle-core19% serilog: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %20serilog20% mediator: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %21mediator21% fastendpoints: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %23fastendpoints23% fluid: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %23fluid23% carter: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %24carter24% lamar: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %26lamar26% awesomeassertions: testleri bozan 81 değişiklikte ortalama çalıştırılan test sınıfı oranı %27awesomeassertions27% nsubstitute: testleri bozan 3 değişiklikte ortalama çalıştırılan test sınıfı oranı %29nsubstitute29% immediate-handlers: testleri bozan 43 değişiklikte ortalama çalıştırılan test sınıfı oranı %29immediate-handlers29% open-xml-sdk: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %30open-xml-sdk30% fluentvalidation: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %32fluentvalidation32% unitsnet: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %34unitsnet34% vogen: testleri bozan 77 değişiklikte ortalama çalıştırılan test sınıfı oranı %36vogen36% nodatime: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %43nodatime43% graphql-dotnet: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %45graphql-dotnet45% newtonsoft-json: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %47newtonsoft-json47% autofac: testleri bozan 77 değişiklikte ortalama çalıştırılan test sınıfı oranı %49autofac49% scrutor: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %57scrutor57% meziantou-analyzer: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %63meziantou-analyzer63% automapper: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %67automapper67% protobuf-net: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %78protobuf-net78% yamldotnet: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %78yamldotnet78% cliwrap: testleri bozan 69 değişiklikte ortalama çalıştırılan test sınıfı oranı %81cliwrap81% nlog: testleri bozan 65 değişiklikte ortalama çalıştırılan test sınıfı oranı %82nlog82% mapperly: testleri bozan 79 değişiklikte ortalama çalıştırılan test sınıfı oranı %89mapperly89% markdig: testleri bozan 80 değişiklikte ortalama çalıştırılan test sınıfı oranı %98markdig98% scriban: testleri bozan 71 değişiklikte ortalama çalıştırılan test sınıfı oranı %100scriban100%
Değişiklik başına çalıştırılan test sınıflarının ortalama oranı, değerlendirmenin 1. turu. Arkasındaki değişiklik sayısını görmek için imleci bir satırın üzerine getirin.