测试返回三角形类型的函数

时间:2013-11-20 13:19:04

标签: c++ c testing integration-testing

作为筛选面试的一部分,我得到了以下问题:

编写一个函数,该函数接收三角形边长的三个整数输入,并返回四个值中的一个以确定三角形类型(1 =斜角,2 =等腰,3 =等边,4 =误差)。假设另一个开发人员编写了该函数,为该函数生成测试用例。

我的回答是:

#define ERROR 4
#define EQUILATERAL 3
#define ISOSCELES 2
#define SCALENE 1

int detemineTriangle(int x, int y, int z)
{
    if((x<=0) || (y<=0) || (z<=0))
        return ERROR;

    if((x==y) || (x==z) || (y==z))
    {
        if((x==y) && (y==z))
            return EQUILATERAL;
        else
            return ISOSCELES;
    }

    return SCALENE;
}

测试案例:

detemineTriangle (0,0,0);   //error
detemineTriangle (2,2,2);   //equilateral
detemineTriangle (3,3,1);   //isosceles
detemineTriangle (1,3,3);   //isosceles
detemineTriangle (3,1,3);   //isosceles
detemineTriangle (1,2,3);   //scalene
detemineTriangle (-1,2,3);  //error  scalene
detemineTriangle (1,-2,3);  //error  scalene
detemineTriangle (1,2,-3);  //error  scalene
detemineTriangle (-2,-2,-2);   //error equilateral
detemineTriangle (-2,5,-2);   //error isosceles
detemineTriangle (-2,-2,5);   //error isosceles
detemineTriangle (5,-2,-2);   //error isosceles


//looking for overflows/underflows
detemineTriangle (INT_MAX,INT_MAX,INT_MAX);
detemineTriangle (INT_MAX,1,1);
detemineTriangle (1,INT_MAX,1);
detemineTriangle (1,1,INT_MAX);
detemineTriangle (-INT_MAX,-INT_MAX,-INT_MAX);
detemineTriangle (-INT_MAX,1,1);
detemineTriangle (1,-INT_MAX,1);
detemineTriangle (1,1,-INT_MAX);

//boundary tests
detemineTriangle(1,1,1)
detemineTriangle(0,0,0)
detemineTriangle(-1,-1,-1)


detemineTriangle (0,10,10);   
detemineTriangle (1,10,10);   
detemineTriangle (-1,10,10); 

detemineTriangle (10,0,10);   
detemineTriangle (10,1,10);   
detemineTriangle (10,-1,10); 

detemineTriangle (10,10,0);   
detemineTriangle (10,10,1);   
detemineTriangle (10,10,-1);   

//checking thread safety
a =detemineTriangle (10,10,10);  
b =detemineTriangle (10,10,10);   
//a==b function does not appear to depend on global or static variables

你觉得这个答案有什么问题吗? 提前谢谢。

5 个答案:

答案 0 :(得分:5)

你也应该检查边长。如您所知,2边的总长度必须大于最后边的长度。 所以你也应该检查一下这样的东西:

if(x+y<=z || x+z<=y || z+y<=x)
    return ERROR;

UPD:以下是完整解决方案(包括溢出检查):

inline bool isSidesOverflow(int a, int b)
{
    return b > INT_MAX - a;
}
int detemineTriangle(int x, int y, int z)
{
    if((x<=0) || (y<=0) || (z<=0)) return ERROR;
    // If all sides are equal and greater than 0 - no need to check overflow and validness.
    if(x == y && y == z) return EQUILATERAL;
    //Check overflow now
    if(isSidesOverflow(x,y) || isSidesOverflow(x,z) || isSidesOverflow(y,z)) return ERROR;
    //Check if it's valid triangle
    if(x+y<=z || x+z<=y || z+y<=x) return ERROR;
    if((x==y) || (x==z) || (y==z)) return ISOSCELES;
    return SCALENE;
}

(没有编译,可以通过评论报告错误)

答案 1 :(得分:1)

#include <iostream>  

#include <iomanip>

#include <string>

using namespace std;

// define the data type "triangletype" with {values}

enum triangleType { scalene, isosceles, equilateral, noTriangle };

// Prototype function which returns the position of triangleType{value}

// Example: Scalene = 0, isosceles = 1, etc. These are zero indexed.

triangleType triangleShape(double a, double b, double c);

// Prototype function which takes the integer value of the 

// triangle type and outputs the name of triangle

string shapeAnswer(int value);

int main() {

    double inputA; 
    double inputB; 
    double inputC;

    cout << "To determine whether a triangle is either:" << endl;
    cout << setw(50) << " - Scalene" << endl; // Unequal in length
    cout << setw(52) << " - Isosceles" << endl; // Two sides equal length
    cout << setw(54) << " - Equilateral" << endl; // All sides equal
    cout << setw(57) << " - Not a triangle" << endl; 
    cout << "Enter side A: ";
    cin >> inputA;
    cout << "Enter side B: ";
    cin >> inputB;
    cout << "Enter side C: ";
    cin >> inputC;
    cout << "The triangle is " << shapeAnswer(triangleShape(inputA, inputB, inputC)) << endl;

}

triangleType triangleShape(double a, double b, double c) {

    triangleType answer;

    if ( c >= (a + b) || b >= (a + c) || a >= (b + c) ) {
        answer = noTriangle;
    }
    else if (a == b && b == c) {
        answer = equilateral;
    }

    // Test the 3 options for Isosceles equality
    else if ( (a == b) && (a != c) || (b == c) && (b != a) || (a == c) && (a != b) ) {
        answer = isosceles;
    }
    else {
        answer = scalene;
    }

    return answer;
}

string shapeAnswer(int value) {

    string answer;

    switch (value) {
    case 0:
        answer = "Scalene";
        break;
    case 1: 
        answer = "Isosceles";
        break;
    case 2:
        answer = "Equilateral";
        break;
    case 3:
        answer = "Not a triangle";
        break;
    default:
        break;
    }
    return answer;
}

答案 2 :(得分:0)

我会将测试分成几个测试用于测试不同错误的测试用例。这样,您现在不仅可以使函数determineTriangle不正确,而且还可以解决它有什么问题。

我想说使用第三方库进行测试(例如CXXTest或谷歌测试框架)将是一个优势。大多数此类框架提供了可用于验证的不同断言函数。

我能想到的另一个改进是在所有可能的排列中测试每个三元组 - 函数的结果应该是相同的(所以也许写一个辅助函数testTiplet(int sidea, int sideb, itn sidec, int expectedType))

编辑:我的回答只是建议你如何改进测试部分。 Sat在他/她的回答中提到了一个重要的实施流程。

答案 3 :(得分:0)

我会将评论转换为答案。

您还应该测试三边的长度是否有效。一般规则是longest_size < shortest_side + median_side

对此的测试可能是:

detemineTriangle(1, 1, 100);

除此之外,您可以通过执行其他人建议的操作来使测试更加稳固,例如测试所有参数的排列(@Ivaylo)。

答案 4 :(得分:0)

我最近在解决这个问题。

这就是我解决它的方法。

int detemineTriangle(int x, int y, int z)
{
 if (x <= 0 || y <= 0 || z <= 0 )
    return ERROR;
 else
    if (z >= (x + y) || y >= (x + z) || x >= (y + z) )
        return ERROR;
    else if (x == y && y == c)
        return EQUILATERAL;
    else if ( ( (x == y) && (x != z) ) || ( (y == z) && (y != x) ) )
            return ISOSCELES;
    else
            return SCALENE;
}

第一个if语句限定输入以确保值大于1。第二个if语句限定输入是否为有效三角形(两边加在一起必须大于第三边)。第三个if语句查找x = y和y = z,这意味着x = z。第四个if语句看起来是双方相等但第三方不是。结论性的else语句只返回scalene,但如果你愿意,可以测试它。