2.CI(Continuous Integration)——Flask从制作到起飞,零件级颗粒度制造

写在前面的话:
作者是一名终身学习者,横跨环境、教育和IT三个行业。
IT是当前正在精进的行业,作者相信专业精神,崇尚知行合一。
作者以这个系列文章向每一个脚踏实地的web开发者致敬,希望能写出高度实用又有深度的文章帮路上的你清除障碍,欢迎你的指正和技术交流。

1.Test Framework

所有的代码都会出问题,这是编程的基础。以此出发,TDD--test driven development备受推崇,即使做不到,也很少有人会质疑测试的重要性。
一般认为测试从基础到集成分为unit test, integration test, system test, functional test, subcutaneous test。

  • unit test: check a small bit of code, like a function or a class, in isolation of the rest of the system;
  • integration test: check a larger bit of the code, maybe several classes, or a subsystem;
  • system test(end-to-end): check all of the system under test in an environment as close to the end-user environment as possible;
  • functional test: check a single bit of functionality of a system;
  • subcutaneous test: a test that doesn’t run against the final end-user interface, but against an interface just below the surface. (like API layer)

一般developer要负责unit test,QA要负责functional test和subcutaneous test,其他测试根据实际情况分配。

当前很多团队都使用agile开发模式,但很多企业对agile的理解往往有偏差,有时候甚至是外行领导内行。断章取义的只强调功能的快速开发,以为agile相对于传统的waterfall就在于灵活调整需求,快速开发功能。实际上agile没有黑魔法,该做的工作不可能被省略,他的效率主要是通过developer与其他相关人员解耦合来释放工作能力的。
无论什么样的开发,都应该由测试来保障质量,软件工程在这一点上和传统工程不应该有差别。

2.Unit test

确认了测试的重要性,就要针对上一节的代码进行测试。一般认为unit test的工作量是代码编写的2-3倍,在开发估时的时候要做好相应的准备。
tests在逻辑上是和项目代码并列的,所以在根目录创建tests路径,在其中再创建unit tests路径,在unit tests针对index接口写unit test。

- FlaskTemplate
    - tests
        - unit_tests
            - __init__.py
            - test_index.py
        - __init__.py
    - venv
    - .gitignore  # 非git版本管理文件
    - core.py
    - README.md  # 创建git仓库时选择生成的说明文档

接着安装测试工具pytest

$ pip install pytest

编写unit test代码

# -*- coding: utf8 -*-

# 引入待测试的代码
from core import index


def test_index_success():
    """
    test index, response successfully
    :return:
    """
    response = index()  # response接受index()的返回结果
    assert response == "<h1>This is an index page.<h1/>"  # 测试返回内容与预期返回内容相等

运行单元测试

$  pytest tests/unit_tests/test_index.py
============================ test session starts =============================
platform darwin -- Python 3.6.4, pytest-4.0.2, py-1.7.0, pluggy-0.8.0
rootdir: /Users/hongfu/Work/Computer_science/FlaskTemplate, inifile:
collected 1 item                                                             

tests/unit_tests/test_index.py .                                       [100%]

========================== 1 passed in 0.24 seconds ==========================

3.Test Coverage

往往单元测试并不能完美覆盖,一方面是开发和测试的不同步造成的,另一方面有时也要放弃较安全代码的测试以换取更快的开发迭代,这时需要用测试覆盖率来反应代码测试的情况。
安装测试覆盖率工具coverage,pytest-cov

$ pip install coverage
$ pip install pytest-cov

将core.py放入根路径server中,以更好的管理项目结构

- FlaskTemplate
    - server
        - __init__.py
        - core.py
    - tests
        - unit_tests
            - __init__.py
            - test_index.py
        - __init__.py
    - venv
    - .gitignore  # 非git版本管理文件
    - README.md  # 创建git仓库时选择生成的说明文档

运行测试覆盖率

$ pytest --cov=server  # 用pytest测试server的代码覆盖率
========================================================================== test session starts ===========================================================================
platform darwin -- Python 3.6.4, pytest-4.0.2, py-1.7.0, pluggy-0.8.0
rootdir: /Users/hongfu/Work/Computer_science/FlaskTemplate, inifile:
plugins: cov-2.6.0
collected 1 item                                                                                                                                                         

tests/unit_tests/test_index.py .                                                                                                                                   [100%]

---------- coverage: platform darwin, python 3.6.4-final-0 -----------
Name                 Stmts   Miss  Cover
----------------------------------------
server/__init__.py       0      0   100%
server/core.py           6      1    83%
----------------------------------------
TOTAL                    6      1    83%


======================================================================== 1 passed in 0.33 seconds ========================================================================

4.Circle CI

后续的开发虽然会更加复杂,但底层逻辑和流程和这两节的过程是一致的:功能开发-unit test开发-test coverage报告。
在团队开发中,为了提高效率,往往使用自动化测试来提交代码,保证代码质量,降低代码审核的压力。所以CI(continuous integration)被大家普遍接受。
该项目在github上,其他平台的项目也同样可以使用CI管理。github的CI工具包括Hound, WIP, CircleCI等。

image

这里使用免费的CircleCI,在根路径创建.circleci路径并在其中创建config.yml

- FlaskTemplate
    - .circleci
        - config.yml
    - server
        - __init__.py
        - core.py
    - tests
        - unit_tests
            - __init__.py
            - test_index.py
        - __init__.py
    - venv
    - .gitignore  # 非git版本管理文件
    - README.md  # 创建git仓库时选择生成的说明文档
version: 2
jobs:
  build:
    docker:
      - image: circleci/python:3.6
    steps:
      - checkout
      - restore_cache:
          key: deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}
      - run:
          command: |
            python3 -m venv venv
            . venv/bin/activate
            pip install -r requirements.txt
      - save_cache:
          key: deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}
          paths:
            - "venv"
      - run:
          name: Running tests
          command: |
            . venv/bin/activate
            pytest --cov=server
      - store_artifacts:
          path: test-reports/
          destination: python_app

生成安装文件列表

$ pip freeze > requirements.txt

将相应代码提交到github,然后在circleCI使用github账号注册一个账号,选择ADD PROJECTS,在项目列表中选择FlaskTemplate,并点击SetupProject。

image

因为已经配置好circleCi,所跳过中间4步,直接点击Start Building,CI连接成功并测试通过。
image

5.CircleCI Test

接下来修改README,测试配置是否生效。

$ git checkout -b readme  # 切换到新的reademe分支

修改readme文件

# FlaskTemplate

CI is applied using CircleCI.

提交readme分支

$ git add .
$ git commit -m "update readme"
$ git push origin readme

接着在github上提交一个pull request,点击下图右下角的compare & pull request。


image

然后通过pull request。


image

再检查circleCI,发现两条新的检查,一条是readme的检查,另一条是merge到master的检查。
image

至此,CI配置成功。

相关链接
1.初始化——Flask从制作到起飞,零件级颗粒度制造

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容