【问题标题】:Testing event-driven tcp applications测试事件驱动的 tcp 应用程序
【发布时间】:2013-11-28 09:33:32
【问题描述】:

我已经为我们在工作场所开发的系统的特定需求编写了一个事件驱动的 tcp 服务器。我还为此编写了单元测试。
在每个测试中,我都使用标准 C# TcpListener 和 TcpClient 连接到我的库。我正在将特定的数据位写入其中,然后检查测试代码是否触发了适当的事件。
问题是——这是一场比赛!我的意思是,有时当我向 TcpClient 写入数据时,可能会立即触发事件,有时可能需要 100 毫秒,有时如果计算机速度很慢(或连接速度很慢),则需要更多时间。
说了这么多,我们来画一个简单的测试(顺便说一下我用的是NUnit):

[Test]
public void TestEventA()
{
    bool eventFired = false;

    //my server would listen on 127.0.0.1:9090
    MyTcpServer serv = new MyTcpServer("127.0.0.1", 9090);
    serv.OnA += new AEventHandler((object sender, AEventArgs args) =>
    {
        eventFired = true;
    });

    //imitating a remote client connecting
    TcpClient client = new TcpClient();
    client.Connect("127.0.0.1", 9090);

    //remote client is sending data
    client.Getstream().Write(/*you know the drill here*/);

    //give the connection and server time to react
    System.Threading.Sleep(100);

    Assert.IsTrue(eventFired);
}

所以这只是一个简单的测试示例。问题是 - 它每次都在我的本地 PC 上通过,但在我们的构建服务器上它是完全随机的。现在我 100% 确定这是因为当我们到达断言时事件还没有被触发。问题是,我不知道如何正确设计测试以避免这种竞争条件。
我相信你们中的许多人都做过类似的事情(可能不是使用 TCP,而是测试事件驱动的东西,当我们不知道事件触发需要多长时间等时),所以我很想学习你的经历。
谢谢。

【问题讨论】:

    标签: c# unit-testing events tcp nunit


    【解决方案1】:

    这是一个端到端/集成测试,在这种情况下除了增加睡眠时间你还能做什么?

    如果你想对服务器进行单元测试,你需要以一种可以模拟来自客户端的连接的方式编写它,这样你就不需要实际实例化网络连接。

    【讨论】:

    • 即便如此,如果在触发事件之前发生了很多处理,您仍然无法预测应该休眠多长时间以确保在您到达时触发事件断言。所以我希望有一种不同的测试设计方法来避免遇到这样的情况。
    • 如果你对服务器进行单元测试——所有与网络/数据库等的连接都被模拟,你就不会有这个问题。在端到端测试中,我认为您无法摆脱它
    • 是的,我明白了,网络连接会导致延迟。但是想象一下这样的情况:你模拟了连接,你发送数据,服务器在准备触发事件之前处理它说 500 毫秒(一些 CPU 繁重的操作),但你只等待 300 毫秒。因此,您将等待时间增加到 600 毫秒,但是在 CPU 功率较低且速度较慢的机器上,处理将需要 1000 毫秒……您看到这里的问题了吗?不仅 TCP 延迟是个问题,“我得到数据”和“我准备好触发一个事件”之间的差距在事件驱动的应用程序中也是一个问题......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 2017-03-09
    • 2012-07-29
    • 2011-05-23
    • 1970-01-01
    相关资源
    最近更新 更多