-
Notifications
You must be signed in to change notification settings - Fork 80
1004 wordle #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
varhegyimeli
wants to merge
3
commits into
bmeaut:gh-pages
Choose a base branch
from
varhegyimeli:1004_Wordle
base: gh-pages
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
1004 wordle #96
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,328 @@ | ||
| --- | ||
| layout: default | ||
| codename: Wordle | ||
| title: Test-Driven Wordle klón fejlesztés MI segítségével | ||
| tags: snippets mieset | ||
| authors: Várhegyi Melinda | ||
| --- | ||
|
|
||
| # Test-Driven Wordle klón fejlesztés MI segítségével | ||
|
|
||
| ## A feladat leírása | ||
|
|
||
| A feladat egy Wordle szójáték klón elkészítése volt .NET MAUI keretrendszerben, C# nyelven, | ||
| Windows platformra célozva (`net8.0-windows10.0.19041.0`), Visual Studio 2022-ben. | ||
| A Wordle játék lényege röviden: Egy 5 betűs szavakat tartalmazó szólistából sorsolunk egy feladványt, | ||
| melyet a felhasználó megpróbál megfeljebb 6 próbálkozásból kitalálni. Minden beküldött tippjének | ||
| betűit kiértéklejük aszerint, hogy a feladvány tartalmazza-e az adott betűt. | ||
| (Ugyanazon a helyen tartalmazza - zöld, tartalmazza, de másik helyen - sárga, nem tartalmazza - szürke.) | ||
|
|
||
| A fejlesztés során használt MI eszközök: | ||
|
|
||
| - **GitHub Copilot Chat (Claude Haiku 4.5)** — a kód generálásához és a TDD ciklus végrehajtásához | ||
| - **Claude Sonnet 4.6 (desktop alkalmazás)** — tervezéshez, architektúra döntésekhez, prompt íráshoz és | ||
| hibakereséshez | ||
|
|
||
| A projekt MVVM architektúrán alapul, a fejlesztés TDD (Test Driven Development) | ||
| módszerrel történt, xUnit, Moq és FluentAssertions könyvtárak használatával. | ||
|
|
||
| --- | ||
|
|
||
| ## Tanulságok | ||
|
|
||
| - **A kontextus átadása kulcsfontosságú.** Minél részletesebb és pontosabb promptot kap a Copilot, | ||
| annál jobb kódot generál. Az egyszerű, rövid kérések általában rossz vagy hiányos eredményt adnak. | ||
| - **A TDD workflow jól kombinálható az MI-vel**, de egyes tesztek megírása emberi feladat marad — | ||
| különösen az összetett edge case-ek esetén (pl. duplikált betűk kezelése a Wordle logikában). | ||
| - **Copilot nem látja a renderelt UI-t**, így vizuális hibák debuggolásában (pl. gomb layout) | ||
| korlátozott a segítsége. Az ilyen problémákat sajátkezűleg kell megoldani. | ||
| - **A Copilot hajlamos hibás architektúra döntéseket javasolni** — pl. rossz target framework, | ||
| felesleges `<RuntimeIdentifier>` a `.csproj`-ban, inkompatibilis NuGet csomagok. | ||
| Ezeket mindig kritikusan kell értékelni. | ||
| - **Az összetett logikai edge case-eket a Copilot nem kezeli helyesen** — a duplikált betűk | ||
| Wordle szabály szerinti kiértékelési logikáját kézzel kellett megírni. | ||
| - **A kontextus elvész** — ha a Copilot Chat ablak bezárul (pl. VS összeomlás vagy fájlok | ||
| áthelyezése után), az összes korábbi kontextus elveszik. Érdemes a kontextus promptot | ||
| külön fájlban tárolni és újra beadni. | ||
| - **Claude Sonnet 4.6 és Copilot (Claude Haiku 4.5) jól kiegészítik egymást** — Claude | ||
| erős volt a tervezésben, architektúrában és hibakeresésben, a Copilot pedig a kód generálásban. | ||
| - **A mutációs tesztelés és az MI jól kombinálható** — a Stryker által talált túlélő | ||
| mutánsokat Copilottal hatékonyan meg lehet ölni, de a promptot pontosan kell | ||
| megfogalmazni: meg kell adni a mutáns pontos helyét és viselkedését. | ||
| - **A Copilot törlési feladatoknál megbízhatatlan** — amikor kódot kellett törölni, | ||
| Copilot váratlan módosításokat végzett más fájlokban is. Törlési feladatokat | ||
| érdemes kézzel elvégezni. | ||
|
|
||
| --- | ||
|
|
||
| ## A megvalósított rendszer | ||
|
|
||
| ### Projektstruktúra (4 projekt) | ||
|
|
||
| ``` | ||
| WordleMAUI/ ← .NET MAUI alkalmazás — csak nézetek (XAML) | ||
| WordleMAUI.Core/ ← Class Library — modellek és szolgáltatások (pure C#) | ||
| WordleMAUI.ViewModels/ ← Class Library — GameViewModel (CommunityToolkit.Mvvm) | ||
| WordleMAUI.Tests/ ← xUnit tesztprojekt | ||
| ``` | ||
|
|
||
| **Projekt hivatkozások:** | ||
| - `WordleMAUI` → `WordleMAUI.ViewModels` → `WordleMAUI.Core` | ||
| - `WordleMAUI.Tests` → `WordleMAUI.ViewModels` és `WordleMAUI.Core` | ||
| - `WordleMAUI.Tests` nem hivatkozik `WordleMAUI`-ra (WinRT inicializálási hiba miatt) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Itt érdemes megemlíteni, hogy ennek részleteiről később is lesz szó. |
||
| *Ennek a részleteiről a 3. pontban lesz szó.* | ||
|
|
||
| ### Főbb komponensek | ||
|
|
||
| | Komponens | Leírás | | ||
| |---|---| | ||
| | `LetterState` | enum: Correct, Misplaced, Absent | | ||
| | `GuessResult` | record: char Letter, LetterState State | | ||
| | `WordValidator` | 5 betűs, szótárban szereplő szavak ellenőrzése | | ||
| | `GuessEvaluator` | Betűnkénti kiértékelés, duplikált betűk helyes kezelésével | | ||
| | `GameStateManager` | Játékállapot kezelése (6 kísérlet, nyerés/vesztés) | | ||
| | `WordSelector` | Véletlenszerű szókiválasztás | | ||
| | `GameViewModel` | MVVM ViewModel, összeköti a logikát és a UI-t | | ||
|
|
||
| --- | ||
|
|
||
| ## A munkafolyamat tanulságos részletei | ||
|
|
||
| ### 1. A TDD workflow MI-vel | ||
|
|
||
| A fejlesztés az alábbi ciklust követte minden komponensnél: | ||
|
|
||
| ``` | ||
| 1. Tesztnevek megírása (szándék leírása) | ||
| 2. Copilot által tesztek generálása | ||
| 3. Copilot javaslatának kritikus értékelése | ||
| 4. Tesztek alapján kód generálása | ||
| 5. Tesztek futtatása, felmerülő hibák javítása | ||
| 6. Összes teszt zöld -> kész a komponens | ||
| ``` | ||
|
|
||
| Ez a workflow az egyszerűbb komponenseknél (pl. `WordValidator`, `GameStateManager`) | ||
| jól működött. Copilot gyorsan generált helyes implementációt, mivel a tesztek neve | ||
| egyértelműen leírta a szándékot. | ||
|
|
||
| **Példa sikeres promptra (Phase 2 implementáció):** | ||
|
|
||
| ``` | ||
| The unit tests for Phase 2 — Core Domain Layer are written and finalized. | ||
| Now implement the production code to make all tests pass, one class at a time | ||
| in the order below. Do not move to the next class until all tests for the | ||
| current one are green. | ||
|
|
||
| ## Rules | ||
| - All strings are uppercase — no case conversion needed in any service | ||
| - Use the exact class and interface names specified below | ||
| - Do not add any methods or properties that are not required by the tests | ||
| - All classes are plain C# with zero UI dependencies | ||
|
|
||
| ## Implementation Order | ||
| [...] | ||
| ``` | ||
|
|
||
| ### 2. A duplikált betűk problémája | ||
|
|
||
| A `GuessEvaluator` implementálása során a duplikált betűk helyes kezelése | ||
| nem zajlott zökkenőmentesen. A Wordle szabályai szerint: | ||
|
|
||
| - Ha a tippben egy betű többször szerepel, mint a feladványban, a felesleges | ||
| előfordulások `Absent` jelölést kapnak | ||
| - A helyes pozíciókat (`Correct`) kell először meghatározni, és csak ezután | ||
| a rosszul pozicionált (`Misplaced`) betűket | ||
|
|
||
| A Copilot még részletes magyarázat után sem generált helyes | ||
| duplikált betű logikát. Az ehhez kapcsolódó teszteket végül kézzel kellett megírni. | ||
|
|
||
| **Példa edge case teszt (kézzel írva):** | ||
|
|
||
| ```csharp | ||
| [Fact] | ||
| public void GivenDuplicateLetterInGuess_WhenOnlyOneExistsInSecret_ShouldMarkSecondAsAbsent() | ||
| { | ||
| var guess = "AWAKE"; // Two A's in guess | ||
| var secret = "STARE"; // Only one A in secret at position 2 | ||
|
|
||
| var result = _evaluator.Evaluate(guess, secret); | ||
|
|
||
| result.Should().HaveCount(5); | ||
| // A is in STARE at position 2, BUT the other A in guess at position 2 is correct -> Absent | ||
| result[0].State.Should().Be(LetterState.Absent); | ||
| // W is not in STARE -> Absent | ||
| result[1].State.Should().Be(LetterState.Absent); | ||
| // A is in STARE at position 2 (correct position in guess) -> Correct | ||
| result[2].State.Should().Be(LetterState.Correct); | ||
| // K is not in STARE -> Absent | ||
| result[3].State.Should().Be(LetterState.Absent); | ||
| // E is in STARE at position 4 (correct position in guess) -> Correct | ||
| result[4].State.Should().Be(LetterState.Correct); | ||
| } | ||
| ``` | ||
|
|
||
| **Tanulság:** Az összetett üzleti logikát tartalmazó teszteket nem érdemes | ||
| a Copilotra bízni. Az ilyen tesztek megírása emberi feladat, a Copilot feladata az | ||
| implementáció generálása a tesztek alapján. | ||
|
|
||
| ### 3. Architektúra probléma — WinRT hiba a tesztek futtatásakor | ||
|
|
||
| Az első megközelítésben a tesztprojekt közvetlenül hivatkozott a MAUI projektre. | ||
| Ez `System.TypeInitializationException` hibát okozott, mert a MAUI projekt | ||
| betölti a WinRT runtime-ot, ami nem elérhető a tesztfuttató környezetben. | ||
|
|
||
| **Copilot javasolta megoldás:** A tesztprojekt target frameworkjét `net8.0`-ra | ||
| állítani — ez hibás volt, mert a framework eltérése miatt a projekthivatkozás | ||
| sem működött. | ||
|
|
||
| **Helyes megoldás:** Külön osztálykönyvtár projektek | ||
| létrehozása (`WordleMAUI.Core` és `WordleMAUI.ViewModels`), amelyek nem | ||
| húzzák be a WinRT függőségeket. A tesztprojekt csak ezekre hivatkozik, | ||
| a MAUI projektre nem. | ||
|
|
||
| **Tanulság:** A Copilot hajlamos a legegyszerűbb technikai megoldást javasolni, | ||
| ami nem mindig az architektúrailag helyes döntés. Az ilyen döntéseknél emberi | ||
| felülvizsgálat szükséges. | ||
|
|
||
| ### 4. Projekt konfiguráció hibák — .csproj problémák | ||
|
|
||
| Copilot több hibás `.csproj` módosítást javasolt: | ||
|
|
||
| | Copilot javaslata | Probléma | Helyes megoldás | | ||
| |---|---|---| | ||
| | `<TargetFramework>net8.0</TargetFramework>` a tesztprojektben | Framework eltérés, hivatkozás nem működik | `net8.0-windows10.0.19041.0` | | ||
| | `<RuntimeIdentifier>win10-x64</RuntimeIdentifier>` | Felesleges, projekt hivatkozási problémákat okoz | Törlés | | ||
| | `CommunityToolkit.Maui` NuGet csomag | Verzió inkompatibilitás | Csomag eltávolítása | | ||
|
|
||
| **Tanulság:** A `.csproj` fájlokat mindig kritikusan kell átnézni, mielőtt | ||
| elfogadjuk a Copilot javaslatát. Ha valami furcsának tűnik, valószínűleg az is. | ||
|
|
||
| ### 5. A kontextus prompt fontossága | ||
|
|
||
| Mivel a Copilot Chat nem őrzi meg a kontextust munkamenetek között (pl. VS | ||
| összeomlás, fájlok áthelyezése után), részletes kontextus promptot kellett készíteni, | ||
| amelyet minden új munkamenet elején be kellett adni. Ez tartalmazta: | ||
|
|
||
| - A projekt teljes struktúráját | ||
| - Az összes projekt hivatkozást | ||
| - A már implementált komponensek interfészeit | ||
| - A fejlesztési konvenciókat (csak nagybetűs szavak, nincs `CommunityToolkit.Maui` stb.) | ||
| - Az aktuális fázist és feladatot | ||
|
|
||
| **Példa kontextus prompt részlet:** | ||
|
|
||
| ``` | ||
| You are helping me build a Wordle clone called WordleMAUI using .NET MAUI | ||
| targeting net8.0-windows10.0.19041.0 in Visual Studio 2022 with .NET 8.0. | ||
| [...] | ||
| Note: CommunityToolkit.Maui is NOT installed due to version incompatibility. | ||
| Do not suggest or use any APIs from it. | ||
| [...] | ||
| We follow strict TDD: tests are always written before implementation. | ||
| Never generate implementation before tests unless I ask. | ||
| ``` | ||
|
|
||
| **Tanulság:** Minél pontosabb és részletesebb a kontextus prompt, annál kevesebb | ||
| hibás javaslatot ad a Copilot. A negatív megszorítások (pl. "ne használd ezt a | ||
| csomagot") különösen fontosak. | ||
|
|
||
| ### 6. A UI fejlesztés kihívásai | ||
|
|
||
| A MAUI XAML UI generálásánál a Copilot hasznos volt az alapstruktúra elkészítésében, | ||
| de a vizuális hibák javításában korlátozott segítséget nyújtott, mivel nem látja | ||
| a renderelt eredményt. | ||
|
|
||
| **Konkrét példa — billentyűzet layout:** | ||
| A virtuális billentyűzet gombjainak helyes elhelyezése több lépésen keresztül tartott: | ||
| - Copilot egymás után javasolt fix pixel szélességeket, padding és margin értékeket | ||
| - Ezek egyike sem oldotta meg a problémát | ||
| - A végső megoldás a MAUI `Button` vezérlő `MinimumWidthRequest="0"` tulajdonsága | ||
| volt | ||
|
|
||
| **Tanulság:** A vizuális UI debuggolás emberi feladat. A Copilot tud XAML kódot | ||
| generálni, de a renderelt eredményt nem látja, ezért vizuális javításra | ||
| nem feltétlenül alkalmas. | ||
|
|
||
|
|
||
| ### 7. Mutációs tesztelés Stryker.NET-tel | ||
|
|
||
| A fejlesztés végén mutációs tesztelést végeztünk a Stryker.NET eszközzel (v4.14.0) | ||
| a `WordleMAUI.Core` projekt tesztelési minőségének mérésére. | ||
|
|
||
| **A mutációs tesztelés folyamata:** | ||
| A Stryker apró változtatásokat ("mutációkat") végez a forráskódon, majd lefuttatja | ||
| a teszteket. Ha egy mutáció nem buktatja el a teszteket, az azt jelenti, hogy | ||
| a tesztek nem fedik le megfelelően azt a logikát — ez egy túlélő mutáns. | ||
|
|
||
| **A tesztelés eredményei:** | ||
|
|
||
| - **Első futtatás: 74.00%** | ||
| - **`SelectByDate` eltávolítása után: 80.43%** | ||
| A `SelectByDate` egy olyan teszt volt, amely a TDD fejlesztés során megírásra került, | ||
| viszont később ez a funkció mégsem került implementálásra a fejlesztő döntése miatt. | ||
| Így ennek a tesztnek az eltávolítása rögtön növelte a mutáció score-t. | ||
| - **`GameStateManager` tesztek után: 89.13%** | ||
| A hibák abból eredtek, hogy nem volt lekezelve az, ha az egyes függvéynek | ||
| bemeneti paraméterül null-t kapnak. | ||
| - **`WordSelector` tesztek után: 93.48%** | ||
| A `wordList` konstruktorában null argumentum kezelése. | ||
| - **`WordValidator` + `GuessEvaluator` tesztek után: 100.00%** | ||
| `WordValidator` - null kezelése. `GuessEvaluator` - Ha egy betűt már megjelöltünk | ||
| Correct-ként, akkor az ő helye `processed[i] = true` jelölést kap. A mutáns ezt false-ra | ||
| állította, ekkor a betű a következő iterációban újra kiértékelésre került Misplaced | ||
| vagy Absent-ként, ami hibás, ezt kellett lekezelni. | ||
|
|
||
| **A Stryker konfigurálásának nehézségei:** | ||
| A Stryker beüzemelése számos kihívással járt, amelyek mind a `.csproj` konfiguráció | ||
| sajátosságaiból eredtek: | ||
| - A `stryker-config.json` helyes formátumát Copilot rosszul generálta | ||
| - A `console` reporter neve Stryker 4.14.0-ban `cleartext` — ezt is tévesen adta meg | ||
| - A `mutate` path filter nem működött relatív útvonalakkal, csak `**/*.cs` mintával | ||
| - A `LinqMutator` érvénytelen kódot generált `List<string>.Count` mutációjakor, | ||
| amit az `ignore-mutations: ["linq"]` beállítással kellett kizárni | ||
|
|
||
| **A Stryker + Copilot workflow:** | ||
| A leghasznosabb megközelítésnek az bizonyult, amikor a Stryker riportból azonosított túlélő | ||
| mutánsokat Copilottal öltük meg. A workflow: | ||
|
|
||
| ``` | ||
| 1. Stryker futtatása → HTML riport generálása | ||
| 2. Túlélő mutáns azonosítása a riportban (fájl + sor + mutáció típusa) | ||
| 3. Copilot Chat: pontos prompt a mutáns megöléséhez szükséges teszttel | ||
| 4. Teszt hozzáadása → Stryker újrafuttatása → score javulás ellenőrzése | ||
| ``` | ||
|
|
||
| **Tanulság:** A mutációs tesztelés hasznos eszköz a tesztek minőségének mérésére, | ||
| de a konfigurálása összetett és eszközismeretet igényel. A Copilot segíthet | ||
| a tesztek generálásában, de a mutáns azonosítása és a prompt pontos | ||
| megfogalmazása emberi feladat marad. | ||
|
|
||
| **Megjegyzés:** | ||
| A 100%-os mutáció score azt jelenti, hogy minden meglevő kódsor tesztelve | ||
| van — de nem jelenti azt, hogy a szoftver helyes. A Stryker csak a meglévő | ||
| kódot tudja mutálni, hiányzó funkciókat vagy hibás üzleti logikát nem képes | ||
| detektálni. Jó példa erre a duplikált betűk kezelése: ha a `GuessEvaluator` | ||
| eleve rossz algoritmust tartalmazott volna, a Stryker azt nem találta volna | ||
| meg — csak a kézzel megírt, üzleti logikán alapuló tesztek tudták garantálni | ||
| a helyes viselkedést. | ||
|
|
||
| --- | ||
|
|
||
| ## Összefoglalás | ||
|
|
||
| A TDD és az MI eszközök kombinációja hatékony fejlesztési módszernek bizonyult, | ||
| de fontos tanulság, hogy az MI nem helyettesíti a fejlesztői tudást — inkább | ||
| egy erős asszisztens, amely felgyorsítja a munkát, de folyamatos emberi | ||
| felügyeletet igényel. | ||
|
|
||
| A legjobb eredményt akkor értük el, amikor: | ||
| 1. A fejlesztő írta meg a tesztek leírását | ||
| (NEM az MI dönti el, hogy milyen tesztesetekre lesz szükségünk) | ||
| 2. A teszteket vagy MI generálta és alaposan ellenőrizte őket a fejlesztő, | ||
| vagy maga a fejlesztő írta | ||
| 3. A Copilot legenerálta az implementációt a tesztek alapján | ||
| 4. A fejlesztő itt is kritikusan értékelte és szükség esetén javította a javaslatot | ||
| 5. Claude segített az összetettebb promptok megírásában és a nehezebb hibák azonosításában | ||
|
|
||
| **Szerző:** Várhegyi Melinda | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ide érdemes lenne egyetlen mondatban leírni, hogy mi a Wordle, hátha valaki nem tudja pontosan.