代码之家  ›  专栏  ›  技术社区  ›  Glenn

测试JSON客户机-服务器API的推荐方法是什么?

  •  2
  • Glenn  · 技术社区  · 17 年前

    编辑2:是否有人有一个好的方法来测试客户机-服务器应用程序的“中间”,我们可以截取请求和响应,根据需要伪造客户机或服务器,并提供API的自我文档?

    黄瓜在很多情况下可能是一个很好的解决方案,但它不是我想要的。中间层应该是不可知的客户机/服务器实现。(例如,黑匣子)。


    我们的客户机-服务器模型是一个带有flex客户机的RubyonRails服务器,使用一个带有JSON的restish接口作为数据格式。所以客户机向服务器发布的任何内容通常都是一个JSON参数。服务器做它的事情,并用纯JSON模型响应。

    我们在服务器上有标准的Rails测试,我们正在努力在客户机上完成适当的flexUnit测试(这是一个移动目标)。但是,我的团队中有一个关于当前测试模型有效性的争论,因为服务器上的每一个更改似乎都会破坏API的一部分。这说明API通信(团队成员之间、代码中的自我文档等)存在问题,并且缺乏适当的API健全性测试。

    因此,我一直在质疑我们是否需要一个模拟客户机来在纯JSON级别测试服务器(不需要富客户机的所有其他复杂性),以及是否需要一个模拟服务器来对富客户机执行相同的操作。这有两个目的,一个是记录API,另一个是对API本身进行更彻底的测试。

    之所以会有争论,是因为Rails人员声称Rails集成测试足以测试所有服务器请求,而中间层测试环境只是多余的。

    所以这里的问题是,考虑到我们的情况,应该如何对API进行自文档化,以及应该如何测试API本身?

    编辑:

    我们有类似/foo/444/bar.js的路由,但根据操作,参数实际上可以是任何复杂的JSON字符串,例如:

    json={
      "foo":{
        "x":1, 
        "y":2
       }, 
      "bar":[1,2,3,4,5]
    }
    

    但是除了手工编辑的API文档之外,没有自己的文档。Rails控制器通常只是反序列化并将更改直接应用于模型。很高兴有一些常见的测试来告诉我们什么时候发生了变化, 和 期待什么。

    4 回复  |  直到 15 年前
        1
  •  1
  •   Chiwai Chan    17 年前

    我刚开始研究这个名为MAXQ的Web功能测试工具,我认为它有潜力解决您的问题,MAXQ充当Web客户机和服务器应用程序之间的代理服务器。 它位于JUnit之上,这意味着您可以通过断言对服务器应用程序的调用的行为和响应来为您的API进行适当的单元测试。 它基本上捕获并记录您从Web客户机发出的所有请求以及从服务器返回的响应,它还能够生成请求的测试脚本,您可以使用这些脚本在任何服务器上回放和测试。

    你应该试试看 http://maxq.tigris.org/

        2
  •  1
  •   amitkaz    17 年前

    你可以把它看成两个不同的项目。如果你有两个项目,你会写两个独立的测试套件,对吗?

    您应该首先在服务器和客户机之间建立API。- 犹如 在开始实施之后,团队之间不会有任何沟通。

    然后,构建使用API的客户机和生成API的服务器(或者,如果是TDD,则先测试)。

    对于测试,一个团队需要一个模拟服务器来提供假API响应来测试客户机,另一个团队需要测试服务器的生成数据(即,第二个团队使用的是像Rails Guy声称的那样的AILS集成测试)。

        3
  •  1
  •   Ariejan    17 年前

    我推荐黄瓜。它允许您通过模拟浏览器为应用程序编写特定的测试。通过这种方式,您可以轻松地发送请求和验证JSON响应。

        4
  •  0
  •   Scott Schulthess    15 年前

    一种方法是使用rspec进行控制器测试(也可以使用test::unit)

    describe PersonApiController 
      # GET /person/1.json
      it "should respond with a person" do 
         person = Person.create(:name => "scott")
         get :show, :id => person.id, :format => 'json'
         response.should be_success
         response.body.should have_selector('name', :content => person.name)
      end
    end