logo

Glöm inte The Edge Cases!

En introduktion till Test Drive Development (TDD)

Föreställ dig ett scenario där du vill skriva följande funktion som en del av något större projekt:

I rita en funktion för att returnera typen av en triangel baserat på värdet av längden på tre sidor av en triangel. Låt oss göra det lite enklare genom att anta att testet för indatatyp redan är på plats så att du bara får numeriska värden att arbeta med.



Situationen ser lätt ut. Du går vidare och skriver funktionen som ser ut ungefär så här -

Algoritm:   

    Input :    3 numeric values  
Output : 1 string stating type of triangle
Function : triangleType (side1 side2 side3)
Start :
1. If side1 == side2 == side3
Then Return Equilateral Triangle
2. Else if side1 == side2 or side1 == side3 or side2 == side3
Then Return Isosceles Triangle
3. Else
Return Scalar Triangle
Stop

När du har slutfört funktionen får du ett par påståenden att utföra. Och till din förvåning upptäcker du att endast 50 % av fallen gick igenom. 

Låt oss titta på testpåståendena. De som passerar är:
1. Bekräfta om (String_toLowerCase(triangle_type(678))==skalär triangel) = Rätt 
2. Bekräfta om (String_toLowerCase(triangle_type(666))==liksidig triangel) = Rätt 
3. hävda(String_toLowerCase(triangle_type(676))==likbent triangel) = Rätt 
Det ser bra ut hittills. Men de som misslyckas är:
4. Bekräfta om (String_toLowerCase(triangle_type(000))==inte en triangel) = Felaktigt 
5. Bekräfta om (String_toLowerCase(triangle_type(-6-7-8))==inte en triangel) = Felaktigt 
6. Bekräfta om (String_toLowerCase(triangle_type(528))==inte en triangel) = Felaktigt 

  • I den 4:a satsens ingångsvärden är (000). Nu vet vi att (000) bildar en punkt och inte en triangel. Faktum är att om något inmatningsvärde är noll är triangeln inte möjlig. Men i vårt fall kommer det att returnera en liksidig triangel!
  • Även den 5:a uttalande påminner oss om att längden aldrig kan vara ett negativt värde. Du ser en skala som är -30 cm lång. Så om vi har ens ett -ve-värde av längden är triangeln inte möjlig. Men i vårt fall, beroende på värdet, kan det returnera något av de 3 resultaten. Här ger det en skalär.
  • Hur är det nu 6:a påstående. Alla värden är >= 0 och det är säkert en skalär triangel. Eller är det? Kom ihåg regeln att i en triangel är summan av 2 sidor alltid större än eller lika med 3:an.

Här ser vi för:  

8 + 2 > 5  
8 + 5 > 2
5 + 2 > 8

Utgång:  

True  
True
False

Den klarar triangularitetstestet. Längder (258) bildar därför inte en triangel.

Så vad vi behöver är en sorts triangelvalidering på plats som talar om för oss om det vi har ens är en triangel eller inte. Som en del av lösningen skriver du en annan funktion som ser ut så här:

Algoritm:   

oracle sql inte lika
Input : 3 sides of the triangle   
Output : Boolean value: True if 3 sides form a triangle false otherwise
Function : triangleValidator(side1 side2 side3)
Start
1. If (side1 <= 0 or side2 <= 0 or side3 <= 0) and
(side2 + side3 >= side1) and
(side3 + side1 >= side2) and (side1 + side2 >= side3)
then return True
3. Return False
Stop

Vår tidigare funktion innehåller nu 2 extra rader i början och wola! alla tester går nu.

Detta är bara ett enkelt exempelscenario för att påminna oss om att när vi skriver produktionsnivåkod måste vi vara försiktiga med även enkla saker. Genom att ha de enkla kantfodralen i åtanke och kontrollera med enhetliga strängfodral ökade vi vår testtäckning och fick vårt program att ge mer matematiskt korrekta resultat.

Nedan är implementeringen av ovanstående tillvägagångssätt:  

Python3
# Check if given sides form a triangle or not def triangleValidator(side1 side2  side3): if side1 <= 0 or side2 <= 0 or side3 <= 0: return False elif (side1 + side2 >= side3) and (side2 + side3 >= side1) and (side3 + side1 >= side2): return True return False # Return the type of triangle def triangleType(side1 side2 side3): # If not a triangle return 'Not a triangle' if triangleValidator(side1 side2 side3) == False: return 'Not A Triangle' # Else perform type checking if side1 == side2 == side3: return 'Equilateral Triangle' elif (side1 == side2) or (side2 == side3) or (side3 == side1): return 'Isosceles Triangle' return 'Scalar Triangle' def call(): print(triangleType(678)) print(triangleType(666)) print(triangleType(676)) print(triangleType(000)) print(triangleType(-6-7-8)) print(triangleType(528)) if __name__=='__main__': call() 
JavaScript
// Check if given sides form a triangle or not function triangleValidator(side1 side2 side3) {  if (side1 <= 0 || side2 <= 0 || side3 <= 0) {  return false;  } else if (side1 + side2 > side3 && side2 + side3 > side1 && side3 + side1 > side2) {  return true;  }  return false; } // Return the type of triangle function triangleType(side1 side2 side3) {  // If not a triangle return 'Not a triangle'  if (triangleValidator(side1 side2 side3) === false) {  return 'Not A Triangle';  }  // Else perform type checking  if (side1 === side2 && side2 === side3) {  return 'Equilateral Triangle';  } else if (side1 === side2 || side2 === side3 || side3 === side1) {  return 'Isosceles Triangle';  }  return 'Scalar Triangle'; } // Assertions console.assert(triangleType(6 7 8).toLowerCase() === 'scalar triangle'); console.assert(triangleType(6 6 6).toLowerCase() === 'equilateral triangle'); console.assert(triangleType(6 7 6).toLowerCase() === 'isosceles triangle'); console.assert(triangleType(0 0 0).toLowerCase() === 'not a triangle'); console.assert(triangleType(-6 -7 -8).toLowerCase() === 'not a triangle'); console.assert(triangleType(5 3 8).toLowerCase() === 'not a triangle'); 

Ovanstående program kommer nu att klara testfallen när det testas på de påståenden som diskuterats tidigare.

Att i branschen komma med hörnfall och sedan utveckla funktioner för att se till att dessa testfall klarar kallas "testdriven utveckling". Den här bloggen är bara en glimt av vad TDD betyder i praktiken.
 

Skapa frågesport