美文网首页Python
2.CI(Continuous Integration)——Fl

2.CI(Continuous Integration)——Fl

作者: Sisyphus235 | 来源:发表于2018-12-24 23:42 被阅读0次

    写在前面的话:
    作者是一名终身学习者,横跨环境、教育和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从制作到起飞,零件级颗粒度制造

    相关文章

      网友评论

        本文标题:2.CI(Continuous Integration)——Fl

        本文链接:https://www.haomeiwen.com/subject/pmztlqtx.html