1. 一个小Bug

最近和同事提起一个几年前的 Bug,那是一个很小很小的 Bug,没什么技术含量。那时候我刚入职,正好公司卖了一款仪器到某个国家,但是那边说配套的软件运行不起来,一打开就报错。经过排查发现出错的代码很简单,大致是这样:

public static int GetSecond(DateTime time)
{
return Convert.ToInt32(time.ToString().Split(":")[2]);
}

当时真是哭笑不得。这段代码应该是从旧语言迁移过来,如果只在国内完全没问题,但放到国外就可能报错,因为不同地区和语言会有不同的时间格式,例如加拿大的时间显示格式就不一样,秒的后面还带了表示上午/下午的 a.m/p.m.,这一点可以通过在代码中更改 Thread.CurrentThread.CurrentCulture 来验证:

var time = new DateTime(2000, 1, 20, 1, 2, 3);
Console.WriteLine(time); \\ 输出 2000-01-20 1:02:03
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-CA");
Console.WriteLine(time); \\ 输出 2000-01-20 1:02:03 a.m.

至于测试人员,可以通过将系统设置中的“时间和语言- > 语言&区域”中的区域格式为英语(加拿大)来验证:

可是无论开发人员还是测试人员都没有发现有问题,当时这个离谱的 Bug 就这样插着翅膀,飞越高山和大海,飞到了国外客户的手上。整个团队上上下下由开发到测试都没发现整个 Bug,也许团队在技术和流程上都有问题,让我不得不怀疑我进了个大坑。

吃一堑就要长一智。虽然只是一个小 Bug,但也反映了团队技术和代码流程的欠缺。为了避免再发生这种情况,需要从团队培养及流程改善两个方面着手。团队培养是另一个话题,这篇文章只说说流程改善。当时我们已经在使用 TFS(Azure DevOps 的前身),不过只用于代码管理,很多功能都没有用到。后来 Azure DevOps 不断改善,我们也使用了它更多的功能来帮助我们改进产品质量。这篇文章以文章开头的那个小 Bug 为例,简单讲解 Azure DevOps 处理它的流程。

2. 在 Azure DevOps 上记录并开始处理这个 Bug

首先假设我已经在 Azure DevOps 管理代码,并且配置好 Pipeline 等基础设施,我现在只需要处理这个 Bug。

第一步,添加一个 Bug。除了Bug 的标题,Bug 的详细内容里还可以添加重现步骤、系统信息等,如果有错误日志的话还可以作为附件添加到这个 Bug 里。

当团队理解并同意了这个 Bug 的内容后,在 Boards 中将它从 New 拖动到 Approved,并在 ··· 的下拉菜单中选中 Add TaskAdd Test 分别添加任务和测试用例。

我随意添加了两个任务以及一个测试用例。

3. 在 Visual Studio 中修复 Bug 并添加单元测试

之后轮到团队中负责处理这个 Bug 的开发人员接手工作。打开 VisualStudio 新建分支,修复这个 Bug,并根据单元测试 Arrange、Act、Assert 的方式添加一个对应的单元测试:

[TestMethod]
public void GetSecond_DifferentCultureInfo_Succeed()
{
var time = new DateTime(2000, 1, 20, 1, 2, 3);
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-CA");
var second = DateTimeUtils.GetSecond(time);
Assert.AreEqual(second, time.Second); Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("zh-CN");
second = DateTimeUtils.GetSecond(time);
Assert.AreEqual(second, time.Second);
}

运行单元测试,确保所有单元测试都通过后在 Git 更改 面板提交这个 Bug 的信息,并且输入关联的工作项的 ID,然后点击 全部提交并推送

推送成功后回到代码编辑器,可以看到被修改的函数上的 CodeLens 有一个待变单元测试通过的绿色图标,鼠标放上去可以显示它被哪些单元测试验证过。

在被修改的函数及相关的单元测试的 CodeLens 最右边显示“4个工作项”,鼠标放上去可以看到之前提交代码时关联的工作项。

4. 在 Pull Request 中验收代码

接下来的操作需要回到 Azure DevOps。新的代码不能随随便便就签进去主分支,需要创建一个 PullRequest 通知相关人员这个代码变动,并在这个 Pull Request 里记录关联的工作项,经过修改的代码,需要谁来 Code Review 等。听起来很多,其实提交代码的开发人员只需要点击创建 Pull Request,选择要合并的分支,然后点击创建,其它内容几乎都由 Azure DevOps 自动填充。

Pull Request 最起码需要两道把关,一个是自动运行的单元测试,它需要代码里所有单元测试都运行并且通过。另一个是 Code Review,Azure DevOps 可以设置各种 Code Review 策略,包括最少的 Code Review 人数、当有变更时重置所有审核等。Code Review 除了保证签入的代码质量,还是代码集体所有的一个体现。代码集体所有是敏捷中一个重要的要素,它确保团队中知识的传承,并促进能力的提升。

下图是一个已完成的 Pull Request,可以看到几个绿色的代表通过的图标,代表它通过了多少道“工序”。还可以看到它关联的工作项,由谁创建,由哪个分支合并到哪里等信息。

切换到 Files 选项卡,可以看到具体的代码变更:

5. 测试验证与测试用例

完成上面的步骤后将 Bug 从 Approved 拖动到 Committed,并且将关联的两个 Task 设为完成。代码合并到 master 后 Azure Pipeline 将自动编译并部署好最新的代码,然后通过邮件或 Teams 通知给相关测试人员。测试人员在收到通知后打开 Board,当它看到这个 Bug 的全部 Task 都已经完成(黄色图标旁边的 2/2),他就知道应该开始进行测试验收。完成测试后在测试用例右边的 ··· 下拉菜单中选择测试结果,顺利的话选择 Pass test,并且把这个 Bug 拖到 Done

到这一步 Bug 的处理已经完成。为防止错误再次发生,开发人员添加了单元测试,并且所有相关人员都通过这个流程分享了经验,无论是代码或是团队都变得更加强大。但这还不是结束,这个 Bug 里包含的测试用例是它留下的另一份宝贵财产,需要谨慎对待。打开这个 Bug,可以在右下角 Tested By 部分看到它的测试用例。

点击这个测试用例查看详细信息,可以看到它的 Steps(这里我懒得写),以及各种关联的工作项。

Azure DevOps 提供了 Test Plans 模块,用于管理测试用例和测试计划。在开发过程中产生的各种测试用例最终汇集成测试计划,由测试人员确保曾经正确运行过的功能不会再次出错。不过这部分只开放给收费用户,有机会再详细介绍它的各种功能。

6. 最后

现在公司的代码已经在 Azure DevOps 上安了家,一系列流程都运作得很畅顺(虽然还有很多很多可以改进的地方),尽管软件功能膨胀了几倍但售后反馈的问题反而更少。回过头来看看几年前那个 Bug,当时的代码生产方式和代码质量与现在真的有天壤之别,这其中 Azure DevOps 功不可没。

最后提醒一下,如果想尝试 Azure DevOps 可以不依照我写的流程。这篇文章介绍的流程只是个简化版本,实际工作起来稍微不同,而且应该根据自己团队的实际情况灵活改变,打造属于自己和自己团队的流程(幸好 Azure DevOps 可以做到相当灵活)。

关于 Azure DevOps 的更多内容请参考官方文档:

Azure DevOps documentation _ Microsoft Docs

从一个小Bug,到Azure DevOps的更多相关文章

  1. 关于一个小bug的修正

    python初学者,非常喜欢虫师的文章. 练习时发现一个小bug,http://www.cnblogs.com/fnng/p/3782515.html 验证邮箱格式一题中,第三个x不允许有数字,但是测 ...

  2. iOS开发之使用UICollectionView实现美团App的分类功能【偶现大众点评App的一个小bug】

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下 ...

  3. js动画--一个小bug处理下

    对于上面的课程我们很好的处理了一个小bug,那么我们现在讲程序进行优化一下,前一节的程序中,我们处理处理的属性都是写死了的.为了我们能够很好的对某个属性进行操作的话.我们这样来设置. js文件 win ...

  4. Python2 下 Unicode 的一个小bug

    关于Python的编码问题已经是老生常谈了,此处主要是介绍一个罕见的问题,也算是Python2的一个bug了(Python3不会有此问题). 在有时候我们去爬取网页或者调用一些第三方库获取文本的时候, ...

  5. Cocos2d-JS V3.10 一个小bug提示

    感谢读者古事东流反馈,新版V3.10的音乐播放接口存在一个bug. 重复播放一个音乐,会出现音乐停止的状况. debug了一下,发现src的对比有点问题.传入的url是相对路径,但背景bgMusic. ...

  6. 一个短路求值引起的一个小bug

    今天在写一个判断字符串是否回文时因为短路求值问题导致了一个bug,记录如下: 代码如下 bool isPal(char str[],int len) { int begin=0; int end=le ...

  7. 关于c语言的一个小bug(c专家编程)

    不多说,说了都是累赘!直接看代码吧! #include <stdio.h> int array[] = {23, 34, 12, 17, 204, 99, 16}; #define TOT ...

  8. 关于args的一个小bug

    我在开始学习Java的时候就有点疑惑,到底main方法中的args到底是什么?经过我的一些思考,然后结合代码写一点自己的看法. 下面来看一段代码: /** * @author 薛定谔的猫 * 关于ar ...

  9. 第三方开源动画库EasyAnimation中一个小bug的修复

    看过iOS动画之旅的都知道,其中在最后提到一个作者写的开源动画库EasyAnimation(以下简称EA). EA对CoreAnimation中的view和layer动画做了更高层次的包装和抽象,使得 ...

随机推荐

  1. CF193D Two Segments (线段树+dp)(外加两个扩展题)

    大概算是个系列整理 (最强版是模拟赛原题)) 首先,我们先来看这个题目. QWQ一开始是毫无头绪,除了枚举就是枚举 首先,我们可以枚举一个右端点,然后算一下当前右端点的答案 我们令\(f[l,r]\) ...

  2. FastAPI 学习之路(二)

    之前的文章已经介绍了如何安装,以及简单的使用,这篇文章呢,我们就不去分享如何安装对应的包了. 我们如何去编写呢,其实很简单,按照下面的步骤,一个简单的基于fastapi的接口就编写完毕. 首先:创建一 ...

  3. UE4蓝图AI角色制作(四)之Gameplay调试器

    8. 寻路网格体和Gameplay调试器 为了及时识别出AI系统中的导航问题,UE4提供了一个工具用来解决这类问题,它叫Gameplay调试器.打开项目设置,在左侧找到"引擎",然 ...

  4. 初学python-day5 集合

  5. 【数据结构与算法Python版学习笔记】算法分析

    什么是算法分析 算法是问题解决的通用的分步的指令的聚合 算法分析主要就是从计算资源的消耗的角度来评判和比较算法. 计算资源指标 存储空间或内存 执行时间 影响算法运行时间的其他因素 分为最好.最差和平 ...

  6. VMD可视化hdf5格式的分子坐标文件

    技术背景 VMD是分子动力学模拟领域常用的一款可视化软件,可以非常直观方便的展示分子的运动过程.而VMD本身对展现的格式有一定的要求,如果不是常见的rst等类型的坐标文件的话,就需要自己手动去实现一个 ...

  7. Noip模拟12 2021.7.12

    T1 interval 亏得昨天晚上改掉了T3并且理解了单调栈,今天一扫这题目就知道要用啥了. 先预处理出以a[i]为最大值的最大左右区间.然后再将a[i]取%!!!是的,要不然会影响单调栈的使用.. ...

  8. 两个栈实现队列 牛客网 程序员面试金典 C++ Python

    两个栈实现队列 牛客网 程序员面试金典 C++ Python 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. C++ //run:5ms memeory ...

  9. PicGo+Gitee(码云)中的404错误解决方案

    今天在用PicGo配置Gitee时,出现了404问题,记录一下解决方案. 安装与配置 PicGo默认是不支持Gitee的,只能通过安装插件来进行支持.我这里安装的插件是Gitee. 在图床设置---& ...

  10. AppScan 10安装使用

    一.简介 AppScan是IBM的一款web安全扫描工具,具有利用爬虫技术进行网站安全渗透测试的能力,能够根据网站入口自动摸取网页链接进行安全扫描,提供了扫描.报告和修复建议等功能. appscan有 ...