【问题标题】:test a function that returns triangle type测试一个返回三角形类型的函数
【发布时间】:2023-03-12 05:31:01
【问题描述】:

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

编写一个函数,该函数接收三角形边长的三个整数输入,并返回四个值之一以确定三角形类型(1=scalene,2=isosceles,3=equilateral,4=error)。假设另一个开发人员对该函数进行了编码,则为该函数生成测试用例。

我的回答是:

#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

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

【问题讨论】:

  • 在我看来,您没有测试三个边的长度是否有效。例如,你不能有一个三边分别为111000 的三角形。一般规则应该是longest_size &lt; shortest_side + median_side
  • 我想说@elnigno 有关键点,但不要假设人们不会因为他们的“一般东西”而被拒绝。招聘是一项奇怪的业务。将“最佳”编码实践与此类答案一起应用总是一个很好的提示 - 例如 always 支持 if 并且只有一个返回。你永远不知道审稿人最近是否被一个不带支撑的多行宏咬了......
  • 首先排序长度(这样x &gt;= y &amp;&amp; y &gt;= z 保持)将简化检查。例如。 ERROR 将被返回 if z &lt;= 0 || x -y &gt;= z, EQUILATERAL if x == z

标签: c++ c testing integration-testing


【解决方案1】:

您还应该检查边长。如您所知,两条边的总长度必须大于最后一条边的长度。 所以你也应该检查这样的事情:

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;
}

(未编译,欢迎通过cmets报错)

【讨论】:

  • true,所以应该为此添加另一个测试。
  • 它为[INT_MAX-1, INT_MAX-1, INT_MAX-2]等有效三角形提供错误错误
【解决方案2】:
#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;
}

【讨论】:

    【解决方案3】:

    我会将测试分成几个测试用例来测试不同的错误。这样,您现在不仅会发现函数 determineTriangle 不正确,而且还会对它的问题有所了解。

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

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

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

    【讨论】:

    • 我同意 - 除非 Sat 已经确定了逻辑问题,否则我会担心测试本身无法运行 - 正如 Ivaylo 所说,我希望看到每个测试都在运行并与预期结果进行比较,并输出一份报告,说明有多少测试失败。另外,我对最后的“线程安全”测试有点困惑。
    • 测试部分已经分为几类,涵盖了几个错误类别
    • 是的,但您的测试结果是all passedsomething failed。如果你有单独的测试用例,你可以说This case failed
    【解决方案4】:

    我会将我的评论转换为答案。

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

    对此的测试可能是:

    detemineTriangle(1, 1, 100);
    

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

    【讨论】:

      【解决方案5】:

      我最近遇到了这个问题。

      我就是这样解决的。

      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,但您可以根据需要对其进行测试。

      【讨论】:

        猜你喜欢
        • 2021-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-19
        • 2019-02-20
        • 2021-01-21
        相关资源
        最近更新 更多