作為創業公司很重要的一個環節就是在有限的時間和資源下把產品需求落地為產品,也就是研發和項目管理,毫無疑問,這個階段的主角是開發人員,那作為一個PM,把做項目管理的過程也當成做產品的過程的話,是不是應該多思考下怎麼面向開發人員來優化整個研發過程和項目管理流程。本文就是我們如何通過優化開發環境搭建,代碼管理,需求生命周期管理,開發任務分配和追蹤,項目整體進度管理來提高研發過程中開發人員效率,通過持續集成和交付讓開發中的問題更早暴露,通過合理的測試反饋工具讓開發人員最快定位和解決問題。

一點前提條件和背景

印象中很多關於產品和開發為了進度撕逼的段子,其實作為一個開發轉的產品,對這兩塊都有所了解,就我的看法是研發效率不止是研發人員本身的技術能力和工作效率,而是整個研發過程和項目管理流程的效率,但我自己理解的高效的研發和項目管理有兩個前提:

  • 公司內各團隊有個大家認同的溝通協作方式:因為所有的流程和工具都是為人所用的,只有團隊有主動性去溝通協作才能提高效率,這也是我這個系列第一篇寫“異地創業團隊如何做團隊溝通協作”的原因。
  • 盡量清晰的需求定義:產品經理的任務就是讓研發團隊開發正確的任務,我所碰到的開發延期或者交付失敗很多時候就是由於自己對需求的認識不夠,開發中過多需求的變更造成的,一個表達清楚,考慮完善的需求定義才能保證下面的研發和管理是不是在做無用功,所以本系列的第二篇是“聊聊針對異地團隊的需求協作和原型、設計的評審”

說到創業團隊的研發和項目管理的實踐,就逃不開先要說一下我們研發和項目管理中的工具作為背景:

  • 即時交流和協作:Slack,這個我在“異地創業團隊如何做團隊溝通協作”里重點談到過,鑒於它的開放性,已經基本連接了我們用到的文件管理,設計評審,持續集成,測試分發,Bug Report等一系列工具。
  • 代碼管理:Git+Gitlab,在VPN環境內自己搭建Git和Gitlab一定程度上保證了代碼的安全性,不過維護和備份都是個會耗費精力的問題,對沒有專業運維的創業團隊推薦直接Github託管。
  • 項目管理:Redmine,老實說Redmine一直都不是項目管理上的最佳方案,專業級的有JIRA,輕量的有Asana、Tower等很多,我們就是已經習慣了,有一套Githooks在上面,並沒有什麼動力去換。
  • 持續集成:Jenkins,雖然Java的坑也很大,維護起來也不時被坑,不過功能和插件確實齊全,搭起來也不易,有興趣的可以嘗試Travis CI或者Gitlab CI。

最後切入正題了,本篇涵蓋的是我們在研發過程和項目管理流程,以及當中在DevOps上做的一些努力去優化開發人員的體驗,就試着從各個環節總結一下,因為不同團隊的研發流程和項目管理都不一樣,各位看官可以挑有興趣的來看:

  • 研發環境的搭建:包括如何kick off新開發者,如何搭建日常開發環境
  • 代碼的管理:包括源碼管理,Code Review和組織公共庫
  • 需求在研發中的生命周期管理:包括功能需求清單,功能需求定義和其中的開發任務項分配和狀態管理
  • 項目進度的管理:包括如何通過Redmine有效的執行敏捷開發
  • 研發階段的產品測試和反饋:包括在產品測試和反饋中的一些經驗和工具分享
  • 持續集成和持續發布:包括如何針對Web, Android和iOS分別搭建持續集成和發布

一、研發環境的搭建

如何讓團隊新的開發者儘快上手

對新的開發人員,一般都會有開賬號,裝系統,配環境,跑代碼這些過程,我自己發現每次都低估這些工作的耗時,以前就發現有時候不小心就一两天過去了還沒跑起來代碼,一兩周還沒搞清楚目前產品的功能,我總結了兩點加快這個進度的方法:

1.加快能讓代碼跑起來的速度

有很多可以加速的環節,一個比較重要的就是自動構建代碼,就是指開發人員checkout代碼后通過簡單的構建腳本就能完成代碼依賴安裝,代碼編譯,單元測試運行,也就是我們常說的跑起來。以Web為例,可以通過npm的腳本完成npm依賴的安裝,然後用gulp完成代碼的構建和運行,這也是持續集成的基礎。

2.對產品功能需求和目前進度的了解

在背景的里說的保持一個盡量清晰的需求定義的一個用途就在這,新的開發人員可以通過瀏覽產品的需求文檔來了解產品功能,我們的做法是在Redmine上把“系統功能匯總(含已排期未完成功能)”作為一個Custom Query,將所有功能的PRD列出來,有兩種視圖可以選擇,一個就是下圖這樣按照產品線,能看到每個產品線的功能:

另一個視圖就是按照功能完成的時間來歸類,可以知道以前每個版本都做了什麼功能,未來有什麼功能正在排期中:

如何方便開發人員進行日常開發調試

目前對於Web開發來說,一般構建的過程中代碼都會進行混淆、合併、CDN地址替換、CSS Sprite生成等等操作,造成在Dev服務器上調試很不方便,我們採取的解決方法是在web的Gulp構建流程中分不同的Build Target,本地調試使用未混淆的代碼加本地搭建的Python環境,連接Dev數據庫,方便Web開發人員本地調試。

二、代碼管理

首先最重要的就是代碼必須用源碼管理工具,我們一直用的Git。代碼的查看和管理都在Gitlab上,可以查看代碼,code review,合併分支,打版本tag之類的,不過Gitlab對開發者不是必須要用的,所有這些操作都能用git command解決的事情,有兩點我覺得需要關注的:

1.怎麼讓開發人員高效的使用第三方庫

項目開發的過程中去抽象公共組件,使用第三方庫或開發工具都可以提高開發效率,但需要做好模塊和版本管理,有時候碰到一個開發人員引入了一個不合理的依賴,或者學習成本陡峭的組件,每個參与開發人員都要增加學習成本。這個一般都是根據不同的技術棧有相應的一套工具可以使用,我們自己在Web、Python、iOS、Android上面都有自己習慣的選擇,需要加新的組件或者替換正在使用的都可以一起討論之後加入,以免發生重複或者後期的分歧。我們主要考慮的點有下面這些。

2.如何做新功能開發的代碼管理

只要多人開發,而且多功能并行開發都避免不了要考慮如何管理代碼,一般有Feature Toggle和Git Branching兩種,目前我們根據自己的需求定義了一個Git brancing model,對於複雜的新功能建立feature branch來開發:

雖然我個人更喜歡Feature Toggle的方式,不過實踐起來需要的模板開發和構建方式上的配合,不如Git Branching對開發來說上手更簡單一些,暫時就沒有更換,建議看一下Baidu FEX的<<Feature Flag 功能發布控制>>去考慮自己適合哪一種。

三、需求在研發中的生命周期管理

對於開發人員來說,開發工作一般是圍繞着具體的功能需求進行的,而背景中提到過的“清晰的需求定義”就是研發的主要輸入,由負責的PM來主導需求(User Story)的狀態更新,本節以一個功能需求(User Story)為例,先上一個時序圖來說明單個功能在研發中的生命周期是什麼樣的:

從功能需求(User Story)的時間線上可以看出來其分為下面幾個狀態:

PM創建后協作編寫需求文檔(New) -> 需求確認(Confirmed) -> 開發中(In Progress) -> 待測試(Wait
for test) -> 已完成,可以上線(Finished) -> 完成,可以關閉(Closed)

可以劃分為需求確認,需求開發,需求測試和上線三個階段:

1. 需求確認

對於需求文檔的編寫和確認,不同團隊方式不一樣,我在前一篇《“聊聊針對異地團隊的需求協作和原型、設計的評審”》聊了如何通過怎麼協作完成清晰的需求定義,我的理解是包括功能需求的前置條件和後置條件,用戶流程和規則,完整的產品交互原型,評審確認的設計稿。下圖為在Redmine上定義的一個功能需求(User Story)

2. 需求開發

在需求定義清晰后,開發前需要整個開發團隊的參与確認任務的分配。任務分配的原則就是將功能需求對應的任務按樹形結構分解,敏捷開發里的學名就是“Work Breakdown Structure (WBS)”,保證其中每個任務都是可以開發,並且是可以測試的。下圖就是一個功能需求對應的任務的實例:

具體到其中一個單獨的任務項(Task),裏面會有它所屬的功能需求(User Story),當前的狀態,優先級,任務指派的開發者,任務所屬的產品線(Web, iOS, android…),一個簡單的任務描述的,所屬的milestone,預計開發時間和結束時間,任務當前的狀態和進度等等。如下圖所給的就是一個Task的實例:

從上文中“需求在研發中的生命周期”的時序圖上可以看出其對應的任務的生命周期是如何管理的,包括前端和後台之間的任務協作是如何完成的,簡單來總結的話Task有下面幾種狀態:

新建 -> 開發中 -> 待代碼複查(目前僅junior developer需要被code review) -> 待測試 -> 反饋 -> 完成(可以上線) -> 關閉(上線以後可以關閉)

開發人員主要負責的就是開發的同時更新自己任務的狀態,看起來狀態蠻多,如果開發需要每次登錄redmine來改也確實蠻累,在實踐的過程中我們引入了一下優化的方法:

為Redmine自定義一些Git hooks來更新狀態。通過自定義git提交語法,讓Git提交能自動更新在Redmine相應的issue上,既節省了更新狀態的時間,又能保持一個乾淨的git logs。下面是我們定義的Git提交語法:

[component] Abc: (Issue #Id) + Message (Issue Status)

  • [component] 就是任務所屬的模塊,比如[ios], [android], [backend], [web],這和Jenkins的Build Job綁定,當有相應模塊的代碼提交就會觸發相應部分的持續集成和交付。
  • Abc 就是操作的Action是什麼,比如Add, Mod(ify), Ref(actoring), Fix, Rem(ove) and Rea(dability),用來讓代碼提交信息的目的看起來比較清晰。
  • (Issue #Id) 就是對應的Task的Id是什麼,為了將changelog和task綁定在一起。提交以後就會自動更新Redmine的Task:

Server端接口文檔自動生成。在需求定義里可以將規則和邏輯寫的很清楚,但在前端和服務端協作開發的過程中,如果服務端沒有文檔可能會經常被前端打斷,詢問接口具體參數的名稱或參數類型,也是比較煩的事情,可以考慮用Documentation Generator在代碼中添加註釋來自動生成文檔,我們使用的“Sphinx”作為Python的文檔生成工具,用Python的推薦使用。

開發中的持續集成和交付。這個後面會專門來講如何操作,具體的意義就是開發人員提交代碼之後在Dev服務器上進行自動構建和發布,這樣一方面每次提交都做Lint檢查,有單元測試的做單元測試,降低代碼最後集成的時候出現問題的風險,另一方面讓PM可以儘早的接觸到成品,儘早進行反饋。

2. 需求測試和上線

當單個功能需求下面對應的所有任務都開發完成后,由PM進行測試和反饋,在確認與PRD一致后可以由PM更新為“待測試(Wait for test)”。這裏“待測試(Wait for test)”的意義就是該功能需求可以在發布到測試服務器(Test Server),由業務團隊及測試用戶參与測試。當測試沒有問題后,如果是Web功能則根據上線計劃上線到Production Server;如果是Native App,則按照版本計劃,可能需要固定時間發布或者等待幾個功能完成后一起發布。

由於這裏講的是單個功能需求的研發周期,而測試和上線更多是在整個項目這個Scope上來討論,所以針對測試和上線的部分在後面持續集成和發布的部分會來細說。

四、項目進度的管理

順着上面的思路,當你有單個需求研發的流程后,整個項目的管理就是管理所有的需求,安排優先級和迭代計劃,然後對所有需求進行同樣的研發流程管理。敏捷開發里把一個迭代周期稱為一個Sprint,每個Sprint做一次產品發布,然後回顧Sprint內的問題,規劃下一個Sprint的開發任務,如下圖:

我們的實踐不完全是Scrum,但比較接近,我們的迭代周期為一周,保證每周至少都往Production上做一次同步。項目的進度管理在Scrum的實踐里其實就是在它的三個Meeting時完成的:

  • Sprint Planning Meeting:從整個產品的Product Backlogs里一起規劃出下一個Sprint要完成的功能,可能對應着很多團隊的需求評審會
  • Daily Standup Meeting:在一個Sprint里每天和開發人員一起回顧昨天的開發進度,討論碰到的問題和確認當天的工作計劃,其實對應着為開發人員詬病的項目日報
  • Sprint Review Meeting:在一個Sprint結束回顧項目進度,問題和下一個Sprint的計劃,一般對應着PM要做的項目周報

在產品體驗的優化中有個理論就是在所有直接接觸用戶的‘Touchpoint’上進行體驗優化,其實我個人覺得這三個Meeting就是項目進度管理里的Touchpoint,在這三個Meeting上PM會和開發人員或者Product Owner進行接觸,如果這裏體驗不好就會影響項目的管理。其實我們總結的優化方案也比較簡單,就是通過項目管理工具Redmine去實現的功能需求和開發任務的“看板”

Sprint Planning Meeting

平時積累下的需求我會建立一個Future Milstone來存放,這樣在Planning Meeting上可以直接以這些作為Product Backlogs,作為產品以後可以去做的內容,這些需求可以按照功能模塊來組織,然後在Sprint Planning Meeting上一起規劃出下一個Sprint要完成的功能:

Daily Standup Meeting

每日的站立會議是粒度最細的會議了,就是追蹤每個人每天的任務情況,在這裏我們在Redmine上建立一個叫“本周需要完成的任務(開發人員)”的Custom Query,將這個Sprint里的任務按照不同類別( 網站,後台管理,iOS或者Android)來歸類,作為我們的看板:

對於開發人員,只需要按照前面提到的提交代碼來更新任務狀態,完全不需要額外的工作就可以彙報自己每天的進度。每天早上一上班,所有的開發人員聚在一起,按照不同的類別一個個過任務項,同步昨天完成的任務,確定今天的任務,有疑問的就在早會解決。

Sprint Review Meeting

對於項目進度Review來說,Scrum的看板管理是將任務項按照狀態來分類,這樣能更清晰的看出來哪些已經完成,哪些還沒有開始,可以通過變換Custom Query來實現:

不過Sprint Review Meeting一般就不只是研發團隊參与,為了輔助相關的業務人員和測試用戶一起來Review,我們通過在Redmine上建立一個叫“本周已經完成的任務(業務人員)”的Custom Query準備上線的功能,裏面是這個Sprint已經完成的功能,將已經完成功能的按照來歸類,PM可以按照這個來測試已經完成的功能,全部完成測試提交到測試服務器以後,相關的業務人員和測試用戶也可以按照這些任務來試用,節省一下每次都要介紹更新了什麼的時間:

五、研發階段的產品測試和反饋

產品發布到測試渠道后的反饋

當產品發布到測試渠道就是希望在正式發布前得到業務團隊或內測用戶的反饋,對比開發人員的測試反饋,業務人員和測試用戶的反饋一般都比較抽象,就是問題描述不具體,環境上下文不清晰,沒有復現流程,解決這些問題最好藉助反饋輔助工具:

  • 移動端的Bug反饋工具目前我們使用BugTags,目前只用在Test版本上,可以讓測試人員通過截圖標記的方式描述反饋內容,發送時候也會附上環境和App日誌,能節省不少對於反饋的處理時間。不過這個是顯式的反饋收集工具,需要測試用戶主動提交,如果需要隱式的反饋收集可以考慮AppSee,我自己沒有試用過,但一些測評都表示可以記錄用戶行為的視頻,統計界面點擊熱圖和漏斗分析,不過收費比較高,有機會可以嘗試下。
  • 移動端的錄屏工具的話可以選Lookback,其實是個用研的工具,功能就是語言錄屏+面部攝像,目前還在Beta期間,免費試用,可以Mac直接連接錄屏后發送到它的網站,也可以在它的本地目錄里找到。
  • Web端的Bug反饋工具目前只有截屏報bug,我目前沒有找到類似BugTags的可以顯式標記問題的反饋工具,曾經在《How Google Test Software》裏面看到Google曾經開源的Chrome插件工具BITE,有各種web上bug記錄和復現的黑科技,不過在Google Code上一副年久失修的樣子,我沒有勇氣去嘗試,如果有知道其他類似合適的可以推薦一下。
  • Web的線上用戶追蹤的話,我們目前使用了Mouseflow,它可以記錄用戶的行為,然後在它的網站上通過iframe你的網站幫你復現出來,雖然不是100%精準,但可以觀察一些用戶的行為。

產品發布前的測試用例表

我自己的經驗是每次發布前的測試都需要產品經理親自來做,一方面確認發布功能的正確性,另一方面重新走一遍用戶流程,確認產品目標可以達到。測試的方法比較笨,暫時就是通過Google Sheet維護一張測試用例的表,如果是移動端就每個版本維護一個測試用例表,開發版測試時會把表格分享給所有開發人員,每個人都可以遍歷測試用例提交自己發現的問題。測試用例表的結構為:

一級目錄,二級目錄,三級目錄,用例名稱,優先級,前置條件,執行方式,操作步驟,預期結果,測試狀態,測試備註,是否自動測試覆蓋

六、持續集成和持續發布

前幾年有一段為海外客戶做移動產品設計開發和諮詢的經歷,這裏面一個重要的痛點就是不停發測試版給客戶,徵求意見和反饋,但對於移動app來講之前每次打包都需要打斷開發人員,等待編譯,改文件名加版本號,上傳等一系列繁瑣的過程,然後還經常因為客戶沒有裝最新版而造成溝通時間的浪費,所以早期我們就開始着手建立持續集成和持續發布體系來避免這些問題。

我理解的一個完善的持續集成應該包括代碼提交后的構建->部署->測試->發布幾個階段,可以看‘The Product Managers’ Guide to Continuous Delivery and DevOps’上這個圖來理解:

自動構建

在上文Redmine的Git hooks提到過githooks在持續集成中的作用,其實就是當Git Commit Message出現相應的模塊,就會在代碼提交成功后能在持續集成服務端(CI Server)觸發相應的Server,Web,iOS或android端的自動構建,這是持續集成的基礎。

這裏面有個針對開發這邊的優化就是盡量縮短自動構建的時間消耗,我們的Web編譯就是個反例,優化前有10來分鐘的時間,現在穩定在3分鐘,還有優化空間:

持續部署

部署分為客戶端部署和服務端部署兩種,就是構建以後要把可運行的代碼發布到相應的服務器和手機端。

持續測試

這部分在服務端和每種客戶端都分為單元測試和集成測試,理論上來說能在持續集成的過程中執行測試,是對產品質量極大的提升,不過對團隊的規模和時間要求比較高,一般還是按自己的實際情況來。

自我檢討來說我們客戶端的單元測試這塊做的比較少,自動化集成測試的話每個項目都只對主要流程做一下覆蓋,這也是個從Linkedin早期開發流程里看到的經驗,可以通過分析用戶行為得到主要用戶流程,然後先自動化測試這些流程。早期在Android開發的時候實踐過,通過Jenkins+Spoon+Robotium可以在CI上跑多種不同的Android設備來對主要流程截圖,實現多設備的測試,在CI的效果是這樣的:

雖然效果確實不錯,可以在持續集成階段發現在什麼版本或者分辨率下出現問題,但用Robotium測試寫起來還比較麻煩,後來我在Github上fork過一些優化測試的方法進行優化,但如果不是非常長期維護的產品還是慎用吧。

持續交付

持續集成后的持續發布是我們主要需要解決的痛點,發布的對象分別是給開發和測試人員的Dev版,給內測用戶的Test版和給最終線上用戶的Production版,發布的渠道又分為Web端和Mobile端,需要分別來考慮,一個涵蓋上面所有的情況項目的Jenkins大概是這樣的:

在之前Gitflow的圖上有展示到,我們將發布的dev,test和production分為三個不同的服務器:

  • 對於Dev服務器就是由Git hooks來觸發,每次代碼提交都會更新Redmine對應的Task,然後Redmine發郵件給這個Task的Watchers,同時觸發CI集成新版本到Dev上。
  • 對於Test服務器就是當有新功能測試完成,準備上線的時候,就先同步到Test服務器上,通知內測用戶下載測試,相當於Staging服務器。
  • 對於Production的正常的流程就是當Sprint Review Meeting之後,按照確認要上線的功能進行發布。這裏我有個習慣就是發布的時候在CI上檢查一下發布對應的redmine tasks,避免有不該被同步的內容。

需要注意的就是,Web的持續交付相對來講比較簡單和成熟,但Android端和iOS端處理起來都比較麻煩,首先就是對於Production版本,都不能直接發布到AppStore或者國內的一堆Android市場,能在CI上做的就是build好production以後自動在Git上打版本tag。然後對於Test版本的分發,可以考慮使用Testflight或者國內的蒲公英,綁定到CI上,可以集成好以後直接發布上去,然後通過Slack建立測試用戶Channel,自動發送通知消息,收到通知可以直接點擊下載安裝。

後記

關於團隊溝通,需求協作和項目管理三塊的總結終於寫完了,很久沒碼文字了,寫出來感覺蠻生硬,很多地方沒有說清楚,不過水平確實也就這樣了。寫的過程中還是想到不少現在的方法裏面有缺陷的地方,正好給自己一個ToDo List,以後去優化。

 

作者:王超(微信號arnold_wangchao),創業者,5年互聯網產品管理經驗。本文轉自我個人的blog

本文由 @王超 原創發佈於人人都是產品經理。未經許可,禁止轉載。