大道至简,新一代企业应用无栈开发

平台之上,一种语言,可视化、脚本化、全端一体化开发

测试框架

docutils document without title

测试框架用于后端开发的自动化测试,安装 zopen.tests 可以对任意的应用中的测试脚本进行测试。

测试脚本使用标准的扩展应用脚本编写,要求:

  • 脚本必须以 test_ 开头来命名,。
  • 脚本的模板必须是 api/数据

1   基本测试流程

分准备、初始化测试环境、测试、销毁四个阶段:

# 1. 准备:对于需要使用文件的测试脚本,通常在个人网盘中创建一个文件夹,用于测试
testcase = root.tests  # 初始化一个 testcase
myfiles = root.profiles.get_home(request.me.id)['files']  # 取得个人网盘
test_folder_name = '一个简单的测试'

# 2. 测试
try:
    # 2.1 SETUP环节,初始化测试环境
    test_folder = myfiles.add_folder(test_folder_name)
    test_folder.index(async=False)

    # 2.2 TEST环节,进行测试
    testcase.test(test_folder_name in myfiles, '创建文件夹:' + test_folder_name)

    # 2.3 返回测试结果::
    return testcase.get_results()

# 3. TEAR DOWN环节,销毁测试环境,测试完成后,将整个测试文件夹删除
finally:
    import transaction
    # 如果发生异常,需要先回滚保证完整性
    transaction.abort()

    # 如果之前有commit,需要清理
    if test_folder_name in myfiles:  # teardown 可以单独调用,需要处理已经被 teardown 过的情况
        del myfiles[test_folder_name]  # 销毁测试环境。注意:有时需要修改其他数据才能删除测试环境,例如修改文件状态,或回滚事务。

    # 需要commit来生效,否则执行过程中异常,上面的清理逻辑可能最终被回滚了
    transaction.commit()

2   运行测试

脚本使用 root.tests 来执行断言。具体使用方法是:

testcase.test(expression, title='说明:测试某某')

其中expression就是一个测试表达式,如果成功返回 True ,否则 False

test_folder = myfiles[test_folder_name]  # 获得测试文件夹的引用
testcase.test(test_folder_name in myfiles, '一些测试blahblah')  # 编写实际的测试逻辑
testcase.test(1 + 1 == 2, '一加一等于二')  # 第二个参数指定这个断言的名称,用于最终展示测试报告

3   返回测试结果

返回测试结果:

return testcase.get_results()

测试结果的数据结构是:

[
    {'title': '某某测试', 'result': True}
]

如果某个断言为 False ,则表示这个测试未通过。

通过 zopen.tests:setup 页面手动运行测试,会以表格方式渲染测试报告。

调试时也可以直接打印出结果:

return testcase.render_result()

4   通过开放API测试

如果需要测试各个服务现有的API,可以先得到一个服务器client:

app = 'workonline' # viewer/oc/org/message/upload
wo_client = testcase.get_client(app)

然后调用这个client的标准api进行测试。

所有扩展应用的脚本,都可以通过xapi来进行调用:

result = wo_client.xapi('zopen.tests:index', uid=0))

所有v3接口的api,都有可以通过判断errcode来检查是否成功:

testcase.test(result['errcode'] == 0, 'OK')

5   使用不同用户测试

首先需要确保用户存在:

root.org.sync(objects_detail=[{'object_type':'person',
                             'id':'api_test_user',
                             'parent': 'groups.tree.default',
                             'disable':False}])

先记住当前用户:

me = request.me.id.split('.', 1)[1]

然后用这个用户登录:

root.login_as(request, 'api_test_user')

测试完成,切换到之前的用户:

root.login_as(request, me)

最后删除这个临时用户:

root.org.remove_objects(['users.api_test_user'])