【老物】2021软工-个人阅读作业#2

项目 内容
这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健)
这个作业的要求在哪里 个人阅读作业#2
我在这个课程的目标是 和我的团队开发一个真正的软件,一起提升开发与合作的能力
这个作业在哪个具体方面帮助我实现目标 阅读教材提炼所思所惑;初探Git / CI / CD相关工具

一、阅读提问


问A:结对编程总能做到1 + 1 > 2 吗?

教材中第四章出现了结对编程(Pair programming),这是一种变态的代码复审,有别于传统的Code Review。书中强调"复审的目的在于纠错改进与教育更多的开发人员",随后在4.5.3节说到Pair中两人对程序深入了解,复审效果好。但代码复审包括具体代码、效能、设计规范等多方面,Pair中有时间像Code Review一样周全的考虑吗?在传授经验这个方面,Pair中比较多的也是口头交流吧,那么有些经验不就只停留在两人之间了吗?当开发想到一个新idea,为什么不形成书面形式在Code Review中“让更多的成员熟悉项目各部分的代码”?为什么想着不间断地复审而不去花时间提高团队Code Review的效率

在团队中,开发者是人而不是工具,合体之后就一定能1 + 1 > 2吗?书中提到:

极限编程对工程师提出了更高的要求。这种要求不关乎技术水平,也不关乎学历水平或工作经验。这张要求是对一个人的心智、道德修养的更高要求。结对编程中,编码不再是私人的工作,而是一种公开的“表演”。 (4.5.3节-不间断地复审)

Pair对技术力也有要求,不熟悉技术的两人进行Pair只能是一齐学习。文中将Pair的渐进的成长过程比作双人舞的各个阶段,但实际中Pair是否会因为对人的要求太高而停滞在某一阶段,Pair的普适性何如?

4.6节也谈到了合作之道,说到底结对编程还是交流的艺术,能否高效快速解决问题还是得靠实践出真知吧。

问B:代码测试中覆盖率要达到100%吗?

教材在2.1.2节-好的单元测试的标准中有提到:

单元测试应覆盖所测单元的所有代码路径,包括错误处理路径。为了保证代码覆盖率,单元测试必须测试公开的私有的函数/方法

...

要注意:100%的代码覆盖率并不等同于100%的正确性

那我想反过来问:实际中代码覆盖率一定要达到100%吗?从投入产出比的角度考虑,覆盖率达到100%势必要更多地考虑琐碎的问题,覆盖率不错的情况下边际收益岂不是下降了?或者说,实际测试中是不是应该搞双标,仅对更核心的模块代码作更全面的测试覆盖来保证工作效率?更重要的是,100%的代码覆盖率并不说明代码正确,我认为覆盖率是一个基本指标,而不是目标。全覆盖的测试不一定考虑全了外部的问题,比如特殊的输入值,I\O中的File Not Found,这些都是难以发现的隐患,所以测试用例是不是应该从场景出发,更多地考虑程序功能与逻辑上的完备性呢?

问C:敏捷开发?

冲刺到一半的时候,产品负责人突然要马上做重要的改动!或者某个大佬要看某个不在计划中的功能的演示,怎么办?种种情况非常考验Scurm Master

...

也要等到冲刺完了再说啊! (6.2节-敏捷流程的问题和解法)

根据敏捷的价值观,对于执行原定计划更倾向于响应变化,并与客户合作。所以在冲刺中产生新的需求不应是常态嘛。真有重要变化时,为什么不在Scrum Meeting中一齐讨论此改动的重要性和急迫性再考虑进不进行工作上的调整?既然每次新的需求产生时都可能波及到系统中多个模块,或者是现在完全没有考虑的优化方向,那么有时重构不可避免,拖到Sprint结束会不会导致问题积压,错过重构的黄金时间,Sprint中的安排不可改变吗?

敏捷中的产品Backlog到底是什么样的呢?它的主要表现形式为用户故事。

用户故事是描述对用户有价值的功能,一个好的用户故事应该包括角色、功能和商业价值三个要素。

  1. 角色:到底是谁要使用这个功能,这个功能是为谁而设计的?
  2. 功能:这个功能是怎样的,要达到什么程度?
  3. 商业价值:为什么要这个功能,这个功能最后能带来什么有益的商业价值,对用户来说有什么意义?

敏捷还强调个人和交流,这在小团队很奏效,团队规模大了以后难以保证高效的交流。而且相比传统的软件开发模式不重视正式的文档,这在团队工作交接的时候会不会有困难,敏捷开发中怎么将一个项目做大做长远?

问D:写不出好代码的PM是好PM吗?

书中9.4节关于一个PM(Program Manager)的自我修养:

专业能力:PM通常也能写代码,能玩转Excel, PPT, Visio, 甘特图,有文字功力...

既然PM要做其他的那么多事情,那么对TA的代码能力有要求吗,要求多好呢?我认为PM应该做到的是对开发使用的技术路线与架构有个基本的认识,才能更合理地评估某一功能开发的难度,这样可以避免异想天开的设计,也更方便与开发者交流。在这个回答中微软的答主也说到:"虽然理论上程序经理并不必然是程序大拿,但我见过的很多微软的程序经理都是开发转过来的,技术实力并不比同组的开发弱。...很少能看到诸如艺术类专业出身的人做程序经理的情况。"

问E:创新不必是领域内专家,关键不必是技术?

迷思之六:技术的创新是关键

我们在这里看到,除了技术的创新,还有很多方面的创新:商业模式的创新,用户体验的创新,生态系统的创新。

这些迷思基本是以商业价值在衡量创新,如果很多企业都只安于跟上主流技术,一味追求这些模式创新,怎么解决相关市场的同质化问题,有热度一窝蜂来,没热度一窝蜂去?如果都想做后来者,那谁还愿意承担风险当实干者,这对社会的长远发展是好是坏?埃隆·马斯克为什么能成功?

二、调研源代码版本管理软件


1.基于Git的项目管理工具

a) GitHub

Github是现今世界上最大的同性交友网站,兼最火的开放源代码与代码托管社区。被微软收购后,Github已经在去年免费开放了私有库所有功能来对标Gitlab,好耶。Github作为开山者先入为主,用户基数大,社区建设也是最久的,所以要做开源项目的话,它一定是首选啦。后面的代码托管平台基本都有具有Github的基本功能:Fork \ Pull Request \ Follow \ issue之类的。

b) Gitlab

GitLab 是一个基于Git仓库管理系统的开源项目,并在此基础上搭建web服务。GitLab CI/CDGitLab 内置的一款工具,易于实现持续集成,持续交付,持续部署的pipelineGitLab 支持开发团队对其所辖仓库拥有更多的控制,所以从代码的私有性上来看,GitLab 是一个更好的选择。

c) Gitee

Gitee(码云)是国内规模最大的代码托管平台哦。相比于其他平台,Gitee访问速度更快更稳定,不会因为某些神秘的原因登不上去。Gitee在开源仓库方面差不多是在模仿Github,功能齐全。但感觉Gitee比较注重本地化与社区,其目标用户主要是企业或团队,相应的有小队和任务的功能。持续集成方面也有推出正在内测中的Gitee Go

d) Bitbucket

BitBucket 2008 年创建的源代码托管网站,采用 Mercurial Git作为分布式版本控制系统,同时提供免费账户和商业计划。主要面向慈善企业和企业用户/其主要市场是大型企业。

2.总览

工具名 创建时间 使用人数 项目数 私有仓库 适用范围 CI / CD 用户界面 备注
Github 2008 3100w 10000w 免费,无合作人数上限 全球性开源 支持 简明干净,用着最习惯 最大的开源代码平台
Gitlab 2011 3000w 54w 同上 企业、学校等内网Git私服 支持 功能划分清晰 自托管的 Git 项目仓库
Gitee(国内) 2013 600w 1500w 免费,最多5人合作 全球性开源 开发中 相对比较乱 针对国内用户的代码托管方案
Bitbucket 2008 500w ??? 同上 企业/团队Git私服 支持 很干净,喜欢 为专业团队而生,"code, manage, collaborate"

三、调研持续集成/部署工具


1. GitLab

oo2020_pre3_task3为例,仓库在这里,用的是样例中的.gitlab-ci.yml哦,去掉only: tags,不然只有有tag的commit才能触发pipeline

GitlabCI / CD控制台,第一个stage:

第二个stage:

为了获得代码的测试覆盖率使用了maven插件:jacoco-maven-plugin,配置在mvn test执行时自动执行mvn jacoco:report。用Stackoverflow上面的方法,从生成的csv中提取出总代码覆盖率,设置coverage正则表达式

mvn_test:
  stage: test
  dependencies:
    - mvn_build
  script:
    - echo "------Run JUnit4------"
    - mvn clean test
    - awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print covered, "/", instructions, "instructions covered"; print 100*covered/instructions, "% covered" }' target/site/jacoco/jacoco.csv
  coverage: '/\d+.\d+ \% covered/'

再在Gitlab -> project -> Setting -> CI / CD -> General pipelines settings 找到badge.md,就可动态显示coverage了,好耶。

2. Github Actions

Github上使用这个仓库, 配置yaml:

name: my CI test
on: push
jobs:
  job_build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: check
      run: |
        java -version
        javac -version
        mvn -v
    - name: build
      run: |
        mvn compile
...

Github Action里一个.yml对应一个顶级元素workflow,它和Gitlab里的pipeline差不多哦

workflow包含多个job,即不同阶段,用need字段确定执行次序。

每个jobs还分为多个stepstep里才是执行的脚本。这一点很好,在控制台可以看到不同step的输出信息

当然Github Action有不少开源的Action,直接在step里用uses指明Action的仓库名就能直接用了,上文的.yml就用Action安装了Java环境

3. Gitlab vs. Github Actions

CI / CD主要的工作是自动化单元测试、在QA的类生产环境中自动化集成测试,okay就自动部署到生产环境,这对于敏捷开发而言很舒服。对于下一个可交付的版本,不用再去浪费时间人工操作了。在提高开发效率的同时,大家也都能在仓库中了解当前版本的问题。

上面两个工具只是稍微尝试了一下,总的说来Github Actions用的是远程的服务器,跑起来更快;Github Actions具有Github开源的主要特征,有不少Action可供调用,但用起来总不够灵活,Gitlab的脚本结构更清晰,编写起来容易;Gitlab CI / CD功能更全面,有里程碑设置,代码评审和合并请求啥的...