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