您在AppEngine上使用了什么方法进行轻量级Python单元测试?

您在AppEngine上使用了什么方法进行轻量级Python单元测试?,python,unit-testing,google-app-engine,Python,Unit Testing,Google App Engine,我即将开始一些大型的基于Python的应用程序引擎项目,我认为我应该先检查Stack Overflow的“群体智慧”,然后再致力于单元测试策略。我有一个现有的单元测试框架(基于自定义的运行程序和扩展),我想使用它,所以任何“重量级”/“侵入性”的东西,比如,或者看起来都不合适。在我的worldview中,关键的单元测试是非常轻量级和快速的,它们在非常短的时间内运行,因此我可以一直反复运行它们,而不会打破我的开发节奏(例如,对于一个不同的项目,我得到一个20K线路项目的97%个覆盖率,几十个超快速

我即将开始一些大型的基于Python的应用程序引擎项目,我认为我应该先检查Stack Overflow的“群体智慧”,然后再致力于单元测试策略。我有一个现有的单元测试框架(基于自定义的运行程序和扩展),我想使用它,所以任何“重量级”/“侵入性”的东西,比如,或者看起来都不合适。在我的worldview中,关键的单元测试是非常轻量级和快速的,它们在非常短的时间内运行,因此我可以一直反复运行它们,而不会打破我的开发节奏(例如,对于一个不同的项目,我得到一个20K线路项目的97%个覆盖率,几十个超快速测试,花费5-7秒,经过一段时间,对于一个典型的运行,总体来说,这就是我认为的一套像样的小的、快速的单元测试)。。当然,我还将进行更丰富/更繁重的测试,一直到使用selenium或windmill进行集成测试,这不是我要问的;-)--我在这个问题上的重点(以及在我的大多数开发工作中;-)是小的、轻量级的单元测试,这些测试可以轻松、超快速地覆盖我的代码,在更深层次的问题上没有

因此,我认为我需要的基本上是对各种关键应用引擎子系统的一组小型、非常轻量级的模拟——数据存储、memcache、请求/响应对象和对webapp处理程序的调用、用户处理、邮件和c,大致按此优先级顺序。我还没有找到我想要的东西,所以在我看来,我应该或者依赖,就像我过去经常做的那样,这基本上意味着模拟给定测试中使用的每个子系统,并设置所有期望值&c(很强,但每次都要做很多工作,并且对测试代码的内部非常敏感,即非常“白盒”y),或者对每个子系统进行我自己的模拟(并作为单元测试的一部分对模拟子系统的状态进行断言)。鉴于GAE的Python端强大的“存根”架构,后者似乎是可行的。。。但我不敢相信我需要自己动手,也就是说,还没有人编写过如此简单的模拟器例如,对于数据存储,我需要的似乎是或多或少的“文件上的数据存储”存根,它已经是SDK的一部分,加上一种将其标记为只读和易于使用的访问器的方法,用于断言数据存储的状态;以此类推,一个子系统一个子系统——每个子系统似乎都需要比SDK中已有的“位于现有“存根”体系结构之上”的“稍微多一点”

因此,在投入一两天宝贵的开发时间“滚动我自己的”GAE子系统模拟以进行单元测试之前,我想我应该与So人员再次核实一下,看看大家对此有何看法。。。或者,如果已经有一些现有的开源模拟器,我可以简单地重用(或者至少调整一下!),但我在搜索中没有发现!)

编辑:为了澄清,如果我确实推出了自己的,我确实计划在可行的情况下利用SDK提供的存根;但是,例如,数据存储没有存根,它最初是从文件中读取的,但最后没有保存,因此我需要对现有的存根进行子类化和调整(这也没有提供特别方便的方法来对其状态进行断言——邮件服务存根也是如此,等等)。这就是我所说的“自己翻滚”——而不是“从头开始重写”!-)


编辑:“为什么不使用GAEUnit”--GAEUnit适合自己的用例,但运行dev_appserver并在我的浏览器中查看结果(甚至通过urllib.urlopen)绝对不是我想要的——我想使用一个完全自动化的设置,适合在基于扩展unittest的现有测试运行框架内运行,而且没有HTTP(该框架将“快速”测试定义为一个没有套接字和最小磁盘I/O的测试——我们模拟或模拟这些测试——因此通过gaeunit,我可以做的比“中等”测试更好)+没有方便的方法为每个测试预填充数据存储(也没有OO结构来帮助定制东西).

我将GAEUnit用于我的Google应用程序引擎应用程序,我对测试的速度非常满意。我喜欢GAEUnit的一点,我相信Webtest也会这样做,那就是它为测试所需的所有内容的存根创建了自己的版本,而让您的“实时”版本单独进行测试


因此,您可能用于开发的数据存储在运行Gaetest时将保持原样。

您不需要编写自己的存根-SDK包括它们,因为它们是用来模拟生产API的。并不是所有这些都适合在单元测试中使用,但大多数都适合。查看使用内置存根所需的安装/拆卸代码示例。

是一个nose插件,通过自动为您设置开发环境和测试数据存储来支持单元测试。在dev_appserver上开发时非常有用。

我还可以补充一点,这在我的单元测试中非常有用。它允许您以声明性语法创建模型,并将其转换为可在测试中加载的存储实体。这样,在每个测试用例的开头都有相同的数据集!,这使您不必在每次测试开始时手动创建数据。以下是夹具文档中的一个示例: 鉴于这种模式:

from google.appengine.ext import db

class Entry(db.Model):
    title = db.StringProperty()
    body = db.TextProperty()
    added_on = db.DateTimeProperty(auto_now_add=True)
您的固定装置如下所示:

from fixture import DataSet

class EntryData(DataSet):
    class great_monday:
        title = "Monday Was Great"
        body = """\
Monday was the best day ever.
"""
但是请注意,我遇到了以下问题: 1.但附带的补丁确实解决了这一问题。 2.默认情况下,数据存储不会在测试用例之间重置。因此,我使用它强制每个测试用例重置:

class TycoonTest(unittest.TestCase):
    def setUp(self):
        # Clear out the datastore before starting the test.
        apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map['datastore_v3'].Clear()    
        self.data = self.load_data()
        self.data.setup()
        os.environ['SERVER_NAME'] = "dev_appserver"
        self.after_setUp()

    def load_data(self):
        return datafixture.data(*dset.__all__)

    def after_setUp(self):
        """ After setup
        """
        pass

    def tearDown(self):
        # Teardown data.
        try:
            self.data.teardown()
        except:
            pass
因为有内置的

现在才是Java,但我觉得:

  • 这与您在问题中谈论的内容基本相同(甚至更多——例如在云中运行测试)
  • 在Pyt上移植\实现同样的功能是完全可能的