Übung: Überprüfen und Testen einer C#-Konsolenanwendung mithilfe von Beispieldaten

Abgeschlossen

In dieser Übung überprüfen und testen Sie den Code im Starter-Projekt, isolieren und beheben ein Logikproblem und überprüfen dann, ob Ihre aktualisierte Anwendung wie erwartet funktioniert.

In dieser Übung führen Sie die folgenden Aufgaben aus:

  1. Codeüberprüfung: Überprüfen Sie den Inhalt der Datei „Program.cs“.

    „Program.cs“ enthält die folgenden Codeabschnitte:

    • Anweisungen der obersten Ebene: Die Anweisungen der obersten Ebene simulieren eine Reihe von Transaktionen mithilfe eines Arrays von testData oder einer größeren Anzahl zufällig generierter Transaktionen.
    • LoadTillEachMorning: Die LoadTillEachMorning-Methode wird verwendet, um die Lade der Registrierkasse mit einer vordefinierten Anzahl von Geldscheinen mit jedem Nennwert zu konfigurieren.
    • MakeChange: Die MakeChange-Methode wird verwendet, um die Kasse während Kauftransaktionen zu verwalten.
    • LogTillStatus: Die LogTillStatus-Methode wird verwendet, um die Anzahl von Geldscheinen der einzelnen Nennwerte anzuzeigen, die sich derzeit in der Kasse befinden.
    • TillAmountSummary: Die TillAmountSummary-Methode wird verwendet, um eine Meldung anzuzeigen, die Geldmenge in der Kasse angibt.
  2. Anfängliche Tests: Stellen Sie sicher, dass MakeChange den Kassenbestand erfolgreich ausgleicht, wenn das testData-Array zum Simulieren von Transaktionen verwendet wird.

  3. Codedebuggen: Isolieren und beheben Sie ein Logikproblem, das bei der Verwendung zufällig generierter Daten auftritt.

  4. Überprüfungstest: Führen Sie einen Überprüfungstest für den Code aus, den Sie in dieser Übung entwickeln.

Überprüfen des Inhalts der Datei „Program.cs“

Diese Aufgabe bietet eine exemplarische Vorgehensweise für den Starter-Projektcode. Die Datei „Program.cs“ enthält eine Anwendung, die die Bedingungen für tägliche Transaktionen simuliert. Die Anwendung ruft die MakeChange-Methode auf, um den Kassenbestand während jeder Transaktion zu verwalten. Andere Methoden werden verwendet, um die Kasse zu initialisieren und Berichtsmeldungen zu generieren.

  1. Stellen Sie sicher, dass der Ordner GuidedProject in Visual Studio Code geöffnet ist.

  2. Erweitern Sie in der EXPLORER-Ansicht die Ordner GuidedProject und Starter.

    Der Ordner Starter enthält die Beispielanwendung für dieses GuidedProject-Modul.

  3. Öffnen Sie die Datei „Program.cs“ im Visual Studio Code-Editor.

  4. Wählen Sie im Menü „Ansicht“ die Option Befehlspalette aus.

  5. Geben Sie an der Eingabeaufforderung .net: g ein, und wählen Sie dann .NET: Ressourcen für Build und Debug generieren aus.

  6. Klicken Sie an der Eingabeaufforderung Zu startendes Projekt auswählen das Starter-Projekt aus.

    Die erstellte Datei „launch.json“ enthält eine Konfiguration für das Starter-Projekt.

  7. Nehmen Sie sich einige Minuten Zeit, um die Anweisungen der obersten Ebene für diese Anwendung zu überprüfen:

    /*
    This application manages transactions at a store check-out line. The
    check-out line has a cash register, and the register has a cash till
    that is prepared with a number of bills each morning. The till includes
    bills of four denominations: $1, $5, $10, and $20. The till is used
    to provide the customer with change during the transaction. The item 
    cost is a randomly generated number between 2 and 49. The customer 
    offers payment based on an algorithm that determines a number of bills
    in each denomination. 
    
    Each day, the cash till is loaded at the start of the day. As transactions
    occur, the cash till is managed in a method named MakeChange (customer 
    payments go in and the change returned to the customer comes out). A 
    separate "safety check" calculation that's used to verify the amount of
    money in the till is performed in the "main program". This safety check
    is used to ensure that logic in the MakeChange method is working as 
    expected.
    */
    
    string? readResult = null;
    bool useTestData = true;
    
    Console.Clear();
    
    int[] cashTill = new int[] { 0, 0, 0, 0 };
    int registerCheckTillTotal = 0;
    
    // registerDailyStartingCash: $1 x 50, $5 x 20, $10 x 10, $20 x 5 => ($350 total)
    int[,] registerDailyStartingCash = new int[,] { { 1, 50 }, { 5, 20 }, { 10, 10 }, { 20, 5 } };
    
    int[] testData = new int[] { 6, 10, 17, 20, 31, 36, 40, 41 };
    int testCounter = 0;
    
    LoadTillEachMorning(registerDailyStartingCash, cashTill);
    
    registerCheckTillTotal = registerDailyStartingCash[0, 0] * registerDailyStartingCash[0, 1] + registerDailyStartingCash[1, 0] * registerDailyStartingCash[1, 1] + registerDailyStartingCash[2, 0] * registerDailyStartingCash[2, 1] + registerDailyStartingCash[3, 0] * registerDailyStartingCash[3, 1];
    
    // display the number of bills of each denomination currently in the till
    LogTillStatus(cashTill);
    
    // display a message showing the amount of cash in the till
    Console.WriteLine(TillAmountSummary(cashTill));
    
    // display the expected registerDailyStartingCash total
    Console.WriteLine($"Expected till value: {registerCheckTillTotal}\n\r");
    
    var valueGenerator = new Random((int)DateTime.Now.Ticks);
    
    int transactions = 10;
    
    if (useTestData)
    {
        transactions = testData.Length;
    }
    
    while (transactions > 0)
    {
        transactions -= 1;
        int itemCost = valueGenerator.Next(2, 20);
    
        if (useTestData)
        {
            itemCost = testData[testCounter];
            testCounter += 1;
        }
    
        int paymentOnes = itemCost % 2;                 // value is 1 when itemCost is odd, value is 0 when itemCost is even
        int paymentFives = (itemCost % 10 > 7) ? 1 : 0; // value is 1 when itemCost ends with 8 or 9, otherwise value is 0
        int paymentTens = (itemCost % 20 > 13) ? 1 : 0; // value is 1 when 13 < itemCost < 20 OR 33 < itemCost < 40, otherwise value is 0
        int paymentTwenties = (itemCost < 20) ? 1 : 2;  // value is 1 when itemCost < 20, otherwise value is 2
    
        // display messages describing the current transaction
        Console.WriteLine($"Customer is making a ${itemCost} purchase");
        Console.WriteLine($"\t Using {paymentTwenties} twenty dollar bills");
        Console.WriteLine($"\t Using {paymentTens} ten dollar bills");
        Console.WriteLine($"\t Using {paymentFives} five dollar bills");
        Console.WriteLine($"\t Using {paymentOnes} one dollar bills");
    
        // MakeChange manages the transaction and updates the till 
        string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes);
    
        // Backup Calculation - each transaction adds current "itemCost" to the till
        if (transactionMessage == "transaction succeeded")
        {
            Console.WriteLine($"Transaction successfully completed.");
            registerCheckTillTotal += itemCost;
        }
        else
        {
            Console.WriteLine($"Transaction unsuccessful: {transactionMessage}");
        }
    
        Console.WriteLine(TillAmountSummary(cashTill));
        Console.WriteLine($"Expected till value: {registerCheckTillTotal}\n\r");
        Console.WriteLine();
    }
    
    Console.WriteLine("Press the Enter key to exit");
    do
    {
        readResult = Console.ReadLine();
    
    } while (readResult == null);
    

    Der Code für Anweisungen der obersten Ebene erledigt die folgenden Tasks:

    • Konfigurieren der Anwendungsdaten und Umgebungsvariablen, die zum Testen der MakeChange-Methode verwendet werden
    • Aufrufen der Methoden LoadTillEachMorning(), LogTillStatus() und TillAmountSummary(), um den Kassenbestand vorzubereiten und Statusmeldungen an die Konsole auszugeben
    • Verwenden der while-Schleife zum Simulieren einer Reihe von Transaktionen
    • Aufrufen der MakeChange-Methode innerhalb des Codeblocks der while-Schleife
    • Melden des Status des Kassenbestands nach jeder Transaktion

    Hinweis

    Die Anweisungen der obersten Ebene enthalten eine Console.ReadLine()-Anweisung. Die launch.json-Datei muss vor dem Debuggen aktualisiert werden.

  8. Nehmen Sie sich einen Moment Zeit, um die LoadTillEachMorning()-Methode zu überprüfen.

    static void LoadTillEachMorning(int[,] registerDailyStartingCash, int[] cashTill)
    {
        cashTill[0] = registerDailyStartingCash[0, 1];
        cashTill[1] = registerDailyStartingCash[1, 1];
        cashTill[2] = registerDailyStartingCash[2, 1];
        cashTill[3] = registerDailyStartingCash[3, 1];
    }
    
  9. Nehmen Sie sich einige Minuten Zeit, um die MakeChange()-Methode zu überprüfen.

    static string MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0)
    {
        string transactionMessage = "";
    
        cashTill[3] += twenties;
        cashTill[2] += tens;
        cashTill[1] += fives;
        cashTill[0] += ones;
    
        int amountPaid = twenties * 20 + tens * 10 + fives * 5 + ones;
        int changeNeeded = amountPaid - cost;
    
        if (changeNeeded < 0)
            transactionMessage = "Not enough money provided.";
    
        Console.WriteLine("Cashier Returns:");
    
        while ((changeNeeded > 19) && (cashTill[3] > 0))
        {
            cashTill[3]--;
            changeNeeded -= 20;
            Console.WriteLine("\t A twenty");
        }
    
        while ((changeNeeded > 9) && (cashTill[2] > 0))
        {
            cashTill[2]--;
            changeNeeded -= 10;
            Console.WriteLine("\t A ten");
        }
    
        while ((changeNeeded > 4) && (cashTill[1] > 0))
        {
            cashTill[2]--;
            changeNeeded -= 5;
            Console.WriteLine("\t A five");
        }
    
        while ((changeNeeded > 0) && (cashTill[0] > 0))
        {
            cashTill[0]--;
            changeNeeded--;
            Console.WriteLine("\t A one");
        }
    
        if (changeNeeded > 0)
            transactionMessage = "Can't make change. Do you have anything smaller?";
    
        if (transactionMessage == "")
            transactionMessage = "transaction succeeded";
    
        return transactionMessage;
    }
    

    Die MakeChange-Methode verwaltet den Kassenbestand während jeder Kauftransaktion. Der Transaktionsprozess basiert auf den folgenden Ressourcen und Bedingungen:

    • Bartransaktion: Die MakeChange-Methode akzeptiert eine Barzahlung vom Kunden und bestimmt dann, wie viele Scheine eines jeden Nennwerts an den Kunden zurückgegeben werden müssen. MakeChange muss zunächst sicherstellen, dass der Kunde genügend Geld bereitgestellt hat, um die Transaktion abzudecken. Wenn die Zahlung ausreicht, beginnt der MakeChange-Prozess mit dem größten bis hin zum kleinsten Nennwert. In jeder Phase stellt MakeChange sicher, dass der aktuelle Nennwert kleiner ist als der geschuldete Betrag. MakeChange stellt außerdem sicher, dass ein Schein des erforderlichen Nennwerts in der Kasse verfügbar ist, bevor er dem Wechselgeld für den Kunden hinzugefügt wird.

    • Eingabeparameter: Die MakeChange-Methode verwendet die folgenden Eingabeparameter:

      • Integer, der die Kosten des gekauften Artikels darstellt: itemCost
      • Ganzzahliges Array, das die Anzahl der Scheine in der Kasse für jeden Nennwert enthält: cashTill
      • Vom Kunden angebotene Zahlung, wobei die Anzahl der Scheine für jeden Nennwert separat angegeben wird: paymentTwenties, paymentTens, paymentFives, paymentOnes
    • Geldmenge in der Kasse: Die vom Kunden als Zahlung angebotenen Scheine müssen den Scheinen des jeweiligen Nennwerts entsprechen, die als Wechselgeld zur Verfügung stehen.

    • Dem Kunden geschuldetes Wechselgeld: Das Wechselgeld für den Kunden wird anhand des vom Kunden gezahlten Betrags abzüglich der Kosten für den Artikel berechnet.

    • Nicht ausreichende Zahlung: Wenn die Zahlung des Kunden nicht ausreicht, gibt MakeChange eine beschreibende Nachricht zurück, und die Transaktion wird abgebrochen.

    • Nicht genügend Wechselgeld: Wenn das Wechselgeld nicht genau zurückgegeben werden kann, gibt MakeChange eine beschreibende Meldung zurück, und die Transaktion wird abgebrochen.

  10. Nehmen Sie sich einen Moment Zeit, um die LogTillStatus()-Methode zu überprüfen.

    static void LogTillStatus(int[] cashTill)
    {
        Console.WriteLine("The till currently has:");
        Console.WriteLine($"{cashTill[3] * 20} in twenties");
        Console.WriteLine($"{cashTill[2] * 10} in tens");
        Console.WriteLine($"{cashTill[1] * 5} in fives");
        Console.WriteLine($"{cashTill[0]} in ones");
        Console.WriteLine();
    }
    

    Die LogTillStatus-Methode verwendet das cashTill-Array, um den aktuellen Inhalt der Kasse zu melden.

  11. Nehmen Sie sich einen Moment Zeit, um die TillAmountSummary()-Methode zu überprüfen.

    static string TillAmountSummary(int[] cashTill)
    {
        return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars";
    
    }
    

    Die TillAmountSummary-Methode verwendet das cashTill-Array, um den aktuellen Kassenbestand zu berechnen.

Damit wird die Überprüfung des vorhandenen Codeprojekts abgeschlossen.

Überprüfen Sie, ob MakeChange das Geld bei Verwendung des testData-Arrays erfolgreich verwaltet.

In dieser Aufgabe simulieren Sie Transaktionen mithilfe des testData-Arrays und überprüfen, ob MakeChange das Geld in der Kasse erfolgreich ausbilanziert.

  1. Klicken Sie im Visual Studio Code-Menü Ausführen auf Debuggen starten.

  2. Beachten Sie, dass ein IOException-Fehler auftritt.

    Die Debugging-Konsole unterstützt die Methoden Console.Clear() und Console.ReadLine() nicht. Sie müssen die Datei „launch.json“ vor dem Debuggen aktualisieren.

  3. Klicken Sie auf der Symbolleiste „Debuggen“ auf Beenden.

  4. Verwenden Sie die EXPLORER-Ansicht, um die Datei „launch.json“ zu öffnen.

  5. Aktualisieren Sie in der Datei „launch.json“ das Attribut console wie folgt:

    // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
    "console":"integratedTerminal",
    

    Der Standardwert für das console-Attribut lautet internalConsole und ist damit auf das Panel „Debugging-Konsole“ ausgerichtet. Leider unterstützt das Panel „Debugging-Konsole“ einige Konsolenmethoden nicht. Die integratedTerminal-Einstellung entspricht dem Panel „Terminal“, das Konsoleneingaben und -ausgaben unterstützt.

  6. Speichern Sie Ihre Änderungen an der launch.json-Datei.

  7. Klicken Sie im Visual Studio Code-Menü Ausführen auf Debuggen starten.

  8. Überprüfen Sie die von der Anwendung generierte Ausgabe im Panel „Terminal“.

    Wechseln Sie vom Panel „Debugging-Konsole“ zum Panel „Terminal“, um die Ausgabe zu überprüfen.

  9. Beachten Sie, dass MakeChange die Kasse erfolgreich ausbilanziert, wenn das testData-Array zum Simulieren von Transaktionen verwendet wird.

    Unten in der gemeldeten Ausgabe sollten die folgenden Zeilen angezeigt werden:

    The till has 551 dollars
    Expected till value: 551
    
    
    Press the Enter key to exit
    

    Beachten Sie, dass der gemeldete und erwartete Kassenwert jeweils 551 entspricht.

  10. Um die Anwendung zu beenden, drücken Sie die EINGABETASTE.

Identifizieren und Beheben von Logikproblemen

In dieser Aufgabe verwenden Sie simulierte Transaktionen, um ein Codelogikproblem zu ermitteln. Anschließend verwenden Sie die Visual Studio Code-Debuggingtools, um das Problem zu isolieren und zu beheben.

  1. Um den Code mit zufällig generierten Transaktionen auszuführen, ändern Sie den useTestData zugewiesenen Wert in false.

    Sie finden die useTestData-Variable am Anfang der Anweisungen der obersten Ebene.

  2. Speichern Sie die Program.cs-Datei, und führen Sie dann die Anwendung im Debugger aus.

  3. Überprüfen Sie die Ausgabe im Panel „Terminal“.

  4. Beachten Sie die Differenz in der Kasse.

    Der von MakeChange berechnete Endsaldo und der Saldo, der in den Anweisungen der obersten Ebene beibehalten wird, werden unten in der Ausgabe gemeldet. Beispiel:

    Transaction successfully completed.
    The till has 379 dollars
    Expected till value: 434
    
    
    Press the Enter key to exit
    

    Hinweis

    Die Anwendung generiert die Kosten für Artikel nach dem Zufallsprinzip. Daher unterscheiden sich die in Ihrer Ausgabe gemeldeten Kassenwerte.

  5. Drücken Sie die EINGABETASTE, um die Anwendung zu beenden.

  6. Schließen Sie das Panel „Terminal“.

Debuggen des Codes

In dieser Aufgabe verwenden Sie die Visual Studio Code-Debuggingtools, um das Logikproblem zu isolieren und dann zu beheben.

  1. Suchen Sie am Ende der Anweisungen der obersten Ebene die folgende Codezeile:

    Console.WriteLine();
    
  2. Legen Sie einen Breakpoint für die ausgewählte Codezeile fest.

  3. Klicken Sie im Visual Studio Code-Menü Ausführen auf Debuggen starten.

  4. Beachten Sie, dass die Codeausführung am Breakpoint angehalten wird.

  5. Klicken Sie auf der Symbolleiste Debugsteuerelemente auf Einzelschritt.

  6. Überprüfen Sie die Ausgabe im Panel „Terminal“.

  7. Wenn der gemeldete und der erwartete Kassenwert gleich ist, klicken Sie auf der Symbolleiste Debugsteuerelemente auf Fortsetzen.

  8. Wiederholen Sie den vorherigen Schritt, bis eine Differenz zwischen dem gemeldeten und dem erwarteten Kassenwert angezeigt wird.

  9. Sobald eine Differenz angezeigt wird, nehmen Sie sich kurz Zeit, um die Details der Transaktion zu überprüfen.

  10. Beachten Sie, dass der empfangene Geldbetrag und das zurückgegebene Wechselgeld korrekt sind, in der Kasse jedoch fünf Dollar fehlen.

    Das fehlende Geld deutet darauf hin, dass das cashTill-Array falsch aktualisiert wird, obwohl die Berichterstellung korrekt ist.

  11. Beenden Sie die Debugsitzung, und schließen Sie das Panel „Terminal“.

  12. Scrollen Sie zum Ende der MakeChange-Methode.

    Die while-Anweisungen, die zum Vornehmen von Änderungen verwendet werden, befinden sich am Ende der MakeChange-Methode.

  13. Überprüfen Sie die Codeblöcke der while-Anweisung, die zum Ändern verwendet werden.

    Da in der Kasse fünf Dollar fehlen, liegt das Problem wahrscheinlich im while-Codeblock vor, der verwendet wird, um Fünf-Dollar-Scheine zurückzugeben.

  14. Beachten Sie den folgenden Code:

    while ((changeNeeded > 4) && (cashTill[1] > 0))
    {
        cashTill[2]--;
        changeNeeded -= 5;
        Console.WriteLine("\t A five");
    }    
    

    Das cashTill[]-Array wird verwendet, um die Anzahl der Scheine der einzelnen Nennwerte zu speichern, die derzeit verfügbar sind. Mit dem Arrayelement 1 wird die Anzahl der Fünf-Dollar-Scheine in der Kasse verwaltet. Der Ausdruck in der while-Anweisung bezieht sich ordnungsgemäß auf cashTill[1]. Die Anweisung innerhalb des Codeblocks dekrementiert jedoch cashTill[2] anstelle von cashTill[1]. Die Angabe des Indexwerts 2 bedeutet, dass ein Zehn-Dollar-Schein und kein Fünf-Dollar-Schein aus der Kasse entfernt wird.

  15. Aktualisieren Sie den while-Codeblock wie folgt:

    while ((changeNeeded > 4) && (cashTill[1] > 0))
    {
        cashTill[1]--;
        changeNeeded -= 5;
        Console.WriteLine("\t A five");
    }    
    
  16. Speichern Sie die Datei "Program.cs".

Arbeit überprüfen

In dieser Aufgabe führen Sie Ihre Anwendung aus und überprüfen, ob der aktualisierte Code wie vorgesehen funktioniert.

  1. Klicken Sie im Visual Studio Code-Menü Ausführen auf Alle Haltepunkte entfernen.

  2. Klicken Sie im Menü Ausführen auf Debuggen starten.

  3. Überprüfen Sie die Ausgabe im Panel „Terminal“.

  4. Vergewissern Sie sich, dass der gemeldete Kassenwert dem erwarteten Kassenwert entspricht:

    Der von MakeChange berechnete Endsaldo und der Saldo, der in den Anweisungen der obersten Ebene beibehalten wird, werden unten in der Ausgabe gemeldet. Beispiel:

    Transaction successfully completed.
    The till has 452 dollars
    Expected till value: 452
    
    
    Press the Enter key to exit
    

    Die Anwendung generiert die Kosten für Artikel nach dem Zufallsprinzip. Daher unterscheiden sich die in Ihrer Ausgabe gemeldeten Kassenwerte. Solange die beiden Werte identisch sind, haben Sie das Logikproblem erfolgreich behoben.