Java 如何测试复杂的异步网络代码并遵循tdd

Java 如何测试复杂的异步网络代码并遵循tdd,java,tdd,Java,Tdd,单元测试网络异步代码的最佳实践是什么?我正在努力做/学tdd 我目前正在规划图书馆的这一部分,但原则上: 这是一个ssh客户端库。我希望它是异步的。Ssh连接过程实际上非常复杂。我的connect方法将以原子方式设置一些连接状态变量,然后使用某种任务执行器来调度连接任务。连接需要连接到服务器,通过发送和接收ssh协议版本和内容引入,然后完成密钥交换过程,该过程本身分为几个案例,因为很少有密钥交换算法需要交换不同的数据包 虽然我听说我应该测试公共api,并通过测试使用它的公共方法来测试私有方法,但

单元测试网络异步代码的最佳实践是什么?我正在努力做/学tdd

我目前正在规划图书馆的这一部分,但原则上: 这是一个ssh客户端库。我希望它是异步的。Ssh连接过程实际上非常复杂。我的connect方法将以原子方式设置一些连接状态变量,然后使用某种任务执行器来调度连接任务。连接需要连接到服务器,通过发送和接收ssh协议版本和内容引入,然后完成密钥交换过程,该过程本身分为几个案例,因为很少有密钥交换算法需要交换不同的数据包

虽然我听说我应该测试公共api,并通过测试使用它的公共方法来测试私有方法,但在这种情况下似乎很困难,因为任务相当复杂,可能更容易伪造部分协商而不是整个连接/协商,只需检查连接方法的每个可能结果,包括每个密钥交换算法的结果

将较大的连接任务拆分为较小的连接任务(即使这些任务对用户不公开),并测试每个单独的连接阶段,而不是一次测试整个连接方法,这是一个很好的理由吗?它是否以某种方式打破了最佳实践,或者如何以不同的方式做到这一点?例如,它是否正在测试实现细节

单元测试网络异步代码的最佳实践是什么?我正在努力做/学tdd

你需要阅读的参考资料是弗里曼和普莱斯的。该文本包含了如何使用测试开发异步网络拍卖客户端的详细介绍

正如作者所描述的,在开始填写其他细节之前,该过程会先加载大量工作,以获得初始端到端测试并运行

当然,这不是唯一的方法

虽然我听说我应该测试公共api,并通过测试使用它的公共方法来测试私有方法

是的,而且

在这种情况下,这似乎很困难,因为任务相当复杂,可能更容易伪造部分协商而不是整个连接/协商,只需检查连接方法的每个可能结果,包括每个密钥交换算法的结果

经常发生的事情是,一个复杂的解决方案可以分解成多个模块,每个模块都包含自己的“公共API”——参见Parnas。然后可以单独测试模块

例如,结果常常是,您的代码可以组织成两堆;一个内部功能内核,然后是一个命令shell,它与

一般来说,功能内核比命令式shell更容易测试,因此,要争取一个“非常简单,显然没有缺陷”的shell

那么,公共api的定义是什么

大概是:在实现范围之外可以访问的启示

换句话说,它们是模块的组成部分,如果不重写调用模块的代码,就无法更改


在本例中,我可能会将连接过程拆分为子任务,如连接、ssh介绍和密钥交换。并单独测试各个子任务。此外,我还将测试密钥交换支持,将其与特定的密钥交换算法实现隔离开来。测试这些部件的要求各不相同,只有第一个部件需要模拟插座

你可能还想看看科里·本菲尔德的演讲

我不确定这是否可以


如果你做得不“正确”,TDD警察不会来踢你的门。最坏的情况下,他们会写信给你。

你可能想看看单元测试和集成测试之间的区别。您写的最后一段(一步一步地测试连接)听起来像是单元测试(例如,当您测试服务器逻辑时,模拟客户端等外部部件),而公共API测试的所有部分都到位听起来像是端到端或集成测试。问题是,我听说只对面向公共用户的API进行单元测试是很好的。我尽可能做到这一点,但在这种情况下模拟整个协商将是困难的,因此可能最好分割和单元测试阶段,用户看不到也摸不着。至少是其中的一部分。另一件事是,当所有必要的部分都可以使用时,我也会对这个代码路径进行集成测试,那么公共api的定义是什么呢?中的公共api使用公共关键字,或中的公共api,用户看到了吗?包私有类的公共方法是否被视为公共api?我可以很好地将连接代码拆分为较小的任务,但这些任务中的大多数都不会以任何方式向用户公开,它们是内部任务。在这种情况下,我可能会将连接过程拆分为子任务,如连接、ssh介绍和密钥交换。并单独测试各个子任务。此外,我还将测试密钥交换支持,将其与特定的密钥交换算法实现隔离开来。测试这些部件的要求各不相同,只有第一个部件需要模拟插座。我不确定这是否可以。