Java 如何单元测试客户机-服务器代码

Java 如何单元测试客户机-服务器代码,java,maven-2,junit,testing,Java,Maven 2,Junit,Testing,我目前正在编写一个Java客户机-服务器应用程序。所以我想实现两个库,一个用于客户端,一个用于服务器。客户机-服务器通信有一个非常严格的协议,我不想用JUnit进行测试 作为构建工具,我使用Maven和Husdon服务器进行持续集成 实际上,我不知道如何测试这些客户机/服务器库 我得到了以下方法: 只需编写一个虚拟客户机来测试服务器,并编写一个虚拟服务器来测试客户机。 缺点:不幸的是,这将导致许多额外的工作。我不能100%确定客户端和服务器可以一起工作,因为我不能确定测试是否完全相同 编写一个单

我目前正在编写一个Java客户机-服务器应用程序。所以我想实现两个库,一个用于客户端,一个用于服务器。客户机-服务器通信有一个非常严格的协议,我不想用JUnit进行测试

作为构建工具,我使用Maven和Husdon服务器进行持续集成

实际上,我不知道如何测试这些客户机/服务器库

我得到了以下方法:

  • 只需编写一个虚拟客户机来测试服务器,并编写一个虚拟服务器来测试客户机。 缺点:不幸的是,这将导致许多额外的工作。我不能100%确定客户端和服务器可以一起工作,因为我不能确定测试是否完全相同

  • 编写一个单独的测试项目,一起测试客户端和服务器。
    缺点:单元测试不属于项目本身,因此Hudson不会自动运行它们。在这些库中更改任何内容的每个人都必须手动运行测试,以确保所有内容都是正确的。我也不会收到任何代码覆盖率报告

  • 有没有更好的方法来测试这样的代码? 也许测试一个Maven多模块项目,或者类似的东西

    我希望任何人都能找到解决这个问题的好办法

    谢谢。

    将所有代码都视为“将输入转换为输出”:
    X->[A]->Y

    X
    是输入的数据,
    [A]
    是变压器,
    Y
    是输出。在您的情况下,您有以下设置:

    [Client] -> X -> [Server] -> Y -> [Client]
    
    因此,单元测试的工作原理如下:

  • 您需要一个运行客户端代码的测试来生成
    X
    。验证代码是否实际生成带有断言的
    X
    X
    应该是代码中的最后一个静态字符串

  • 在第二个测试中使用常量
    X
    ,调用服务器代码,将其转换为
    Y
    (另一个常量)

  • 第三个测试确保客户端代码可以解析输入
    Y


  • 通过这种方式,您可以保持测试的独立性,并且仍然确保重要部分工作正常:组件之间的接口。

    您可以使用任何模拟对象框架来创建模拟对象-尝试jmockit

    我的建议是使用两个级别的测试:

  • 对于客户机/服务器项目,在单元测试中包括一些模拟,以确保对象接口按预期工作

  • 在构建之后,进行更广泛的集成测试运行,并在一个或多个测试系统上自动安装已编译的客户端和服务器。然后您可以确保协议的所有细节都经过了彻底的测试。在每次成功构建客户机/服务器项目时触发此集成测试项目。您可以使用JUnit进行此操作,并且仍然可以收到来自Hudson的常规报告


  • 因此,最终的解决方案是构建一个多模块项目,带有一个单独的测试模块,其中包括服务器和客户机模块 在休斯顿工作得很好。在EclipseIDE中甚至更好。
    感谢@Aaron的提示

    解决此问题的最新方法是使用Docker容器。创建一个docker文件,其中包含基本映像和客户端服务器应用程序所需的所有必要依赖项。为分布式客户机-服务器系统的每个节点类型创建一个单独的容器,并使用TestNG或JUnit测试所有入口点服务器API/客户机交互。这种方法最好的部分是,您不会模拟任何服务调用。在大多数情况下,您可以协调所有端到端的客户机-服务器交互

    这种方法涉及到一点学习过程,但是Docker在开发人员社区中非常流行,尤其是在解决这个问题方面

    以下是如何在JUnit测试中使用docker客户端api提取docker映像的示例:

    Hmm这正是为服务器和客户端实现单独单元测试的方法。事实上,这将导致将常量复制粘贴到两个项目中,从而实现“虚拟客户端”/“虚拟服务器”。这是我上面列出的第一种方法。为什么要将客户机和服务器放在不同的项目中?不管怎样,如果你真的想这样做,那么创建第三个单元测试项目,导入另外两个,所以你只需要一次常量。嗯,两个项目,因为客户端必须转到低资源设备。测试项目是我前面列出的第二种方法。我还写了这种方法的缺点。您可以配置Hudson在每次构建客户机或服务器项目时运行测试项目(请参阅“构建触发器”部分中的“在构建其他项目后构建”)。至于两个项目:将客户机和服务器放在两个maven模块中,将测试放在第三个模块中。这样,您就可以从根文件夹构建所有内容。