我如何区分单元测试和集成测试?

How do i differentiate unit tests from integration test?

我模拟了所有依赖项,为下面的测试存根。 这仍然被认为是单元测试或集成测试吗? 我在网上看过一篇文章,你应该把两者分开,单元测试应该 运行 尽可能频繁,集成测试偶尔进行一次。 我没有很多单元测试经验,我很难区分两者。

例如,我添加了新功能,但下面的测试失败了,但我测试了应用程序代码,它按预期工作。我觉得我的测试太脆弱了,我目前需要在更改源代码时不断更改测试或添加测试,这对我来说似乎不合适。

TEST_F(UserInterfaceTest, TransmitCalibrationWithWrongPacket)
    {
        std::vector<std::string> commandpathnames;

        for (int i = 0; i < 9; i++)
        {
            std::string txt("transmit_calibration");
            txt += std::to_string(i);
            txt += ".txt";

            commandpathnames.push_back(txt);
        }

        EXPECT_CALL(*m_View, DisableAndSwitchPanel());
        EXPECT_CALL(*m_View, CheckInstance(_, _));
        EXPECT_CALL(*m_View, GetSerialPortInstance()).WillRepeatedly(ReturnRef(serialport));
        EXPECT_CALL(*m_View, GetSerialPortAddress()).WillOnce(Return(port));
        EXPECT_CALL(*m_View, GetCalibration()).WillRepeatedly(Return(calib));

        EXPECT_CALL(*m_Param, SetFunction(_));
        EXPECT_CALL(*m_Param, GetFunction()).WillOnce(Return(TRANSMIT_CALIBRATION));
        EXPECT_CALL(*m_Param, GetTemperature());
        EXPECT_CALL(*m_Param, GetSurveyDelay()).WillOnce(Return(20));

        EXPECT_CALL(*calib, GetCommandPathNames()).WillRepeatedly(Return(commandpathnames));

        EXPECT_CALL(serialport, Read(_))
            .WillOnce(DoAll(SetArgReferee<0>(poll), Return(0)));

        EXPECT_CALL(serialport, Write(_))
            .WillOnce(DoAll(SetArgReferee<0>(identitycommand), Return(0)));

        EXPECT_CALL(*m_View, CustomEventDisplayData(_)).Times(AtLeast(1));

        EXPECT_EQ(wxTHREAD_NO_ERROR, m_Controller->TransmitMasCalibration());

        m_Controller->GetSemaphore()->Wait();
    }

当你转向wikipedia时,你会发现单元测试

unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use.

换句话说:你做的任何种测试都可以称为单元测试。

事实是:该定义没有帮助。 art of unit testing 等网站更具体:

Runs in memory (no DB or File access, for example)

导致:"true" 完全隔离的单元测试 运行。您切断了与其依赖关系的 任何 关系(除非这些依赖关系在您的单元测试环境中执行 "fine")。

从这个角度来看:只要您的单元测试不需要完整的堆栈启动和 运行ning,或者在某些网络接口上可以访问某些东西……它们可能就是单元测试.

我宁愿区分单元测试和功能测试。他们都练习了一小部分,但后面的一个有一个或多个依赖项 "really" 在那里。

集成测试甚至更进一步 - 这里您几乎没有 "stubbing" 依赖项。

但真正的答案是:这些术语模糊。不同的人有不同的看法。而且几乎不可能改变他们的观点。因此,真正的结论是:(和你的团队)应该清楚地定义这些术语对你意味着什么,然后你确保每个基于该代码工作的人至少知道那个愿景.

关于"too brittle"方面:这里又是两种观点。一方面,您专注于测试 public 合约。理想情况下,您可以将一种实现完全替换为另一种实现,并且您的单元测试仍然有效。因为理想情况下,您的单元测试只做 "given this input, expect that output (behavior)"。一旦您开始测试实现细节,您的测试就会在实现发生变化时中断。这使得测试的价值降低。

另一方面,测试特定的 "internal" 元素也可能是公平的。那好吧,你需要测试一下。

但如前所述:第一个方法是关于测试public合约,"what",而不是"how"。