Använd vänsterpil och högerpil för att navigera
Eller Ctrl+P för att skriva ut till PDF (eller på papper)
Föreläsning 28
Felsökning
Hur vi bör skriva program
I teorin
Skriv programmet korrekt
Testa att det är korrekt
Lansera
I praktiken
Verkligheten
Felsökning
Vi vet att programmet är fel; hur åtgärdar vi det?
Modell: medicin
Symtom
Orsak
Behandling
Alternativt:
När inträffar felet?
Varför inträffar felet?
Hur åtgärdar vi felet?
Symtom
Användare: "Feature X fungerar inte"
Anledning till felrapport
Betyder inte att vi vet orsak eller rätt behandling
Strategi:
Be om detaljer
Återskapa
Testa liknande scenarion
Leta efter mönster
Vår kod
Product[] cart = {...};
string discountCode = ...;
double total = 0;
foreach (Product p in cart) {
total += p.Price;
}
double shipping = 0;
if (total >= 300) {
shipping = 30;
}
if (total <= 300) {
shipping = 70;
}
total += shipping;
if (discountCode == "ABC123") {
total = total - 50;
}
Console.WriteLine(total);
Felrapport
"Jag får betala för mycket frakt!"
Fler detaljer:
Produkter:
Radio för 200 kr
Lampa för 100 kr
Rabattkod "ABC123"
Symtom
Fel inträffar när summan före frakt och rabattkod är 300 kr
Summan blir 320 kr
Summan borde bli 280 kr
300 kr för produkter
30 kr för frakt
50 kr rabatt
300 + 30 - 50 = 280 kr
Alla andra scenarion verkar vara korrekta
Orsak
Vilken kodrad orsakar felet?
Ibland flera, men ofta en enda
Fel kan "vidarebefordras" och synas först mycket senare
"Backtracka" från symtomet till tidigast ogiltiga tillståndet
Felet borde ligga på raden direkt efter det sista giltiga tillståndet
Tyvärr finns inte kommandot "Step Back"
Sista giltiga tillståndet
Felet uppenbarar sig på sista raden
Tillståndet före andra if-satsen är giltigt
Tillståndet efter andra if-satsen är ogiltigt
Hypotes: andra if-satsen är felaktigt skriven
Behandling
Ändra koden så att den blir korrekt
Ibland det enklaste, ibland det svåraste
Ibland avslöjas grundläggande fel i designen
Processen är samma som att lösa ett problem från början
Dock vet vi nu vad som
inte
fungerar
Behandla orsaken, inte symtomet
Snabba eller ytliga fixar kan fungera
... men de kan ofta orsaka andra fel, nu eller senare
Behandla symtomet
if (total == 370) {
total = 330;
}
Problem med att behandla symtomet
Vad händer när produkterna kostar 340 kr?
Vi förväntar oss 340 + 30 - 50 = 320 kr
Vi får 330 - 50 = 280 kr
Behandla orsaken
<
istället för
<=
else if
istället för
if
else
istället för
if
...
Ytterligare exempel
class MyForm : Form {
TextBox textBox;
Button button;
public MyForm() {
var table = new TableLayoutPanel {
RowCount = 1,
ColumnCount = 2,
Dock = DockStyle.Fill
};
Controls.Add(table);
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 70));
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 30));
textBox = new TextBox {
Dock = DockStyle.Top
};
table.Controls.Add(textBox);
button = new Button {
Text = "Reverse!",
Dock = DockStyle.Top
};
table.Controls.Add(button);
button.Click += ClickedEventHandler;
}
private void ClickedEventHandler(object sender, EventArgs e) {
string userString = textBox.Text;
string reverseString = "";
for (int i = userString.Length - 1; i >= 0; i -= 1) {
reverseString += userString[i];
}
button.Click += ClickedEventHandler;
MessageBox.Show(reverseString);
}
}
Specifika tekniker
Debugger, debugger, debugger
Minimala exempel
Förenkla programmet eller indatan till minsta möjliga
Fortsätt tills felet uppstår
Mycket lägre "kognitiv börda" för att hitta orsaken
"Binärdebugging"
Dela programmet på mitten tills det fungerar
Felet finns troligtvis i halvan som togs bort
Inte alltid möjligt eller givande
Fler specifika tekniker
Skriv tester
Uttrycker programmet och problemet på en annan nivå
Blir ett säkerhetsnät för framtiden
Skriv koden från början
Upptäck obefogade antaganden eller svårupptäckta misstag
Om nya koden fungerar utan att du vet varför: bättre än inget!
Be en annan utvecklare att titta på koden
Eller ett föremål: "rubber duck debugging"