在单元测试用例中使用 Mock Server API接口服务(Mock Server)已经有了,但是如果每次运行单元测试时都要先在外部手工启动API接口服务的话,做法实在是不够优雅。 推荐的做法是,制作一个ApiServerUnittest基类,在其中添加setUpClass类方法,用于启动API接口服务(Mock Server);添加tearDownClass类方法,用于停止API接口服务。由于setUpClass会在单元测试用例集初始化的时候执行一次,所以可以保证单元测试用例在运行的时候API服务处于可用状态;而tearDownClass会在单元测试用例集执行完毕后运行一次,停止API接口服务,从而避免对下一次启动产生影响。 # test/base.pyimport multiprocessingimport timeimport unittestfrom . import api_serverclass ApiServerUnittest(unittest.TestCase): """ Test case class that sets up an HTTP server which can be used within the tests """ @classmethod def setUpClass(cls): cls.api_server_process = multiprocessing.Process( target=api_server.app.run ) cls.api_server_process.start() time.sleep(0.1) @classmethod def tearDownClass(cls): cls.api_server_process.terminate()这里采用的是多进程的方式(multiprocessing),所以我们的单元测试用例可以和API接口服务(Mock Server)同时运行。除了多进程的方式,我看到locust项目采用的是[color=#069d6 !important]gevent.pywsgi.WSGIServer的方式,不过由于在gevent中要实现异步需要先monkey.patch_all(),感觉比较麻烦,而且还需要引入gevent这么一个第三方依赖库,所以还是决定采用multiprocessing的方式了。至于为什么没有选择多线程模型(threading),是因为线程至不支持显式终止的(terminate),要实现终止服务会比使用multiprocessing更为复杂。 不过需要注意的是,由于启动Server存在一定的耗时,因此在启动完毕后必须要等待一段时间(本例中0.1秒就足够了),否则在执行单元测试用例时,调用的API接口可能还处于不可用状态。 ApiServerUnittest基类就绪后,对于需要用到Mock Server的单元测试用例集,只需要继承ApiServerUnittest即可;其它的写法跟普通的单元测试完全一致。 例如,下例包含一个单元测试用例,测试“创建一个用户,该用户之前不存在”的场景。 # test/test_apiserver.pyimport requestsfrom .base import ApiServerUnittestclass TestApiServer(ApiServerUnittest): def setUp(self): super(TestApiServer, self).setUp() self.host = "http://127.0.0.1:5000" self.api_client = requests.Session() self.clear_users() def tearDown(self): super(TestApiServer, self).tearDown() def test_create_user_not_existed(self): self.clear_users() url = "%s/api/users/%d" % (self.host, 1000) data = { "name": "user1", "password": "123456" } resp = self.api_client.post(url, json=data) self.assertEqual(201, resp.status_code) self.assertEqual(True, resp.json()["success"])为项目添加持续集成构建检查(Travis CI)当我们的项目具有单元测试之后,我们就可以为项目添加持续集成构建检查,从而在每次提交代码至GitHub时都运行测试,确保我们每次提交的代码都是可正常部署及运行的。 要实现这个功能,推荐使用[color=#069d6 !important]Travis CI提供的服务,该服务对于GitHub公有仓库是免费的。要完成配置,操作也很简单,基本上只有三步: - 在[color=#069d6 !important]Travis CI使用GitHub账号授权登录;
- 在[color=#069d6 !important]Travis CI的个人profile页面开启需要持续集成的项目;
- 在Github项目的根目录下添加.travis.yml配置文件。
大多数情况下,.travis.yml配置文件可以很简单,例如[color=#069d6 !important]ApiTestEngine的配置就只有如下几行: sudo: falselanguage: pythonpython: - 2.7 - 3.3 - 3.4 - 3.5 - 3.6install: - pip install -r requirements.txtscript: - python -m unittest discover具体含义不用解释也可以很容易看懂,其中install中包含我们项目的依赖库安装命令,script中包含执行构建测试的命令。 配置完毕后,后续每次提交代码时,GitHub就会调用Travis CI实现构建检查;并且更赞的在于,构建检查可以同时在多个指定的Python版本环境中进行。 下图是某次提交代码时的构建结果。 另外,我们还可以在GitHub项目的README.md中添加一个Status Image,实时显示项目的构建状态,就像下图显示的样子。 配置方式也是很简单,只需要先在Travis CI中获取到项目Status Image的URL地址,然后添加到README.md即可。 写在后面通过本文中的工作,我们就对项目搭建好了测试框架,并实现了持续集成构建检查机制。 |