草庐IT

java - 我自己的 http 服务器的 TCP 机器状态单元测试

coder 2023-09-20 原文

我使用新的 http 服务器实现。我将创建单元测试,这将帮助我检查我的 TCP 连接状态的状态机是否正常工作。

当然我需要检查一些简单的事情,比如:我的服务器是在收到 RST 后切换到 closed 状态还是切换到 established在序列 SYN、SYN+ACK、ACK 之后。

因为这个状态机中可能的路径数量很大,我想知道我应该关注哪些测试。

例如,Apache 是否有我可以从中获取模式的公共(public)单元测试?

第二件事是......我应该从应用程序的角度开始创建这个测试,所以我应该专注于创建我可以使用简单的 java 套接字模拟的测试,使用像 connect 这样的命令, 发送

最佳答案

测试什么

每个单元测试策略的总体目标是:

  1. 完整代码覆盖:这意味着您的应用程序的每一行代码在完整测试套件中至少执行一次。
  2. 规范的全面覆盖:通常,软件开发从功能规范开始,该规范准确说明了软件的功能以及它在每种可能情况下的 react 方式。规范中提到的每个需求至少需要一个测试。当您没有规范时,最少测试的指南可能是 the specification of the HTTP protocol itself .

无论何时测试服务器应用程序,您都必须记住,您不能假设您的客户端将是 HTTP 协议(protocol)的完美实现。在现实世界中,您的服务器将面对错误实现它的客户端,或者连接不可靠的客户端,这些客户端在您的应用程序的任何状态下突然终止。这甚至还没有考虑到故意尝试查找和利用您服务器中的漏洞的恶意客户端。这些也是您需要测试用例的情况。

服务器通常是多线程的。这意味着应该测试多线程带来的常见问题(如竞争条件、死锁、同步问题、繁忙的旋转等)。不幸的是,这些问题很难预测,甚至更难为其编写有意义的单元测试。不仅因为这些问题通常通过不同组件的交互表现出来,这是集成和系统测试的范围,而不是单元测试。

如何测试

单元测试通常不应依赖于外部资源,因为当它们依赖于外部资源时,您是在测试该资源,而不是您自己的应用程序。当您的应用程序的功能严重依赖外部系统时,例如 http 服务器的情况,则应模拟其他系统。

这是通过使用 mock objects 实现外部资源来完成的.模拟对象是代替依赖于外部资源的对象的对象(通过扩展它或通过实现相同的接口(interface)),但仅模拟其行为。在网络服务器的上下文中,您将创建一个扩展 Socket 的类, 但用模拟外部客户端而不实际访问网络的东西覆盖 Socket 的所有方法。

然后您可以在单元测试期间使用它来测试您的类而不是普通套接字。

这使您可以轻松实现特殊的模拟套接字来测试特殊的测试条件,例如响应缓慢、非常快或完全错误的客户端。

您可能想知道“但是当我在要测试的类中创建一个 new Socket() 时,我应该怎么做呢?”?答案是,为了使应用程序可单元测试,您不应该这样做。关键字是Dependency Injection .简而言之,依赖注入(inject)意味着一个类不应该使用 new 关键字,除非它是那种类的工厂或生成器。类使用的任何对象都不应该由它创建。它们应该通过构造函数或 setter 方法提供给它。

示例:

所以当你有一个 ConnectionListener 类,它使用 ServerSocket 来等待客户端连接,然后用它们做一些事情时,你不应该创建那个 ServerSocket它的构造函数。相反,您应该将 ServerSocket 传递给 ConnectionListener 的构造函数。在生产代码中,这将是 a normal server socket .但是在您的单元测试中,您可以传递一个扩展 ServerSocket 的模拟对象。该模拟对象将模拟一个或多个客户端,然后在 ConnectionListener 的行为符合预期时向单元测试框架报告。

关于java - 我自己的 http 服务器的 TCP 机器状态单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15945140/

有关java - 我自己的 http 服务器的 TCP 机器状态单元测试的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  5. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  6. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

随机推荐