谷歌测试除以零

时间:2018-09-19 12:40:52

标签: c++ unit-testing testing googletest divide-by-zero

我正在学习编写单元测试,并且从我想测试的简单“计算器”类开始。 我想出了如何使用EXPECT / ASSERT函数,以及什么是测试用例等,但是当我想测试除以零时遇到了一个问题。有可能进行测试吗?我的意思是,我应该写什么作为测试结果?是否有类似“错误”的内容?还是我必须使用例外?

到目前为止,这是我的测试:

describe MyController, type: :controller do

  before(:each) do
    @var1 = FactoryGirl.create(:var1)
    @var2 = FactoryGirl.create(:var2)
    @var3 = FactoryGirl.create(:var3)
  end

  # todo
  describe "#update" do

    # @var1, @var2 and @var3 are being used in each test

    it "should aaa" do
      put :url1, params: { ... } 

      expect(response.status).to eql 200
      r = JSON.parse(response.body)
      expect(r["val1"]).to eql val
    end

    it "should bbb" do
      put :url1, params: { ... } 

      expect(response.status).to eql 200
      r = JSON.parse(response.body)
      expect(r["val1"]).to eql val
    end


    it "should ccc" do
      put :url1, params: { ... } 

      expect(response.status).to eql 200
      r = JSON.parse(response.body)
      expect(r["val1"]).to eql val
    end

  end
end

3 个答案:

答案 0 :(得分:2)

我不同意@Ketzu。您期望当除以零时,计算器的表现如何。

EXPECT_EQ(, calculate.div(27,0));

在该测试中可能无法很好地表达这种期望。

如果calculate.div(27,0)引发异常,那么您可以捕获此异常,并且如果未引发测试,则测试将失败。你可以这样写

TEST(ExceptionTest, ExpectThrowsSpecificException) {
    try {
        calculate.div(27,0);
        FAIL() << "calculate.div(27,0) should throw an error, since a     division by zero is not valid\n";
    } catch (TestException& exception) {
        EXPECT_THAT(std::string(exception.what()), Eq("VALID_SETTING"));
        EXPECT_THAT(exception.errorCode, Eq(20));
    }
}

有关详细讨论,请参见here

如果没有引发异常,如何检测calculate.div的异常用法?

答案 1 :(得分:1)

  

是否有可能进行测试?我的意思是,我应该写什么作为测试结果?是否有类似“错误”的内容?还是我必须使用例外?

这是您需要问(并回答)自己的核心问题-如果无效,计算器(在这种情况下,函数Calc::div())的行为应该如何输入。它的行为方式有几种:

  1. 崩溃。这(通常)是在C ++中除以零时得到的行为(从技术上讲,行为是未定义的,因此编译器可能会执行任何操作。幸运的是(对我们而言),大多数编译器都同意终止整个过程是在此处执行的“正确” 任何操作
  2. 返回一些值。您可以返回(在被零除的情况下)infinity。或者可能是NaN。或在您的上下文中有意义的任何其他值。但是,这种方法将结果错误处理混合在一起,如今不建议这样做(因为这会迫使您检查函数的每个调用中是否有“错误结果”-以及如果您忘记了一项检查,则在继续使用无效/伪造的值进行操作时会遇到讨厌的错误。)
  3. 引发异常。您可以抛出异常,表示出现问题。这是当今常用的方法(极端性能敏感的东西除外,其中每微秒都很重要),因为它将正常路径(返回结果值)与错误路径(异常)巧妙地分隔开了(如果您忘记处理异常,则可以会立即注意到,而不是像选项2那样使用错误的值

一旦您决定了自己的行为,就可以可以进行测试。

对于选项1 ,gtest提供了death tests
对于选项2 ,您只需验证您是否获得了预期的结果即可。
对于选项3 ,您可以通过exception assertions或在try { } catch { }末尾带有FAIL()的自制try捕获并评估异常阻止(因此您会注意到该函数是否在预期的时候未能引发异常)

答案 2 :(得分:0)

您的评论

  

我以为我可以测试

建议对测试有误解。

您的测试仅测试类的行为是否符合您的期望。 测试绝不是错误处理机制!

如果您的函数之一正在使用某些参数创建应用程序崩溃,那不是您的测试应标记为正确的东西。

有关如何解决它(异常和合适的宏)的信息,请参阅约翰的评论。