我们的开发团队一直在使用Gitflow分支策略,它非常棒!
最近我们招募了几个测试人员来提高我们的软件质量。其想法是每个特性都应该由测试人员进行测试/QA。
在过去,开发人员在单独的特性分支上处理特性,并在完成后将它们合并回develop分支。开发人员将在该feature分支上测试自己的工作。现在有了测试人员,我们开始问这个问题
On which branch should the tester test new features ?
号
显然,有两种选择:
开发分公司测试
最初,我们认为这是必经之路,因为:
- 自开发开始以来,该特性将与合并到develop分支的所有其他特性一起进行测试。
- 任何冲突都可以早于稍后检测到
- 这使得测试人员的工作变得简单,他每次只处理一个分支(develop)。他不需要向开发人员询问哪个分支是针对哪个功能的(功能分支是由相关开发人员专门自由管理的个人分支)
最大的问题是:
特征分支测试
因此,我们再次思考并决定应该在特性分支上测试特性。在测试之前,我们将develop分支的更改合并到功能分支(赶上develop分支)。这很好:
- 您仍然使用主流中的其他功能测试该功能
- 进一步的开发(如缺陷修复、解决冲突)不会污染develop分支机构;
- 您可以很容易地决定在完全测试和批准该特性之前不释放它;
但是,也有一些缺点
- 测试人员必须合并代码,如果有任何冲突(很可能),他必须向开发人员寻求帮助。我们的测试人员专门从事测试,不能编码。
- 一个特性可以在不存在另一个新特性的情况下进行测试。例如,功能A和B同时在测试中,这两个功能彼此不知道,因为它们都没有合并到develop分支。这意味着,当两个特性无论如何都合并到开发分支时,您必须再次对develop分支进行测试。你必须记住在将来测试这个。
- 如果特性A和特性B都经过了测试和批准,但是在合并后发现了冲突,那么这两个特性的开发人员都认为这不是他自己的错误/工作,因为他的特性分支通过了测试。在沟通上有额外的开销,有时解决冲突的人会感到沮丧。
上面是我们的故事。由于资源有限,我希望避免在任何地方测试任何东西。我们仍在寻找更好的方法来解决这个问题。我很想听听其他团队是如何处理这种情况的。
- 这个问题似乎更适合程序员,因为它不处理编程问题,而是一个开发过程。有人能迁移吗?
- 兴高采烈的问题:Git流应该如何与QA一起测试发布和新特性?
- 我们的模型完全一样。我感兴趣的是,您的QA团队如何不同于现场问题或UAT过程中的问题(如果您有)报告功能分支上的问题。我们使用Atlassian Jira,并为这两者提供了不同的工作流程。
- 现在就做同样的决定。另外,由于我们的环境是Java Spring应用程序,所以需要花费大约20分钟来构建和部署测试环境。很高兴有人问我同样的疑问。
- 第一个缺点不是特性分支测试过程固有的。像Github Enterprise和BitBucket这样的工具能够要求对请求进行批准,并且负责QA的人员可以批准向开发人员发出信号,表明他们可以自由地合并到开发中。
- 我要补充的一点是:1)要么要求测试人员将特性部署到本地盒中,要么使用CI将特性部署到共享的QA环境中。2)功能通常是渐进的(例如,故事1添加了支持基础设施的功能X,故事2基于故事1的基础设施添加了功能Y)。只允许合并已完成的功能来开发意味着您要么无法压缩功能提交(垃圾提交多于功能错误修复原因),要么在完成第1个故事之前无法启动第2个故事。
- 有意思的是,有些问题虽然是关于编程和编程语言的,但却因为表面上的宽泛而被封闭了,而这类问题在这里是可以接受的。
我们的方法如下:
在合并最新开发的分支代码之后,我们对特性分支进行测试。主要原因是我们不希望在接受某个特性之前"污染"开发分支代码。如果一个特性在测试后不能被接受,但是我们想发布其他已经在开发中合并的特性,那将是地狱。开发是发布的一个分支,因此最好处于可发布状态。长版本是我们在许多阶段进行测试。更具分析性的是:
开发人员为每个新功能创建一个功能分支。
特性分支(自动)部署在我们的测试环境中,每次提交都需要开发人员进行测试。
当开发人员完成部署并准备好测试特性时,他合并特性分支上的开发分支,并部署包含测试中所有最新开发更改的特性分支。
测试人员测试。完成后,他会"接受"故事,并在开发中合并功能分支。由于开发人员先前已经合并了功能上的开发分支,所以我们通常不希望出现太多冲突。但是,如果是这种情况,开发人员可以提供帮助。这是一个棘手的步骤,我认为避免它的最好方法是尽可能地保持特性的小/具体。不同的功能最终必须以某种方式合并。当然,团队的规模在这一步骤的复杂性中扮演了一个角色。
开发分支也(自动)部署在测试中。我们有一个策略,即使功能分支构建可能失败,开发分支也不应该失败。
一旦我们达到了特性冻结,我们就从开发中创建一个发布。这将自动部署在转移上。在部署生产之前,在那里进行了大量的端到端测试。(好吧,也许我夸大了一点,他们不是很广泛,但我认为他们应该是)。理想情况下,测试人员/同事,即真正的用户应该在那里进行测试。
你觉得这种方法怎么样?
- 我们如何确保独立测试的特性1和特性2也能很好地结合在一起(如问题中所述)?
- 我们间接地通过合并一个然后另一个来发展。这是上述过程的第4步,与时间顺序有关。因此,如果功能2准备好合并,但功能1已经合并,那么功能2开发人员和测试人员必须确保它们的合并可以工作。
- 我认为无论如何,根据这个git分支模型,不应该将两个特性分支合并在一起。
- 我们在步骤6中遇到了一些问题,特别是在关键时刻,多个特性被转移到开发中,因为在QA签署了特性分支之后发生了一些非常重要的合并,尽管尽可能晚地将devlop合并到特性中。我在这里更详细地评论了一下:stackoverflow.com/a/25247382/411282
- @乔舒戈德伯格,我知道你的意思,并同意这是最棘手的部分。我能想到的一种降低复杂性的方法是创建常规的小版本,只有很少甚至只有一个特性。或者不接触代码相同部分的功能。无论如何,在它投入生产之前,应该对整个版本进行彻底的测试。
- 对于每个功能分支,您是否有一个完整的测试环境(DB、服务器、客户机等)?或者他们共享环境,只是有不同的名称(例如app-name_feature1-app-name_feature2等)
- @hinnelinks一个环境应该足够,并且一次测试一个功能分支。
- 所以这个模型仍然不允许在每次开发合并之后不必重新测试的情况下对特性进行并发测试?
- 由于我们促进构建(我们在每个env上使用相同的构建来在生产前进行测试),这种方法对我们来说并不适用。
- 如何保持E2E测试的更新?您只是在特性到达测试环境时创建它们吗?或者开发人员是否合并了E2E测试?这是假设已经定义并合并了自动化单元测试。您的签准是否需要自动E2E测试?
- @Oletha不知道你怎么知道,在重新平衡开发之前,每一次都是有效的。但如果你知道我有多好奇的话!
- @我会把它们当作所有其他测试,但这取决于您的特定设置:谁编写这些测试?它们是在同一回购协议上吗?它们是持续集成的一部分吗?
- @Aspasia如果您将/Rebase Development合并到您的功能分支中,那么在将该功能分支合并到它中之后,它将处于与Development相同的状态。:)当然,这并不理想,因为在您准备合并之前,开发可能会发生更改…
- @Oletha我在上面就是这么建议的,我更喜欢rebase。但是,如果在平均时间内发生变化,这可能是个问题。对于一个小团队来说,它是有效的。
- @Aspasia是的,令人恼火的是,测试是在不同的回购中进行的,我们有一个角色负责编写测试。当然,我们必须与它们进行良好的通信,但有时,根据自动测试的特性有多复杂,我们首先进行手动测试,然后循环返回以自动测试用例。我只是好奇你是否有不同的过程。
- 什么时候执行拉请求(即代码审查)?
- @格伦托马斯,这是一个相当古老的职位。pr/代码评审将在步骤4中进行,以便合并要开发的功能分支。
- @Aspasia所以测试人员正在为他们没有编写的代码创建一个pr?
- @格伦托马斯对不起,我的意思是3。因此,开发人员在特性分支上重新进行开发,然后在测试中部署。测试人员是否也会检查代码,这取决于测试人员是否也是开发人员。在任何情况下,当测试和审查完成并对未来的分支进行修复时,可以合并PR来开发。
- 如果在将特性分支合并到开发分支之后出现bug,会发生什么?这个bug应该在新的特性分支中修复还是在开发分支中修复?
- @我的观点是,如果分支已经被合并为master,它应该被视为master上的修补程序。如果不是的话,很可能与其中一个期货有关,最好是固定在那里。请在这里查看nvie.com/posts/a-successful-git-branching-model
- @Aspasia有一件事我不明白,当我们从功能分支发布测试时。我们不需要多个测试环境吗?事实上,我们需要的测试环境和目前开发的功能一样多吗?
- @我认为这完全取决于团队。例如,如果每个5-6人的团队有一个测试环境,那么很容易协调和测试一个特性。因为功能一旦完成就独立了,所以部署下一个功能。如果团队经常发布和测试,那么就需要更多的测试环境,或者可能需要虚拟/云即兴环境。
Before test, we merge the changes from the develop branch to the feature branch
号
不,不要,特别是如果我们是质量保证测试人员。合并将涉及到解决潜在的冲突,这最好由开发人员(他们知道他们的代码)完成,而不是由QA测试人员(他们应该尽快进行测试)。
使开发人员在devel上对自己的feature分支进行重新组合,推送feature分支(开发人员已验证该分支是在最新devel分支状态的基础上编译和工作的)。允许:
- 功能分支上的一个非常简单的集成(简单的快进合并)。
- 或者,按照下面Aspasia在评论中的建议,拉请求(Github)或合并请求(Gitlab):维护人员在功能pr/mr分支和develop之间进行合并,但前提是Github/Gitlab检测不到冲突。
每当测试人员检测到bug时,他/她都会向开发人员报告并删除当前的特性分支。开发者可以:
- 修复错误
- 在最近获取的开发分支上重新设置基片(再次确认,以确保他/她的代码与其他已验证的特性集成在一起)
- 推动feature分支。
总体思路:确保合并/集成部分由开发人员完成,而测试则留给QA。
- 你是说"不要使用合并,而是使用REBASE"?如果是这样的话,我很困惑,给出了关于这两者之间区别的git常见问题解答:git.wiki.kernel.org/index.php/…
- @Vickilaidler是的,如果特性分支被QA拒绝,开发人员必须重新设置基片,而不是合并(stackoverflow.com/a/804178/6309)
- @哇,我很惊讶没有其他人在摸索这个。你所推荐的显然是正确的方法。我甚至会这么说,只要特性分支是在一个稳定点开始的,并且不太落后,就不需要每次都重新进行平衡。但是如果我们坚持要将特性分支与开发同步,那么绝对要重新平衡,不要合并。Junio Hamano对本文的评论很好地解释了这一点:kentnguyen.com/development/visualized git-practices for team‌&8203;/…
- @我同意。我使用这种工作流程(本地重新设置,然后推送),因为它是由大多数其他现代工具强制执行的:我现在使用的是rtc(Rational ream concert:jazz.net/products/Rational team concert),它具有相同的工作流程。几年前,我在stackoverflow.com/a/457988/6309和stackoverflow.com/a/804178/6309中描述了Git One。
- @VONC我完全同意,但有一些问题:1)删除分支会影响其他工具,如stash pull请求(删除分支会关闭PR)。更喜欢用力推。2)如果它是一个大的功能分支,在它的一生中有两个人合作,那么合并将比再平衡更受欢迎。当合并提交将被删除时,在末尾重新设置它的值会造成冲突噩梦,如果代码依赖于这些合并更改,那么修复它是非常重要的
- @void.pointer我同意此工作流不适合所有情况。我之前提到过强制推(stackoverflow.com/a/26753583/6309)。
- 回首我的答案,我也会做一个重新平衡,而不是一个更干净的历史合并。
- "不,不要这样做,特别是如果‘我们’是质量保证测试人员。"没有提供任何理由,因此此审查没有用处。
- @史蒂文哈里森:我已经加上了原因(在这个答案的最后一句重复)
- "总体思路:确保合并/集成部分由开发人员完成,将测试留给QA。"这不是"在测试之前,我们(QA测试人员)将从开发分支到功能分支的更改合并"的原因。"
- 重新平衡只能用于私人开发人员历史记录(即尚未与其他开发人员共享的历史记录或其他开发人员正在处理的历史记录)。对于所有环境,这可能并不总是明智的。
- @VONC对于您的第一点,功能分支已经在开发的基础上重新调整,不期望出现合并冲突。当然,这一切都取决于团队的设置。我们的QA也是开发人员。
- @Aspasia如果特性分支已经在Development之上重新进行了调整,那么您就不会将DevelopToFeature合并。
- @很抱歉,我的意思是相反的。很明显,我想你知道我的意思,在创建pr之前,开发人员有责任在特性分支的基础上重新平衡开发。
- @Aspasia奇怪:再平衡发展会改变它的历史,这是不现实的…
- @噢,困惑。我通常的工作方式是:像:git-rebase-i开发一样重新设置特性分支的基,决定我保存的消息是哪个提交的,然后创建一个请求。如果进展顺利,我们将合并公关。
- @Aspasia好吧,这次我明白了;)一个git rebase -i develop不是"再平衡develop",而是"再平衡(当前分支)在develop之上"。如果当前的分支是feature,那是有道理的!
- @我知道,当你在其他东西之间快速打字的时候就会发生这种情况。因此,要回复您的"如果功能分支已经在开发之上重新设置了基准,那么您不会将开发合并为功能。":不,但您确实合并了PR。
- @Aspasia是在Feature和Development之间完成的公关吗?如:"我将从特性应用到开发"?
- @VONC是功能和开发之间的。在GitHub中称为"合并拉请求"。你为什么问这个问题?
- @Aspasia只是为了确保我在回答中需要修改的内容:它仍然是一个从功能到主功能的合并,但并不像我描述的那样是一个快速前进的合并:相反,是一个被接受/合并的请求。
- @vonc是的,我所说的是合并一个pr。但是,如果在合并pr之前对其进行了重新平衡,那么在后台执行完全相同的操作,就像这里描述的一样,快速前进帮助。github.com/articles/about pull-request-merges/…。就我个人而言,我喜欢PRS有几个原因。其中之一是它们可以很好地连接到GitHub问题,并在合并时自动关闭它们。其他原因是,这些描述对于审阅者理解已经完成的工作和需要检查的内容非常有用,并且如果需要,它们很容易还原。
- @Aspasia的优点。我在答案中加入了拉取请求,以提高可见性。
- @VONC"每次测试人员检测到错误时,他/她都会向开发人员报告并删除当前的功能分支。"删除当前功能分支的意义是什么?
- @文内古恩只是确保分行不会被错误地合并。(我想这是我5年前的打算)
最好的方法是持续集成,一般的想法是尽可能频繁地将特性分支合并到开发人员分支中。这减少了合并痛苦的开销。
尽可能地依赖自动化测试,并让构建自动从Jenkins的单元测试开始。让开发人员完成所有工作,将他们的更改合并到主分支中,并为他们的所有代码提供单元测试。
测试人员/QA可以参与代码评审、检查单元测试并编写自动化集成测试,在完成特性后将其添加到回归套件中。
有关详细信息,请查看此链接。
- +1.介绍CI,谢谢。
- 您仍然可以使用分支+在Git中重新平衡来进行CI。
我们使用所谓的"金"、"银"和"铜"。这可以称为prod、staging和qa。
我来把这个叫做熔炉模型。它对我们来说很好,因为我们在业务方面对QA有着巨大的需求,因为与技术方面相比,需求可能很难理解。
当一个bug或特性准备好进行测试时,它将进入"青铜"状态。这会触发一个Jenkins构建,将代码推送到预构建环境中。我们的测试人员(不是超级技术人员)只是点击了一个链接,并不关心源代码管理。这个构建还运行测试等。如果测试(单元、集成、Selenium)失败,那么我们在这个构建上来回地将代码推送到testingqa环境中。如果您在一个单独的系统上进行测试(我们称之为Lead),您可以防止将更改推送到您的QA环境中。
最初的担心是我们在这些特性之间会有很多冲突。如果功能X让它看起来像是功能Y正在崩溃,那么它确实会发生,但它的出现频率不够,实际上是有帮助的。它有助于在似乎是变化背景的情况下进行广泛的测试。很多时候,幸运的话,你会发现你的改变是如何影响并行开发的。
一旦一个特性通过了QA,我们就把它转移到"银色"或阶段。将运行生成并再次运行测试。每周我们将这些更改推送到我们的"黄金"或生产树,然后将它们部署到我们的生产系统中。
开发人员从金树开始他们的更改。从技术上讲,你可以从舞台开始,因为这些很快就会出现。
紧急情况的解决办法被直接投进了金树。如果一个变更是简单的并且很难QA,那么它可以直接进入Silver,这将找到它通向测试树的方法。
在我们发布之后,我们将黄金(prod)中的变化推到青铜(testing)中,只是为了保持一切同步。
您可能希望在推入临时文件夹之前重新设置基片。我们发现,不时地清除测试树可以保持它的清洁。有时特性会被抛弃在测试树中,特别是当开发人员离开时。
对于大型的多开发人员功能,我们创建了一个单独的共享回购,但在准备就绪时将其合并到测试树中。事情往往会从QA中反弹,所以保持变更集的隔离非常重要,这样您就可以添加变更集,然后将其合并/挤压到您的登台树中。
"烘焙"也是一个很好的副作用。如果你有一些根本性的改变,你想让它坐一会儿,这是一个很好的地方。
还要记住,我们不维护以前的版本。当前版本始终是唯一的版本。即使这样,您也可能拥有一个主烘焙树,您的测试人员或社区可以在这里大摇大摆地看到各种贡献者的东西是如何交互的。
我不会单独依靠手工测试。我将使用Jenkins自动测试每个特性分支。我设置了一个vmware实验室,在所有浏览器的Linux和Windows上运行Jenkins测试。它确实是一个很棒的跨浏览器、跨平台测试解决方案。我测试功能/与Selenium WebDriver的集成。我的硒测试是在RSPEC下进行的。我特意写了它们,让JRuby在Windows上加载。我在rspec下运行传统的单元测试,在jasmine下运行javascript测试。我用幻影JS设置无头测试。