配置测试项目¶
本节主要介绍如何修改测试项目的配置文件 settings.py来修改测试框架的行为。如果需要查询QTA框架的全部配置项,请参考《配置项说明文档》。
配置语法¶
测试项目的配置文件是一个python模块,所以配置项都是python模块的模块变量,如下所示:
DEBUG = True
RUNNER_THREAD_COUNT = 5
LOCAL_REPORT = 'console'
由于使用的是python模块表示,因此需要符合以下要求:
- 需要符合python语法要求
除此之外,对于配置项还需要符合以下要求:
- 配置变量名必须使用大写
- 配置变量名不可以双下划线开头
比如下面的变量都是非法的:
lower_test = 34
__CONFIG = "XXX"
配置文件¶
QTA配置文件分为三种:
- 用户配置文件
- 依赖Egg包的配置文件
- Testbase配置文件(即qtaf_settings模块)
注解
注意依赖Egg包的配置文件只有通过“manage.py installlib”方式安装到测试项目中,其配置文件才会被加载,具体的依赖egg,可以参考exlib下的installed_libs.txt
用户配置文件存放在测试项目的顶层位置;而QTAF配置文件打包在QTAF的egg包中,在QTAF egg包的顶层位置上;如下:
test_proj/
qt4a/
exlib/
qtaf.egg/
testbase/
tuia/
pyqq/
qtaf_settings.py # Testbase配置
qt4i.egg/
qt4i/settings.py # 依赖Egg包的配置文件
mqlib/
mqtest/
settings.py # 用户配置
当两个配置文件中的配置项存在冲突时,按照以下优先级从高到低处理:
- 用户配置文件
- 依赖Egg包的配置文件
- Testbase配置文件
也就是说,用户配置文件可以重载QTAF配置中的默认配置。
配置文件定位¶
上面提到的三种配置文件,对于存在整个工程的情况来说,就可以直接使用,不需要额外处理。 如果想要独立使用qtaf或其他qta的egg模块,可以采用定义环境变量的方式告诉qtaf配置文件的位置:
QTAF_EXLIB_PATH: 指定qta相关egg包存放的路径,qtaf、qt4s、qt4a等egg都会去这里查找,并加载配置
QTAF_INSTALLED_LIBS: 指定已安装并计划使用的第三方模块(即qtaf除外的),多个模块间用分号隔开,例如:qt4s;qt4a;qt4i
QTAF_SETTINGS_MODULE: 指定用户自定义的配置模块,python在运行时可以找到的模块,支持多级路径,例如:myproject.settings_20160705
警告
特别注意,如果环境变量存在,仅仅使用环境变量指定的内容,例如存在QTAF_INSTALLED_LIBS环境变量,就不会使用exlib目录下的installed_libs.txt中的内容了
使用测试配置¶
配置使用的接口统一使用conf接口,如下:
from testbase.conf import settings
if settings.DEBUG:
print 'debug mode'
else:
print 'release mode'
也可以使用get接口查询配置,比如:
from testbase.conf import settings
my_conf = settings.get('MY_SETTING', None)
警告
settings.py和qtaf_settings.py也是可以直接import使用的,但是不建议这样做,如果这样使用,可能会遇到非预期的结果。
注意settings配置不允许动态修改配置的值,如:
settings.DEBUG = False
会导致异常:
Traceback (most recent call last):
File "D:\workspace\qtaftest\test.py", line 17, in <module>
settings.DEBUG = 9
File "build\bdist.win32\egg\testbase\conf.py", line 85, in __setattr__
RuntimeError: 尝试动态修改配置项"DEBUG"
增加配置项¶
QTA对配置项的新增没有严格的限制,但是为避免冲突,最好按照以下的原则:
- 测试项目自定义的配置,增加一个统一的前缀,比如QQ的测试项目增加前缀“QQ_”
- QTA相关组件的配置项目,除了统一增加前缀外,还需要更新到《配置项说明文档》
自定义settings所在的文件¶
QTA默认是通过加载Python模块`settings`来读取所有配置,用户可以通过设置环境变量`QTAF_SETTINGS_MODULE`来指定配置项所在的模块名。
如果需要切换多套配置文件,可以在根木目创建一个settings pakcage,定义多个配置文件,然后在__init__.py中根据 需要定义个配置项用于加载子模块的配置项:
test_proj/
qt4a/
exlib/
mqlib/
mqtest/
settings/
__init__.py
prod.py #正式环境
test.py #测试环境
比如需要使用正式环境的配置:
$ QTAF_SETTINGS_MODULE=settings.prod python manage.py shell
比如需要使用测试环境的配置:
$ QTAF_SETTINGS_MODULE=settings.test python manage.py shell
使用SettingsMixin¶
SettingsMixin是一个混合类,用于方便地跟用户定义的类进行复合,在定义配置项的时候, 将定义放到lib层,而不是孤立地放在settings.py或配置模块中,再人工进行关联。
定义配置项¶
一个简单的使用例子如下:
from qt4s.service import Channel
from qt4s.conn2 import HttpConn
from testbase.conf import SettingsMixin
class MyChannel(Channel, SettingsMixin):
"""define a pseudo channel
"""
class Settings(object):
MYCHANNEL_URL = "http://www.xxxx.com"
def __init__(self):
self._conn = HttpConn()
def get(self, uri, params):
return self._conn.get(self.settings.MYCHANNEL_URL + uri, params)
MyChannel多重继承了Channel和SettingsMixin,SettingsMixin要求类的内部定义一个Settings类, 这个类定义配置项的规则如下:
- 配置项必须以当前类的名字大写+下划线开头,例如这里的"MYCHANNEL_";
- 配置项的每个字母都必须大写;
- 访问配置项,使用self.settings访问,例如self.settings.MYCHANNEL_URL
重载配置项¶
重载配置项,分为两种情况
派生类重载¶
如果某个SettingsMixin类被继承,那么子类可以访问父类所拥有的配置项,并且可以重载父类的配置项,但是这里重载的方式比较特殊。
因为SettingsMixin要求当前类下必须定义一个嵌套Settings类,并且配置项必须以类名加下划线开头,因此,子类要重载父类的配置项, 通过定义相同后缀的配置项来实现,如下面的DUMMY_A和DUMMYCHILD_A,它们的后缀名都是"A",这样才会生效。
一个具体的例子如下:
from testbase.conf import SettingsMixin
class Dummy(SettingsMixin):
class Settings(object):
DUMMY_A = 0
def print_a(self):
print("DUMMY_A=%s" % self.settings.DUMMY_A)
class DummyChild(Dummy):
class Settings(object):
DUMMYCHILD_A = 2
dummy = Dummy()
assert dummy.settings.DUMMY_A == 0
dummy.print_a()
# DUMMY_A = 0
child = DummyChild()
assert child.settings.DUMMY_A == 2
assert child.settings.DUMMYCHILD_A == 2
child.print_a()
# DUMMY_A = 2
如上,我们看到,在覆盖掉父类的配置项后,在父类的方法中访问的配置项也一样会被重载,这样可以复用父类的一些配置项,并根据需要进行重载。
全局配置项重载¶
SettingsMixin定义的配置项还可以被全局配置项重载,并且全局配置项的优先级最高。我们仍然用上面的Dummy和DummyChild来说明问题。
settings.py:
DUMMYCHILD_A = 3
xxxxcase.py:
dummy = Dummy()
assert dummy.settings.DUMMY_A == 0
dummy.print_a()
# DUMMY_A = 0
child = DummyChild()
assert child.settings.DUMMY_A == 3
assert child.settings.DUMMYCHILD_A == 3
child.print_a()
# DUMMY_A = 3
可以看到,即使子类重载了DUMMY_A的值为2,但是仍然可以在settings.py中已更高的优先级将其修改。
警告
框架在SettingsMixin定义的某个配置项被子类重载后,是不允许再在settings.py中去重载该配置项的, 即:如果我们在settings.py中添加DUMMY_A = 5,框架会提示错误,要求用户去重载DUMMYCHILD_A,而不是DUMMY_A。 这样可以防止使用配置项在派生类之间冲突,并且简化配置项的设置。