Don’t Forget The Edge Cases ! (original) (raw)

Last Updated : 20 Sep, 2023

_An Intro to Test Drive Development (TDD)

Imagine a scenario where you want to write the following function as a part of some larger project :

**Write a function to return the type of a triangle based on the value of the length of 3 sides of a triangle. Let's make it a bit easier by assuming that the test for input data type is already in place, so you receive only numeric values to work with.

The situation looks easy. You go ahead and write the function, which looks something like this -

**Algorithm :

**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

After you complete the function, you are given a couple of assertions to perform. And to your surprise, you find that only 50% of the cases passed.

Let's look at the test statements. The ones that pass are :
1. Assert if (String_toLowerCase(triangle_type(6,7,8))==”scalar triangle”) = Correct
2. Assert if (String_toLowerCase(triangle_type(6,6,6))==”equilateral triangle”) = Correct
3. assert(String_toLowerCase(triangle_type(6,7,6))==”isosceles triangle”) = Correct
Well, things look good up till here. But the ones that fail are :
4. Assert if (String_toLowerCase(triangle_type(0,0,0))==”not a triangle”) = Incorrect
5. Assert if (String_toLowerCase(triangle_type(-6,-7,-8))==”not a triangle”) = Incorrect
6. Assert if (String_toLowerCase(triangle_type(5,2,8))==”not a triangle”) = Incorrect

Here we see for :

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

Output :

True
True
False

It fails the test of triangularity. Hence lengths (2,5,8) do not form a triangle.

So what we need is a kind of triangle validation in place, which tells us if what we have is even a triangle or not. As part of the solution you write another function that looks like :

**Algorithm :

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
  2. Return False
    Stop

Our previous function now includes 2 extra lines at the beginning and wola! all are tests are passing now.

This is just a simple an example scenario to remind us that when we writing production level code, we have to be careful with even simple things. By keeping the simple edge cases in mind, and checking with uniform string cases, we increased our test coverage and made our program return more mathematically correct results.

Below is the implementation of above approach :

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(6,7,8)) print(triangleType(6,6,6)) print(triangleType(6,7,6)) print(triangleType(0,0,0)) print(triangleType(-6,-7,-8)) print(triangleType(5,2,8))

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");

`

The above program when tested on the assertions discussed before will now pass the test cases.

In the industry coming up with corner cases and then developing functions to make sure those test cases pass is termed as "test driven development". This blog is just a glimpse of what TDD means in practise.