在軟件開發過程中,撰寫清晰且高效的單元測試非常重要,這些測試實際上能夠工作。單元測試將個別的代碼元素分離出來,並確認它們如预期般正常運作。
有效的單元測試不僅能捕捉錯誤,還能幫助您確定您的代碼可以被維護且值得信賴。但手動創建一套廣泛的單元測試所需的時間和資源。
近來人工智慧有些新发展,有望自動化單元測試開發過程。二月時,Meta的研究人員发布了一篇关于使用大型語言模型自動化單元測試改善的论文。這里 Introduces an innovative method for automating unit testing.
他們的研究 focuses on a new tool called TestGen-LLM
, which explores the possibilities of using LLMs to analyze existing unit tests and improving them to increase code coverage.
雖然TestGen-LLM的代碼尚未发布,我将在本文中介绍一个受其研究启发的开源替代方案。您將了解它是如何生成測試套件的,为什么它比大多数LLM更好,以及如何获得这项技術并开始尝试使用。
目錄
Meta 的 TestGen-LLM
Meta 的 TestGen-LLM 透過大型語言模型的力量,解決了單元測試撰寫的耗時任务。像 Gemini 或 ChatGPT 這種通用型的大 language models 可能會 struggle 單元測試代碼的特定領域、測試語法和生成沒有價值的測試。但 TestGen-LLM 是為單元測試而定制的。
這種专业化使他能夠理解代碼結構和測試邏輯的複雜性,從而產生更有目標的測試套件並生成實際增加價值和覆蓋率的測試。
TestGen-LLM 能夠評估單元測試並識別改善領域。它通過理解常見的測試模式來實現這一目標,這種模式已經训詁過。但單獨生成測試對於正確的覆蓋率是不夠的。
Meta 的研究人员在 TestGen-LLM 內实施了保護措施,以确保其所撰寫測試的成效。這些保護措施,稱為 過濾器
,作為質量控制機制。它們排除了建議:
-
無法編譯
-
不斷失敗,或
-
無法實際提高覆蓋率(這些建議已經被其他測試覆蓋)。
如何運作 TestGen-LLM?
TestGen-LLM 使用一種稱為「保證 LLM 基礎的軟件工程」方法(Assured LLMSE)。TestGen-LLM 只是為現有的測試類別新增額外的測試案例,保留所有現有的測試案例,從而確保不會發生回归。
測試生成工作流程(來自 TestGen_LLM 論文)
TestGen-LLM 生成了一大批測試案例,然後過濾掉那些不能運行的測試,並丢弃那些不能通過的測試。最後,它排除了那些不增加代码覆蓋率的測試。
在利用 TestGen-LLM 自動化一個測試套件之後,Meta 使用一名人類評論員來接受或拒絕生成的測試,在其最好的報告案例中,生成的測試的接纳率為 73%。
根據論文,TestGen-LLM 在每次運行時生成的單個測試,然後添加到之前由開發者编寫的現有測試套件中。但它不一定為任何給定的測試套件生成測試。
TestGen-LLM 的有效性在 Meta 的內部測試馬拉松中得到證明。在這裡,該工具用於分析現有的測試套件並提出改善建議。結果很有前景:
“TestGen-LLM 的測試案例中有 75% 建造正確,57% 可靠地通過,25% 增加了覆蓋率。在 Meta 的 Instagram 和 Facebook 測試馬拉松中,它改善了應用於其上的 11.5% 的所有類別,其中 73% 的建議被 Meta 軟件工程師接受用於生產部署。”。
Also,來自TestGen-LLM的建議被參與測試高峰會的开发者在測試中認為有用且相關。
开源實現(覆蓋代理)
來自Meta的TestGen-LLM研究具有很大潜力改變單元測試和自動測試生成。這個工具可能通過使用特別針對代碼進行訓練的LLM來提高代碼覆蓋率並加快測試創建。但是,由於TestGen-LLM的代碼並未釋出,這個技術並不是任何人都可以使用的。
對這種技術感興趣的开发者在缺乏公開可用的代碼時可能會感到挫折。畢竟,Meta的TestGen-LLM研究讓我們一窥自動測試未來的面貌。
能夠深入最新技術的內部工作机制、理解其決策過程,甚至可能幫助塑造其發展,這非常吸引人。但由於Meta的代碼缺失,這成為了一個障礙,有一個叫Cover-Agent
的开源實現可以作為一個有用的選擇。
CodiumAI的Cover-Agent
是基於TestGen-LLM的自動測試工具的第一個开源實現。受到Meta研究的啟發,Cover-Agent因此成為开源AI驅動單元測試發展的前沿。
為什麼需要特定的測試为重点的LLM?
由於大多數LLM(如ChatGPT和Gemini)都能夠生成測試,那麼為什麼還要有新技術呢?
很好地,Cover-Agent 和 TestGen-LLM 是要成為效率單元測試的下一个階段。它們的目標是避免開發者在使用 LLM 生成測試時遇到的常見誤區,例如:
-
LLM 幻覺
-
生成沒有價值的測試
-
生成略過某些代碼部分的測試,導致代碼覆蓋率低
為了克服這些挑戰(特別是對於回歸單元測試),TestGen-LLM 研究人员提出了以下標準,生成測試必须在通過這些標準後才能被接受:
-
生成的測試是否能夠正確编译和運行?
-
測試是否增強了代碼覆蓋率?
-
它是否有價值?
-
它是否滿足我們可能有的任何其他要求?
這些是生成測試必须在被视为现有技術的升級之前解決的基本問題和問題。Cover-Agent 提供回答這些問題的測試到一个非常高的程度上。
Cover-Agent 是如何工作的?
覆蓋代理是旨在為軟體項目自動化創建單元測試的更廣泛工具集中的部分。它使用TestGen-LLM生成式AI模型,旨在簡化和加快測試過程,確保高品質的軟體開發。
該系統由幾個部件組成:
-
測試運行器:執行運行測試套件和生成覆蓋報告的命令或脚本。
-
覆蓋解析器:驗證當添加測試時,覆蓋率是否增加,確保新的測試有助于整體測試效果。
-
提示建造器:從代碼庫中收集必要的數據並構建要傳遞給大型語言模型(LLM)的提示。
-
AI呼叫器:根據提供的提示與LLM交 interact以生成測試。
這些部件與TestGen-LLM一同工作,生成的測試只有保證能改善現有的代碼庫。
如何使用 Cover-Agent
要求
在您可以开始使用 Cover-Agent 之前,您需要满足以下要求:
-
OPENAI_API_KEY
必须在您的环境变量中设置,这是调用OpenAI API
所必需的。 -
代码覆盖工具:需要一个 Cobertura XML 代码覆盖报告,以便工具正确运行。例如,在 Python 中,您可以使用
pytest-cov
。在运行 Pytest 时,请添加--cov-report=xml
选项。
安装
如果您直接从仓库运行 Cover-Agent,您还需要:
-
在您的系统上安装 Python。
-
安装 Poetry 以管理 Python 包依赖项。您可以在 这里 找到 Poetry 的安装说明。
独立运行时
您可以將 Cover-Agent 作為 Python Pip 包安裝,或者作為獨立的可执行文件運行。
Python Pip
透過 GitHub 直接安裝 Python Pip 包,您可以運行以下命令:
pip install git+https://github.com/Codium-ai/cover-agent.git
二進制
您可以不需要在系統上安裝任何 Python 環境就能運行二進制文件(例如,在不含 Python 的 Docker 容器的環境中)。您可以通過訪問项目的 發布頁面 來下載系統的日发布版本。
倉庫設定
運行以下命令來安裝所有依賴並從源代碼運行項目:
poetry install
運行代碼
在下載可执行文件或安裝 Pip 包後,您現在可以運行 Cover-Agent 以生成和驗證單元測試。
從命令行運行它,使用以下命令:
cover-agent \
--source-file-path "path_to_source_file" \
--test-file-path "path_to_test_file" \
--code-coverage-report-path "path_to_coverage_report.xml" \
--test-command "test_command_to_run" \
--test-command-dir "directory_to_run_test_command/" \
--coverage-type "type_of_coverage_report" \
--desired-coverage "desired_coverage_between_0_and_100" \
--max-iterations "max_number_of_llm_iterations" \
--included-files "<optional_list_of_files_to_include>"
您可以使用這個倉庫中的示例項目來作為測試運行此代碼。
命令參數
-
source-file-path: 存放我們想要測試的函數或代碼塊的文件路徑。
-
test-file-path: 代理將在此文件中寫入測試的文件路徑。最好創建一個此文件的骨架,至少包含一個測試和必要的導入語句。
-
代碼覆蓋報告路徑: 保存代碼覆蓋報告的路徑。
-
測試命令: 運行測試的命令(例如 pytest)。
-
測試命令目錄: 測試命令應運行的目錄。將此設置為根目錄或主要文件的所在地,以避免相對導入引起的問題。
-
覆蓋類型: 要用來覆蓋的類型。Cobertura 是一個不錯的預設值。
-
期望覆蓋率: 覆蓋率目標。越高越好,雖然 100% 通常是不可實行的。
-
最大迭代次數: 代理應該重試生成測試代碼的次數。更多的迭代可能會導致更高的 OpenAI 令牌使用量。
-
追加指示: 確保代碼以特定方式编寫的提示。例如,這裡我們指定了代碼應該格式化以在測試類中工作。
在運行命令時,代理人開始寫作並對測試進行迭代。
如何使用覆蓋代理
是时候测试一下Cover-Agent了。我們將使用一個簡單的calculator.py應用程序來比較手動和自動測試的代碼覆蓋率。
手動测试
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
這是在測試文件夾中的test_calculator.py。
# tests/test_calculator.py
from calculator import add, subtract, multiply, divide
class TestCalculator:
def test_add(self):
assert add(2, 3) == 5
為了查看測試覆蓋率,我們需要安裝pytest-cov
,一個用於覆蓋報告的pytest擴展 earlier mentioned.
pip install pytest-cov
使用以下命令運行覆蓋分析:
pytest --cov=calculator
上面的輸出顯示:
Name Stmts Miss Cover
-----------------------------------
calculator.py 10 5 50%
-----------------------------------
TOTAL 10 5 50%
上面顯示的結果告訴我們calculator.py中的10條語句中有5條沒有被执行,導致覆蓋率仅为50%。對於更大的代碼庫,這將成為一個嚴重問題,導致挫折。
現在讓我們看看覆蓋代理能否做得更好。
使用Cover-Agent的自動測試
為了搭建Codium的Cover-Agent,請按照以下步驟操作:
首先,安装 Cover-Agent:
pip install git+https://github.com/Codium-ai/cover-agent.git
請確保您在環境變量中设置了 OPENAI_API_KEY,因為它對於 OpenAI API 是必需的。
接下來,在終端中编写開始生成測試的命令:
cover-agent \
--source-file-path "calculator.py" \
--test-file-path "tests/test_calculator.py" \
--code-coverage-report-path "coverage.xml" \
--test-command "pytest --cov=. --cov-report=xml --cov-report=term" \
--test-command-dir "./" \
--coverage-type "cobertura" \
--desired-coverage 80 \
--max-iterations 3 \
--openai-model "gpt-4o" \
--additional-instructions "Since I am using a test class, each line of code (including the first line) needs to be prepended with 4 whitespaces. This is extremely important to ensure that every line returned contains that 4 whitespace indent; otherwise, my code will not run."
這會生成以下的代碼:
import pytest
from calculator import add, subtract, multiply, divide
class TestCalculator:
def test_add(self):
assert(add(2, 3), 5
def test_subtract(self):
"""
Test subtracting two numbers.
"""
assert subtract(5, 3) == 2
assert subtract(3, 5) == -2
def test_multiply(self):
"""
Test multiplying two numbers.
"""
assert multiply(2, 3) == 6
assert multiply(-2, 3) == -6
assert multiply(2, -3) == -6
assert multiply(-2, -3) == 6
def test_divide(self):
"""
Test dividing two numbers.
"""
assert divide(6, 3) == 2
assert divide(-6, 3) == -2
assert divide(6, -3) == -2
assert divide(-6, -3) == 2
def test_divide_by_zero(self):
"""
Test dividing by zero, should raise ValueError.
"""
with pytest.raises(ValueError, match="Cannot divide by zero"):
divide(5, 0)
您可以看到,代理商還寫了檢查任何邊界情況錯誤的測試。
現在是再次測試覆蓋率的時間:
pytest --cov=calculator
輸出:
Name Stmts Miss Cover
-----------------------------------
calculator.py 10 0 100%
-----------------------------------
TOTAL 10 0 100%
在這個示例中,我們達到100%的程式覆蓋率。對於更大的程式庫,这个过程相对相同。您可以閱讀 這份指南 進行更大程式庫的导览。
雖然 Cover-Agent 代表了一个重要的进展,但值得注意的是,这项技術仍然处于初级阶段。持续的研究与发展对于进一步的精细化和更广泛的应用至关重要,codiumAI 邀请您为这个开源工具做出您的贡献。
Open Source Cover-Agent 的好处
Cover-Agent 的开源性提供了几个优势,应该有助于推动这项技术前进。其中包括:
-
易用性: 开源性使得基于 LLM 的测试实验变得可行,并为不同背景的开发者提供 accessibilityThis 将增加用户数量,并导致更好的技术开发和更多应用。.
-
合作:開發者能夠做出貢獻,建議改善,提出新功能並報告問題。Cover-Agent將迅速成長發展,成為開發者完美的專案..
-
透明度:關於內部運作的資訊是可用的,這促進了信任,並最終增加了技術的潛力。
除了開放原始碼的優勢之外,Cover-Agent還為開發者提供了自身的一系列強大好處:
-
簡單存取:開發者可以輕鬆安裝並實驗LLM基於的測試。這使得他們能夠第一手並立即探索技術的能力,並且在日常工作流程中幾乎不造成中斷。
-
針對特定需求的客製化:Cover-Agent的開源本性讓開發者能夠將工具 adaptation 到他們的特定項目要求。這可能包括修改使用的LLM模型、調整訓練數據以更好地反映他們的代碼庫,或是將Cover-Agent與既有的測試框架結合。這種程度的客製化讓開發者能夠以符合他們項目需求的方式, lever 年 LLC-based testing 的力量。
-
簡單整合:它很容易與VSCode(一個流行的代碼編輯器)整合,這使得與既有的工作流程整合變得簡單。你也可以很容易地與既有的人類撰寫的測試整合。
你如何可以向Cover-Agent貢獻?
覆蓋代理源代碼是通過這個GitHub倉庫公开发放的。他們鼓勵來自各種背景的開發者測試他們的产品並為進一步改進和成長這個新技术做出貢獻。
結論
基於LLM的測試改進工具為開發者處理單元測試的方式帶來革命性的潛力。通過 leveraging 大型語言模型在代码上的特別訓練,這些工具可以簡化測試創建,提高代碼覆蓋率,最終提升軟體質量。
雖然Meta的TestGen-LLM研究提供了很有價值的見解,但公开可获得的代碼缺乏導致了更廣泛采用和進行中開發的障礙。幸运的是,Cover-Agent提供了一個即可獲得和自訂义的解決方案。它 empowering 開發者實驗LLM基礎的測試並為其演變做出貢獻。
TestGen-LLM和Cover-Agent的潛力巨大,透過開發者的貢獻進行進一步開發將導致一個革命性的工具,將永遠改變自動化測試生成。
Source:
https://www.freecodecamp.org/news/automated-unit-testing-with-testgen-llm-and-cover-agent/