陳馨慧
(南方科技大學(xué)計算機科學(xué)與工程系,廣東深圳 518055)
隨著開源軟件與開源代碼托管平臺如GitHub的蓬勃發(fā)展,國內(nèi)外許多高校已開始將開源項目應(yīng)用于軟件工程課程實踐教學(xué)中。然而,現(xiàn)有課程還存在很多不足:首先,由于編程經(jīng)驗與背景的限制,學(xué)生對開源項目的選擇自由度過小;其次,現(xiàn)有課程往往只關(guān)注特定軟件工程概念對開源項目所帶來的影響;再次,對開源項目不熟悉的學(xué)生往往會提交低質(zhì)量代碼,被開源軟件維護(hù)人員拒收。同時,一些科技公司,如谷歌成功舉辦了多屆谷歌編程之夏(Google Summer of Code,GSoC)[1]和FindBugs“fixit”[2]等項目,以鼓勵學(xué)生為開源項目作出貢獻(xiàn)。本文借鑒這些成功的項目經(jīng)驗,提出基于開源項目的“GitHub-OSS Fixit”課程作業(yè),并對實施過程中所應(yīng)用的教案以及學(xué)生對于該課程作業(yè)的反饋進(jìn)行闡述。
在軟件工程教學(xué)方面,國外高校近年來提出了基于開源軟件的實踐教學(xué)模式[3-4],以培養(yǎng)學(xué)生“解決復(fù)雜工程問題”的能力。該方法在教學(xué)方面取得的成效較為顯著,但在學(xué)生對于開源社區(qū)的選擇自由度方面仍存在不足,目前暫無法大規(guī)模應(yīng)用于超過100 名學(xué)生的軟件工程課程?;陂_源軟件的實踐教學(xué)模式通常由任課教師指定幾個熟悉的開源軟件作為課程作業(yè)的基礎(chǔ),使得學(xué)生無法自由選擇感興趣的開源軟件。此外,學(xué)生一般缺乏開發(fā)與修改大規(guī)模軟件項目代碼的經(jīng)驗,無法系統(tǒng)性地學(xué)習(xí)如何參與開源社區(qū),為其貢獻(xiàn)代碼。
企業(yè)為了推廣開源軟件,創(chuàng)辦了多個以鼓勵學(xué)生參與開源軟件為中心的項目,其中包括谷歌編程之夏和Find-Bugs“fixit”。由谷歌舉辦的谷歌編程之夏[1]項目,旨在鼓勵不同技術(shù)背景的學(xué)生參與開源社區(qū),熟悉相關(guān)工作流程,利用暑假時間充分幫助他們鍛煉與提升代碼編寫能力。雖然該項目在鼓勵學(xué)生參與開源項目上取得了不錯的成效,但仍存在兩點不足:①有興趣參與該項目的學(xué)生必須通過耗時繁瑣的報名與選拔流程才能參與;②在開源項目選擇上,參與學(xué)生僅能選擇一些已提前報名參與GSoC的開源機構(gòu)且只能選擇該機構(gòu)指定的題目。同時,為了提升靜態(tài)分析工具FindBugs的質(zhì)量,谷歌程序員組織了FindBugs“fixit”[2]。該活動主要基于用戶所提交的缺陷報告,對Findbugs的代碼進(jìn)行修改,以修復(fù)用戶提出的缺陷,提升FindBugs 各方面的可靠性。
本文通過基于開源軟件項目的學(xué)期課程作業(yè)與基于軟件工程理念的教導(dǎo)自動化工具,進(jìn)行教學(xué)實踐相關(guān)研究并提供實踐教學(xué)案例,以彌補現(xiàn)有方法的不足。
為了鼓勵學(xué)生參與開源項目,筆者將開源項目融入軟件工程的小組課程項目中。小組課程作業(yè)共分為3 個方面:項目建議書、項目進(jìn)展報告和結(jié)題報告。如圖1 所示,在共16 周的軟件工程課上,該課程作業(yè)貫穿課程全程共10周。在這3 個階段中,由于學(xué)生必須在項目建議書上選擇自己感興趣的開源軟件與該軟件所存在的缺陷相關(guān)課程內(nèi)容,因此該階段為整個課程作業(yè)的核心部分。
Fig.1 Time schedule for team-based project assignment圖1 小組課程作業(yè)時間安排
在項目建議書階段,學(xué)生需編寫4 個主要模塊:①開源軟件選擇;②課程作業(yè)題目選擇;③課程項目整體規(guī)劃;④小組成員角色擬定。在進(jìn)展報告階段,學(xué)生需要對課程作業(yè)進(jìn)展進(jìn)行匯報,詳細(xì)匯報內(nèi)容包括不同靜態(tài)分析工具的分析報告以及有效測試用例數(shù)量與代碼覆蓋率,體現(xiàn)出所編寫代碼的質(zhì)量與規(guī)范性。在結(jié)題報告階段,學(xué)生需要匯報:①整個學(xué)期所修復(fù)的開源軟件缺陷的數(shù)量及所提交補丁的數(shù)量;②所選擇缺陷的重要性與危害程度;③總結(jié)所學(xué)習(xí)到的軟件工程知識與相關(guān)知識在項目中的應(yīng)用;④未來將會繼續(xù)改進(jìn)的各類下一步工作。
由于基于Java的程序設(shè)計課是軟件工程課的先修課程,筆者認(rèn)為學(xué)生已經(jīng)掌握了編寫基本Java 程序的技能,同時也因此限定了學(xué)生必須統(tǒng)一選擇基于Java 編程語言的開源軟件項目,但是GitHub 開源倉庫上仍擁有上萬個基于Java的開源軟件項目供學(xué)生選擇。為了解決開源軟件的選擇問題,筆者為學(xué)生提供了如何編寫項目建議書的詳細(xì)指導(dǎo)與說明。
在開源軟件選擇上,提供以下選擇基準(zhǔn)供學(xué)生參考:①易用性:每名小組成員需要成功編譯所選擇的Java 項目。如果成員所選擇的是安卓應(yīng)用,該應(yīng)用程序需要在手機或者安卓系統(tǒng)模擬器上成功運行;②現(xiàn)有的測試用例:該項目需要有一些測試用例,以方便檢查修改代碼后引入的回歸錯誤;③受歡迎程度:該軟件在GitHub 需要擁有超過100顆星(stars);④開源項目近期維護(hù)積極性程度:該軟件項目需要擁有近一年的代碼提交記錄(commit history);⑤尚未解決的缺陷報告(GitHub Issues)數(shù)量:該軟件項目需要擁有至少15 個未解決(open)的缺陷報告,所選擇的類型需以修復(fù)缺陷或者滿足用戶需求為目的,不能是回答用戶問題、僅涉及文檔修正或者僅優(yōu)化測試用例;⑥貢獻(xiàn)指南:需檢查該開源項目是否有提供任何貢獻(xiàn)指南(contribution guidelines),如有,附上指南鏈接。
以上基準(zhǔn)皆用于指導(dǎo)學(xué)生選擇一些受歡迎且有一群積極維護(hù)開發(fā)者的開源軟件,選擇受歡迎的開源軟件可以確保開源軟件的普及性。筆者認(rèn)為,積極維護(hù)開源軟件的開發(fā)者可視為學(xué)生的第二導(dǎo)師,通過審查學(xué)生所提交的補丁,指導(dǎo)學(xué)生如何提交高質(zhì)量并符合該開源社區(qū)規(guī)范(符合貢獻(xiàn)指南標(biāo)準(zhǔn))的代碼。
當(dāng)學(xué)生確定了開源軟件后,需選擇該軟件項目上未解決(open)的缺陷。為學(xué)生提供以下選擇基準(zhǔn):
(1)缺陷重要性。所選擇的缺陷需要有一定的重要性,例如,一些重要的Issue 會被開發(fā)者添加“供選擇”(“up for grab”)或者“尋求幫助”(“help wanted”)等標(biāo)記。同時,大多數(shù)開源項目會在“貢獻(xiàn)”(“contribute”)鏈接底下列出適合初學(xué)者修復(fù)的缺陷。
(2)無提交記錄。該缺陷報告(Issue)中不能有已修復(fù)該缺陷的提交記錄(commit history),要求不能選擇已被開發(fā)者或者其他用戶已經(jīng)解決過的缺陷。
(3)缺陷可被復(fù)現(xiàn)。學(xué)生需要為該缺陷編寫至少一個測試用例,確保該缺陷的可復(fù)現(xiàn)性,如果不了解該缺陷所提出的具體細(xì)節(jié),請不要選擇該缺陷。
(4)預(yù)計需要增加或修改的代碼行數(shù)。學(xué)生需要選擇相關(guān)項目中具有一定修復(fù)難度的缺陷,不能被輕易地解決。通常,筆者要求學(xué)生解決該缺陷需要增加或者修改至少10 行代碼。
(5)預(yù)計所需使用的時間。學(xué)生所選擇的缺陷如要修復(fù)需要花費一定時間。預(yù)計所花費時間至少是一到兩周。
以上基準(zhǔn)是為了保證學(xué)生選擇既重要又需編寫大量代碼進(jìn)行修復(fù)的缺陷,確保每名學(xué)生花費與其他學(xué)生相似的時間(以確保公平性),完成該課程作業(yè)。
為了培養(yǎng)學(xué)生的任務(wù)規(guī)劃能力,筆者讓學(xué)生選擇并規(guī)劃整個學(xué)期的課程作業(yè)任務(wù)。學(xué)生需根據(jù)以上提到的“開源軟件的題目選擇基準(zhǔn)”,選擇5~10 個備選缺陷,最終所選擇的缺陷數(shù)量取決于小組成員人數(shù)、缺陷難度和預(yù)計修復(fù)缺陷的時間。為了確保每個學(xué)生在課程作業(yè)中用時相當(dāng),筆者指定每名成員預(yù)計該學(xué)期共花費至少6 周的時間。由于學(xué)生在課程項目規(guī)劃方面缺乏經(jīng)驗,筆者為學(xué)生提供了課程任務(wù)規(guī)劃表的樣例。表1 為學(xué)生需提交的規(guī)劃表,其中包括缺陷的鏈接、類型、預(yù)計修復(fù)時間、負(fù)責(zé)修復(fù)缺陷的人數(shù)與預(yù)計的難度評級。由于極限編程提倡結(jié)對編程(兩名程序員并坐在同一臺電腦前,面對同一個顯示器,使用同一個鍵盤、同一個鼠標(biāo)一起編寫程序),筆者限制每個缺陷的修復(fù)人數(shù)不超過兩人,讓學(xué)生可以自主地選擇是否進(jìn)行結(jié)對編程。
Table 1 Iteration planning for GitHub issues表1 GitHub 問題的迭代規(guī)劃
由于學(xué)生可能會選擇修復(fù)一些簡單且無需編寫代碼的缺陷(例如潤色開源項目文檔和增加測試用例等),筆者在說明中表明只能選擇缺陷或者功能需求(feature request)類型的Issue。在課程作業(yè)的最終目標(biāo)說明上,筆者也提到學(xué)生需確保每名成員該學(xué)期至少修復(fù)兩個缺陷(每個階段修復(fù)一個缺陷)。此外,筆者也強調(diào)學(xué)生應(yīng)該根據(jù)預(yù)計難度,先修復(fù)一些因為簡單可能很快被其他人修復(fù)的缺陷,以免被別人捷足先登,同時也可以避免提交重復(fù)的補丁。
為了培養(yǎng)學(xué)生團(tuán)隊精神并鼓勵學(xué)生互相幫助解決作業(yè)上遇到的問題,該課程作業(yè)通過學(xué)生自由組隊的方式進(jìn)行,通常一個完成作業(yè)的隊伍由5~6 名學(xué)生組隊完成。為了確保學(xué)生所提交代碼的質(zhì)量,讓學(xué)生在項目建議書上選擇每名小組成員所扮演的角色并附上表2。
Table 2 Roles of group members表2 小組成員所扮演的角色
如表2 所示,除負(fù)責(zé)編寫代碼的開發(fā)者外,還添加了一些重要的軟件團(tuán)隊角色,包括設(shè)計師、測試員及開發(fā)與文檔維護(hù)者,目的在于確保軟件開發(fā)中各重要部分(如軟件測試、軟件設(shè)計、軟件文檔等)都有專人參與并監(jiān)督其進(jìn)度。同時,筆者也鼓勵學(xué)生在不同階段嘗試扮演不同的角色,以提高對軟件開發(fā)過程中不同角色的認(rèn)知。
南方科技大學(xué)的軟件工程課程以極限編程方法論為基礎(chǔ),對多個涉及軟件開發(fā)與維護(hù)的重要概念進(jìn)行教學(xué)。該課程共有16 周,每周有2 小時的理論課與2 小時的實驗課。軟件工程課程教案如表3 所示。
Table 3 Lesson plan for Software Engineering course表3 軟件工程課程教案
如表3 所示,軟件工程課程通過在理論課上灌輸版本控制、程序分析、軟件測試與持續(xù)集成的理念,加強學(xué)生對軟件開發(fā)與維護(hù)的理解。同時,筆者針對每個重要理念,設(shè)計相關(guān)的實踐練習(xí)題,將一些自動化工具(如單元測試工具JUnit、變異測試工具PIT 和靜態(tài)分析工具PMD 等)作為實踐練習(xí)題的基礎(chǔ),目的在于教導(dǎo)學(xué)生如何應(yīng)用自動化工具分析與維護(hù)代碼,從而保證代碼質(zhì)量,降低軟件維護(hù)時間與成本。
同伴輔導(dǎo)(Peer Tutoring)指一個有經(jīng)驗的學(xué)生在教師的適當(dāng)指導(dǎo)下去幫助另一個或者多個年齡相仿的學(xué)生去學(xué)習(xí)某個技能或概念。目前,同伴輔導(dǎo)已廣泛應(yīng)用于各類教學(xué)活動。由于大部分學(xué)生對開源項目不熟悉且對自己的編程能力不自信,筆者使用同伴輔導(dǎo)的方式,通過借鑒學(xué)長學(xué)姐的開源項目經(jīng)驗,以建立學(xué)生的自信心。筆者分別通過兩種不同的方式進(jìn)行同伴輔導(dǎo):①微信采訪;②分享學(xué)長學(xué)姐錄制的視頻。同伴輔導(dǎo)的主題為“如何從零開始參與開源項目”,在微信采訪環(huán)節(jié),筆者采訪了軟件工程課程的前助教王同學(xué),該生曾為知名開源項目Kubernetes貢獻(xiàn)過代碼。他提到以下幾個方面:①熟悉Git 操作及GitHub的工作流程;②使用某個開源軟件,然后發(fā)現(xiàn)不足;③參與開源軟件維護(hù),幫助開發(fā)者解決問題。在學(xué)長錄制的視頻方面,筆者邀請曾上過軟件工程和軟件測試課的徐同學(xué)錄制視頻。該生在所錄制的視頻中[8]展現(xiàn)了從零開始參與開源項目的親身經(jīng)歷:①在開源安卓應(yīng)用程序上尋找合適的缺陷;②基于測試驅(qū)動開發(fā)理念,準(zhǔn)備用于復(fù)現(xiàn)缺陷的測試用例;③在開源安卓應(yīng)用程序上進(jìn)行缺陷的細(xì)粒度分析;④編寫詳細(xì)的缺陷報告;⑤提交修復(fù)該缺陷的補??;⑥該補丁被開發(fā)者接受并歸入開源項目。
本文從兩方面評估了基于開源項目的課程作業(yè)對學(xué)生的影響:①學(xué)生對該課程作業(yè)的評價;②學(xué)生對開源項目的貢獻(xiàn)度。在評估學(xué)生對該課程作業(yè)的總體評價方面,采用李克特五點量表(選項包括:1.強烈反對;2.反對;3.不贊同也不反對;4.贊同;5.強烈贊同),調(diào)查學(xué)生對于“總的來說,我會推薦基于開源軟件的課程作業(yè)為日后的課程項目”問題的想法。圖2 顯示了學(xué)生對課程作業(yè)的評價,大部分學(xué)生(82%)強烈贊同或贊同基于開源軟件的課程作業(yè)并且會推薦該項目為日后的課程項目。
Fig.2 Students’feedback for team-based project assignment圖2 學(xué)生對課程作業(yè)的評價
此外,在評估學(xué)生對開源項目的貢獻(xiàn)度上,本文收集了學(xué)生所提交的補丁數(shù)量和補丁被開發(fā)者合入開源代碼庫的數(shù)量。該課程總共有154 名學(xué)生,在該學(xué)期結(jié)束前共為24 個不同的開源軟件提交了總計214 個補丁,其中有93個補丁被開發(fā)者接受并合入開源代碼庫,有46 個缺陷報告被開發(fā)者標(biāo)記為已解決。根據(jù)收集到的這些數(shù)據(jù),該項目在鼓勵學(xué)生為開源項目作出貢獻(xiàn)方面效果突出。
本文提出了基于開源軟件的課程作業(yè)并詳細(xì)闡述了課程作業(yè)的說明及實踐教學(xué)案例。本次共有154 名學(xué)生參與軟件工程課程學(xué)習(xí),共為各大開源軟件提交了214 個補丁且大部分補丁都被開發(fā)者接受并合入開源代碼庫。此外,經(jīng)統(tǒng)計后的評價結(jié)果表明,學(xué)生對于基于開源軟件的課程項目大致上表示認(rèn)可并愿意推薦為日后的課程作業(yè)。然而,在學(xué)生所提交的補丁中有部分仍未被開發(fā)者接受,這些補丁的代碼質(zhì)量仍有待提升,后續(xù)將進(jìn)一步加強代碼規(guī)范性與可讀性的教學(xué)環(huán)節(jié),以提升學(xué)生所提交補丁的質(zhì)量,達(dá)到更好的授課效果。整體而言,基于開源軟件的課程項目在提升軟件工程實踐能力上成效顯著。詳細(xì)的教學(xué)實踐實施方法可以參見相關(guān)教材[9],包括:課件、課程作業(yè)及詳細(xì)說明與學(xué)生錄制的視頻等。在今后教學(xué)工作中,還將引入更多前沿的軟件工程技術(shù)與工具,進(jìn)一步提升教學(xué)內(nèi)容的新穎性與多樣化,增強學(xué)生的理論基礎(chǔ)并提升實踐動手能力。