Skip to content

DA5. The Classic Triangle Testing Problem, (Myer’s Triangle)

statement

  • A program reads three integer values. The three values are interpreted as representing the lengths of the sides of a triangle.
  • The program prints a message that states whether the triangle is scalene, isosceles, or equilateral.
  • Develop a set of test cases (at least 6 ) that you feel will adequately test this program.

solution

  • nothing explains programming problems than code, so I decided to submit my assignment as code.
  • all the code below is written in typescript (a super set of javascript)
  • the language of choice has considerable implications on TDD. for example in javascript, there is no difference between float and integer types, they both considered as number.
  • first lets, define our function:
    • according to Triangle Inequality Theorem: that the sum of two sides of a triangle must be greater than the third side, this theorem is implemented in isTriangle function below.
    • after that, we need to choose the longest side (hypotenuse, if exists) of the triangle (findHypotenuse function).
    • if we don’t have a hypotenuse, then all sides are equal and it is an equilateral triangle.
    • if we have a hypotenuse, we proceed to check the other 2 sides of the triangle. (findOther2Sides function).
    • if the 2 sides of the triangle are equal then it is an IsoSceles triangle, otherwise it is a Scalene triangle.
function isTriangle(a: number, b: number, c: number) {
    // Triangle Inequality Theorem
    return a + b > c && a + c > b && b + c > a;
}

function isThreeNumbersEqual(a: number, b: number, c: number) {
    return a === b && b === c && a === c;
}

function isTwoOfThreeNumbersEqual(a: number, b: number, c: number) {
    return a === b || a === c || b === c;
}

function findHypotenuse(a: number, b: number, c: number) {
    if (isThreeNumbersEqual(a, b, c)) return undefined;
    if (a > b && a > c) return "a";
    if (b > a && b > c) return "b";
    if (c > a && c > b) return "c";
    return undefined;
}

function findOther2Sides(hypotenuse: string, a: number, b: number, c: number) {
    if (hypotenuse === "a") return [b, c];
    if (hypotenuse === "b") return [a, c];
    if (hypotenuse === "c") return [a, b];
    return [];
}

function myreTriangle(a: number, b: number, c: number) {
    if (!isTriangle(a, b, c)) return "Not a triangle";
    const hypotenuse = findHypotenuse(a, b, c);
    if (!hypotenuse && isThreeNumbersEqual(a, b, c)) return "Equilateral";
    if (hypotenuse) {
        const [side1, side2] = findOther2Sides(hypotenuse, a, b, c);
        if (side1 === side2) return "Isosceles";
        if (side1 !== side2) return "Scalene";
    }
    if (isTwoOfThreeNumbersEqual(a, b, c)) return "Isosceles";
    return "Unknown triangle type";
}

myreTriangle(1, 2, 2);
  • now we think we did a great job with the above implantation, lets proceed with unit tests.
  • test case 1:
    • input: 1,2,2.
    • expected output: ‘Isosceles’
    • actual output: ‘Isosceles’
    • result: PASS
  • test case 2:
    • input: 7,2,2
    • expected output: ‘Not a triangle’
    • actual output: ‘Not a triangle’
    • result: PASS
  • test case 3:
    • input: 1,2,0
    • expected output: ‘Not a triangle’
    • actual output: ‘Not a triangle’
    • result: PASS.
  • test case 4:
    • input: 1,2,‘2’
    • expected output: ‘Isosceles’
    • actual output: ‘Unknown triangle type’
    • Result: FAIL, maybe the string should be converted to a number.
  • test case 5:
    • input: ‘2’, ‘2’, ‘2’
    • expected output: according to the previous case, we do not convert strings, so we expect this to be ‘Unknown triangle type’ or ‘Not a triangle’
    • actual output: ‘Equilateral’
    • result: FAIL. function output should be consistent, if it does not convert strings to numbers, it should fails whenever a string is passed as an argument. but we found a different result here.
  • test case 6:
    • input: 3,3,3
    • expected output: ‘Equilateral’
    • actual output: ‘Equilateral’
    • result: PASS.
  • test case 7:
    • input 0,0,0
    • expected output: error, eg. ‘Unknown triangle type’ or ‘Not a triangle’
    • actual output: ‘Not a triangle’
    • result: PASS.

conclusion

  • we thought that we did a great job in the first place.
  • with test we find out some issues.
  • if this was submitted without unit tests, it will generate a runtime hard-to-find bugs, but using TTD, it is easier to detect those kind of bugs at an early stages of the product.

References