java HowTo单元测试客户机-服务器代码
我目前正在编写一个Java客户机-服务器应用程序。所以我想实现两个库,一个用于客户端,一个用于服务器。客户机-服务器通信有一个非常严格的协议,我不想用JUnit进行测试
作为构建工具,我使用Maven和Husdon服务器进行持续集成
实际上,我不知道如何测试这些客户机/服务器库
我得到了以下方法:
只需编写一个虚拟客户机来测试服务器,并编写一个虚拟服务器来测试客户机。 缺点:不幸的是,这将导致许多额外的工作。我不能100%确定客户端和服务器可以一起工作,因为我不能确定测试是否完全相同
编写一个单独的测试项目,一起测试客户机和服务器
缺点:单元测试不属于项目本身,因此Hudson不会自动运行它们。在这些库中更改任何内容的每个人都必须手动运行测试,以确保所有内容都是正确的。我也不会收到任何代码覆盖率报告
有没有更好的方法来测试这样的代码? 也许测试一个Maven多模块项目,或者类似的东西
我希望任何人都能找到解决这个问题的好办法
谢谢
# 1 楼答案
解决这个问题的最新方法是使用Docker容器。创建一个docker文件,其中包含基本映像和客户端服务器应用程序所需的所有必要依赖项。为分布式客户机-服务器系统的每个节点类型创建一个单独的容器,并使用TestNG或JUnit测试所有入口点服务器API/客户机交互。这种方法最好的部分是,您不会模拟任何服务调用。在大多数情况下,您可以协调所有端到端的客户机-服务器交互
这种方法涉及到一点学习过程,但是Docker在开发人员社区中非常流行,尤其是在解决这个问题方面
以下是如何在JUnit测试中使用docker客户端api提取docker映像的示例: https://github.com/influxdb/influxdb-java/blob/master/src/test/java/org/influxdb/InfluxDBTest.java
# 2 楼答案
我的建议是使用两个级别的测试:
对于客户机/服务器项目,在单元测试中包括一些模拟,以确保对象接口按预期工作
在构建之后,进行更广泛的集成测试运行,并在一个或多个测试系统上自动安装已编译的客户端和服务器。然后您可以确保协议的所有细节都经过了彻底的测试。在每次成功构建客户机/服务器项目时触发此集成测试项目。您可以使用JUnit进行此操作,并且仍然可以收到来自Hudson的常规报告
# 3 楼答案
将所有代码都视为“将输入转换为输出”:
X -> [A] -> Y
X
是进入的数据,[A]
是转换器,Y
是输出。在您的情况下,您有以下设置:因此,单元测试的工作原理如下:
您需要一个运行客户端代码的测试来生成
X
。验证代码是否实际生成带有断言的X
X
应该是代码中的final static String
在第二个测试中使用常量
X
调用服务器代码,将其转换为Y
(另一个常量)第三个测试确保客户端代码可以解析输入
Y
通过这种方式,您可以保持测试的独立性,并且仍然确保重要部分工作正常:组件之间的接口
# 4 楼答案
您可以使用任何模拟对象框架来创建模拟对象—请尝试jmockit
# 5 楼答案
因此,最终的解决方案是构建一个多模块项目,带有一个单独的测试模块,其中包括服务器和客户机模块 在休斯顿工作得很好。在EclipseIDE中甚至更好。 谢谢@Aaron的提示