您在App Engine上使用了哪些轻量级Python单元测试方法?
我准备开始一些大型的基于Python的App Engine项目,在决定使用什么样的单元测试策略之前,我想先看看大家的意见。我现在有一个现成的单元测试框架(基于unittest,并且有一些自定义的运行器和扩展),我想继续使用它,所以像nose、webtest或gaeunit这些比较复杂的工具似乎不太合适。在我看来,最重要的单元测试是非常轻量级和快速的,能够在极短的时间内运行,这样我就可以不停地运行它们,而不会打乱我的开发节奏(例如,对于另一个项目,我的20,000行代码的项目有大约97%的覆盖率,运行几个超级快速的测试,通常只需5到7秒的时间,这就是我认为的一个不错的小而快的单元测试套件)。当然,我也会有更复杂的测试,包括使用selenium或windmill的集成测试,但这不是我这次想讨论的重点;-) 我关注的是那些轻量级的小单元测试,它们能够快速覆盖我的代码,而不是更深层次的测试。
所以我认为我需要的基本上是一组小而非常轻量的模拟,模拟各种关键的App Engine子系统——数据存储、内存缓存、请求/响应对象以及对webapp处理程序的调用、用户处理、邮件等等,大致按这个优先顺序。我还没有找到完全符合我需求的东西,所以我觉得我要么依赖于mox,就像我过去常做的那样,这基本上意味着在每个测试中模拟每个子系统,并设置所有期望等(虽然很强大,但每次都需要很多工作,并且对被测试代码的内部结构非常敏感,也就是很“白盒”),要么自己动手模拟每个子系统(并在单元测试中对模拟的子系统状态进行断言)。后者似乎是可行的,因为GAE的Python端有很强的“存根”架构……但我真不敢相信我需要自己动手,也就是说,没人已经写过这么简单的模拟器!-) 例如,对于数据存储,我需要的基本上是SDK中已经包含的“文件上的数据存储”存根,加上一个将其标记为只读的方式,以及用于断言数据存储状态的易用访问器;其他子系统也是如此——每个子系统似乎都需要比SDK中已有的“存根”多一点点,“建立在”现有的“存根”架构之上。
所以,在我深入研究并花一两天宝贵的开发时间“自己动手”模拟GAE子系统以进行单元测试之前,我想先和大家确认一下,看看你们对此有什么看法……或者,是否已经有现成的开源模拟器可以让我直接重用(或者稍微调整一下!-),而我在搜索时没有发现!-)
编辑:为了澄清,如果我自己动手,我确实计划在可行的情况下利用SDK提供的存根;但例如,没有一个存根可以从文件中读取数据存储,然后在最后不保存,所以我需要对现有的存根进行子类化和调整(而且现有的存根也没有特别方便的方式来对其状态进行断言——邮件服务存根也是如此)。这就是我所说的“自己动手”——不是“从头开始重写”!-)
编辑:“为什么不使用GAEUnit”——GAEUnit在其特定用例中很好,但运行dev_appserver并在浏览器中查看结果(甚至通过urllib.urlopen)绝对不是我想要的——我想要的是一个完全自动化的设置,适合在基于扩展unittest的现有测试运行框架中运行,并且没有HTTP的干扰(该框架将“快速”测试定义为在其他条件下不使用套接字和最小的磁盘I/O——我们模拟或模拟这些——所以通过gaeunit我也只能做到“中等”测试)+没有方便的方法为每个测试预填充数据存储(也没有面向对象的结构来帮助自定义)。
6 个回答
我在我的Google App Engine应用中使用GAEUnit,测试速度让我很满意。我喜欢GAEUnit的一点是,它会为测试创建自己的一套模拟版本,这样就不会影响到你正在使用的“真实”版本。
所以,当你运行GAETests时,你用来开发的数据存储不会被改变,保持原样。
NoseGAE 是一个插件,它可以帮助你进行单元测试。这个插件会自动为你准备好开发环境和测试用的数据存储,非常适合在 dev_appserver 上进行开发时使用。
你不需要自己写占位符,开发工具包(SDK)里已经包含了这些占位符,因为它们是用来模拟真实的生产接口的。并不是所有的占位符都适合用在单元测试中,但大多数都是可以的。你可以看看这段代码,里面有你需要的设置和清理代码,帮助你使用这些内置的占位符。