È importante scrivere unit test chiari e efficienti che funzionino effettivamente durante il processo di sviluppo del software. I test unitari separano gli elementi di codice individuali e confermano che funzionino come previsto.

I test unitari efficienti non solo catturano errori, ma aiutano anche a rimanere confidenti che il codice possa essere mantenuto e affidabile. Ma richiede tempo e risorse creare manualmente una suite di test unitari estesa.

Ci sono stati alcuni sviluppi recenti nell’intelligenza artificiale che promettono di aiutare ad automatizzare i processi di sviluppo dei test unitari. Nel febbraio, i ricercatori di Meta hanno pubblicato un documento su Automated Unit Test Improvement using Large Language Models. Questo ha introdotto un metodo innovativo per automatizzare i test unitari.

La loro ricerca si concentra su una nuova tool chiamata TestGen-LLM, che esplora le possibilità dell’utilizzo di LLM per analizzare già esistenti test unitari e migliorarli per aumentare la copertura del codice.

Anche se il codice per TestGen-LLM non è stato rilasciato, in questo articolo presenterò un alternativo open-source ispirato dalla loro ricerca. Imparare come genera suite di test, perché è meglio di molti LLM e dove ottenere questa tecnologia e iniziare a provarla.

Tavola dei Contenuti

Meta’s TestGen-LLM

Meta’s TestGen-LLM affronta la task onerosissima di scrivere test unitari utilizzando il potere delle grandi modelli di linguaggio (LLMs). Modelli LLM generali come Gemini o ChatGPT potrebbero avere difficoltà con il dominio specifico del codice di test unitari, della sintassi di test e della generazione di test che non aggiungono valore. Ma TestGen-LLM è stato progettato specificamente per i test unitari.

Questa specializzazione gli consente di capire le sfumature della struttura del codice e della logica di test, portando a suite di test più mirate e alla generazione di test che aggiungono davvero valore e aumentano la copertura del codice.

TestGen-LLM è in grado di valutare i test unitari e identificare aree da migliorare. Riuscisce a questo attraverso la sua comprensione dei comuni pattern di test, cui è stato addestrato. Ma la generazione di test da sola non è sufficiente per una corretta copertura del codice.

I ricercatori di Meta hanno implementato sicurezze all’interno di TestGen-LLM per assicurarsi l’efficacia dei test che scrivono. Queste sicurezze, indicate come filtri, fungono da meccanismo di controllo di qualità. Escluiscono suggerimenti che:

  • non potrebbero essere compilati

  • falliscono costantemente, o

  • non migliano effettivamente la copertura del codice (suggerimenti che sono già coperti da altri test).

Come funziona TestGen-LLM?

TestGen-LLM utilizza un approcio chiamato “Software Engineering basato su LLM Assicurato” (Assured LLMSE). TestGen-LLM semplicemente aggiunge test casistica aggiuntiva ad una classe di test esistente, conservando tutti i test esistenti e garantendo così che non ci saranno regressioni.

Workflow di generazione di test(Da TestGen_LLM paper)

TestGen-LLM genera un insieme di test, quindi filtra i test che non vengono eseguiti e scarta quelli che non passano. Infine, esclude quelli che non incrementano la copertura del codice.

Dopo aver usato TestGen-LLM per automatizzare un insieme di test, Meta ha usato un revisore umano per accettare o respingere i test in cui i test generati avevano un tasso di accettazione del 73% nei loro migliori casi riportati.

Secondo il documento, TestGen-LLM genera un singolo test in ogni esecuzione, che viene quindi aggiunto ad un insieme di test esistente scritto in precedenza da un sviluppatore. Ma non genera necessariamente test per ogni insieme di test.

L’efficacia di TestGen-LLM è stata dimostrata ai test-a-thons interni di Meta. Qui, lo strumento è stato usato per analizzare gli insiemi di test esistenti e suggerire miglioramenti. I risultati sono stati promettenti:

“Il 75% dei casi di test di TestGen-LLM è stato costruito correttamente, il 57% è stato superato in modo affidabile, e il 25% ha incrementato la copertura. Durante i test-a-thons di Instagram e Facebook di Meta, è stato migliorato il 11,5% di tutte le classi a cui è stato applicato, con il 73% delle sue raccomandazioni accettate per la distribuzione in produzione dagli ingegneri software di Meta”.

Anche le raccomandazioni da TestGen-LLM sono state considerate utili e rilevanti dai sviluppatori che hanno partecipato alle test-a-thon.

Implementazione Open-Source (Cover-Agent)

La ricerca TestGen-LLM di Meta ha un grande potenziale per cambiare le unità di test e la generazione automatica di test. L’ strumento probabilmente aiuterà a migliorare la copertura del codice e a velocizzare la creazione di test utilizzando LLM particolarmente addestrate sul codice. Ma questa tecnologia non è disponibile per l’uso di chiunque, poiché il codice di TestGen-LLM non è stato rilasciato.

I sviluppatori che hanno preso interesse in questa tecnologia probabilmente sono frustrati dalla mancanza di codice disponibile pubblicamente. Dopotutto, lo studio di TestGen-LLM di Meta fornisce un’ occhiata al futuro di ciò che può essere la testautomazione.

È piuttosto appallottolato poter immergersi nelle inner working della nuova tecnologia, comprendere i processi decisionali, e forse persino influenzare il suo sviluppo. Ma mentre la mancanza del codice di Meta è un ostacolo, c’è un’ implementazione open-source chiamata Cover-Agent che può servire come alternativa utile.

CodiumAI's Cover-Agent è la prima implementazione open-source di uno strumento di test automatico basato su TestGen-LLM. Ispirato dalla ricerca di Meta, Cover-Agent si trova ora al centro delle evoluzioni nella testautomazione open-source guidata da AI come conseguenza.

Perché sono necessarie LLM specifiche per il testing?

Dato che la maggior parte delle LLM (come ChatGPT e Gemini) è in grado di generare test, allora perché si preoccupare di una nuova tecnologia?

Bene, Cover-Agent e TestGen-LLM sono stati creati come il prossimo passo nell’evoluzione dell’unit testing efficiente. Il loro scopo è di evitare i classici problemi in cui si imbattiscono i developer quando generano test con le LLM, come:

  • LLM Hallucination

  • Generando test che non aggiungono valore

  • Generando test che omettono parti del codice, risultando in bassa copertura del codice

Per superare questi challenge (specificamente per i test di regressione) gli studiosi di TestGen-LLM hanno proposto i seguenti criteri, che i test generati devono soddisfare prima che il test possa essere accettato:

  • Il test generato compila e si esegue correttamente?

  • Il test aumenta la copertura del codice?

  • Aggiunge valore?

  • Soddisfa eventuali altri requisiti che potremmo avere?

Questi sono domande e problemi fondamentali che il test generato deve risolvere prima di essere considerato un’integrazione rispetto alla tecnologia esistente. Cover-Agent fornisce test che rispondono a queste domande in un grado eccezionale.

Come Funziona Cover-Agent?

Cover-Agent fa parte di una suite di utility più ampia, progettate per automatizzare la creazione di test unitari per progetti software. Utilizzando il modello AI Generativo TestGen-LLM, si propone di semplificare e accelerare il processo di test, garantendo una sviluppo software di alta qualità.

Il sistema è composto da diversi componenti:

  • Test Runner: Esegue i comandi o i script per eseguire il insieme di test e generare rapporti di copertura del codice.

  • Coverage Parser: Valida che la copertura del codice aumenti man mano che vengono aggiunti test, garantendo che i nuovi test contribuiscano alla complessiva efficacia del testing.

  • Prompt Builder: Raccoglie i dati necessari dalla base di codice e costruisce il prompt da passare al Large Language Model (LLM).

  • AI Caller: Interagisce con l’LLM per generare test in base al prompt fornito.

Questi componenti lavorano insieme a TestGen-LLM per generare solo test che garantiscono di migliorare il codice esistente.

Come utilizzare Cover-Agent

Requisiti

Devi avere i seguenti requisiti prima di poter iniziare a usare Cover-Agent:

  • OPENAI_API_KEY impostato nelle variabili di ambiente, necessario per richiamare l’API OpenAI.

  • Strumento di coverage di codice: è richiesto un rapporto di coverage XML Cobertura perché lo strumento funzioni correttamente. Per esempio, in Python potresti usare pytest-cov. Aggiungi l’opzione --cov-report=xml quando si esegue Pytest.

Installazione

Se state eseguendo Cover-Agent direttamente dal repository, avrete anche bisogno di:

  • Python installato sul tuo sistema.

  • Poetry installato per la gestione delle dipendenze dei pacchetti Python. Puoi trovare le istruzioni di installazione di Poetry qui.

Esecuzione standalone

Puoi installare Cover-Agent come pacchetto Python Pip o eseguirlo come esecutabile standalone.

Python Pip

Per installare il pacchetto Python Pip direttamente tramite GitHub, esegui il seguente comando:

pip install git+https://github.com/Codium-ai/cover-agent.git

Binario

Puoi eseguire il binario senza aver installato alcun ambiente Python sul tuo sistema (ad esempio, all’interno di un contenitore Docker che non contiene Python). Puoi scaricare la versione per il tuo sistema visitando la pagina delle versioni del progetto.

Impostazione del Repository

Esegui il seguente comando per installare tutte le dipendenze e eseguire il progetto dalla fonte:

poetry install

Esecuzione del Codice

Dopo aver scaricato l’esecutabile o aver installato il pacchetto Pip, ora puoi eseguire Cover-Agent per generare e validare i test unitari.

Eseguilo dalla riga di comando usando il seguente comando:

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>"

Puoi usare i progetti di esempio contenuti in questo repository per eseguire questo codice come test.

Argomenti del Comando

  • source-file-path: Percorso del file che contiene le funzioni o il blocco di codice che vogliamo testare.

  • test-file-path: Percorso del file in cui verranno scritti i test da parte dell’agente. È meglio creare uno scheletro di questo file con almeno un test e le istruzioni di importazione necessarie.

  • report-cov-codice: Percorso dove viene salvato il rapporto della copertura del codice.

  • comando-test: Comando per eseguire i test (esempio pytest).

  • dir-comando-test: Directory in cui si dovrebbe eseguire il comando di test. Impostare questo come radice o nella posizione del file principale per evitare problemi con gli import relativi.

  • tipo-copertura: Tipo di copertura da usare. Cobertura è un buon default.

  • copertura-desegnata: Obiettivo di copertura. Più alto è meglio, anche se spesso il 100% è impraticabile.

  • max-iterazioni:Numero di volte che l’agente dovrebbe riprovare a generare il codice di test. Maggior numero di iterazioni può portare ad un maggiore utilizzo di token OpenAI.

  • istruzioni-addizionali: Prompt per garantire che il codice sia scritto in un determinato modo. Per esempio, qui specificiamo che il codice dovrebbe essere formattato per funzionare all’interno di una classe di test.

Creando il comando, l’agente inizia a scrivere e a iterare sui test.

Come utilizzare Cover-Agent

È ora di provare Cover-Agent. Uszeremo una semplice app calculator.py per confrontare la copertura del codice per i test manuali e automatizzati.

Test manuali

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

Questo è il file test_calculator.py posizionato nella cartella di test.

# tests/test_calculator.py
from calculator import add, subtract, multiply, divide

class TestCalculator:

    def test_add(self):
        assert add(2, 3) == 5

Per visualizzare la copertura del test, occorre installare pytest-cov, un estensione di pytest per la rappresentazione della copertura precedentemente citata.

pip install pytest-cov

Eseguire l’analisi di copertura con:

pytest --cov=calculator

Il risultato mostra:

Name            Stmts   Miss  Cover
-----------------------------------
calculator.py      10      5    50%
-----------------------------------
TOTAL              10      5    50%

Il risultato sopra mostra che 5 delle 10 istruzioni in calculator.py non sono eseguite, portando così a una sola copertura del 50% del codice. Per un base di codice più ampia, questo diventerà un grosso problema e potrebbe comportare intoppi.

Ora vediamo se cover-agent può fare meglio.

Test automatizzati con Cover-Agent

Per impostare Codium di Cover-Agent, segui questi passaggi:

Prima di tutto, installare Cover-Agent:

pip install git+https://github.com/Codium-ai/cover-agent.git

Assicurarsi che la variabile d’ambiente OPENAI_API_KEY sia impostata, poiché è richiesta per l’API OpenAI.

Successivamente, scrivere i comandi per generare test nel terminale:

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."

Questo genera il seguente codice:

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)

Come vedete, l’agente ha anche scritto test che verificano gli errori per qualsiasi caso di边缘.

Ora è il momento di testare di nuovo la copertura:

pytest --cov=calculator

Output:

Name            Stmts   Miss  Cover
-----------------------------------
calculator.py      10      0   100%
-----------------------------------
TOTAL              10      0   100%

In questo esempio abbiamo raggiunto il 100% di copertura del codice. Per basi di codice più grandi, la procedura è relativamente la stessa. Puoi leggere questo guide per un’introduzione a una base di codice più grande.

Sebbene Cover-Agent rappresenti un passo significativo avanti, è importante notare che questa tecnologia è ancora in fase embrionale. La ricerca e lo sviluppo continui sono cruciali per ulteriori raffinamenti e una più ampia adozione, e codiumAI vi invita a contribuire a questo strumento open source.

Vantaggi di Cover-Agent open source

La natura open source di Cover-Agent offre diversi vantaggi che dovrebbero aiutare a spingere avanti la tecnologia. Tra di essi ci sono:

  • Accessibilità: La sua natura open source consente esperimenti di testing basati su LLM ed è accessibile ai sviluppatori con背景 diversi. Questo aumenterà il numero di utenti e condurrà alla creazione di una tecnologia migliore e di più applicazioni..

  • Collaborazione: Gli sviluppatori possono contribuire, suggerire miglioramenti, proporre nuove funzionalità e segnalare problemi. Cover-Agent crescerà e svilupperà rapidamente in un progetto perfetto per gli sviluppatori..

  • Trasparenza: Le informazioni sulle operazioni interne sono disponibili, il che promuove la fiducia e aumenterà potenzialmente il valore della tecnologia.

Oltre agli svantaggi open source, Cover-Agent offre agli sviluppatori un nutrito insieme di benefici propri:

  • Accesso Semplice: Gli sviluppatori possono facilmente installare e sperimentare con i test basati su LLM. Ciò consente un’esplorazione diretta e immediata delle capacità della tecnologia senza interruzioni significative nel flusso di lavoro.

  • Personalizzazione per necessità specifiche: La natura open-source di Cover-Agent permette ai sviluppatori di adattare l’ strumento alle loro specifiche richieste di progetto. Questo potrebbe includere la modifica del modello LLM utilizzato, l’ adeguamento dei dati di addestramento per meglio riflettere la loro base di codice o l’ integrazione di Cover-Agent con framework di test esistenti. Questo livello di personalizzazione dà potere agli sviluppatori per sfruttare il potere dei test basati su LLM in modo che corrisponda alle loro necessità di progetto.

  • Integrazione facile: Può essere integrato facilmente con VSCode (un popolare editor di codice), rendendo semplice l’ integrazione con flussi di lavoro esistenti. Puoi anche integrarlo facilmente con test scritti a mano esistenti.diy9>

Come puoi contribuire a Cover-Agent?

Il codice sorgente di Cover-Agent è disponibile pubblicamente attraverso questo repository GitHub. Essi incoraggiano sviluppatori di ogni background a testare il loro prodotto e a fare contrbuiti per ulteriormente migliorare e crescere questa nuova tecnologia.

Conclusione

Gli strumenti di miglioramento del testing basati sui testi generati da modelli a larga scala (LLM) hanno un potenziale immenso per rivoluzionare il modo in cui i sviluppatori approcciano i test unitari. Utilizzando il potere di modelli a larga scala specificamente addestrati sul codice, questi strumenti possono semplificare la creazione di test, aumentare la copertura del codice e migliorare la qualità del software in definitiva.

Se la ricerca di Meta con TestGen-LLM offre valuabili insight, la mancanza di codice disponibile pubblicamente limita l’adozione più ampia e lo sviluppo in corso. Fortunatamente, Cover-Agent ha fornito una soluzione accessibile e personalizzabile. Dà agli sviluppatori la possibilità di sperimentare i test basati sui LLM e contribuire alla loro evoluzione.

Il potenziale di TestGen-LLM e Cover-Agent è immenso, e ulteriori sviluppi tramite contributi degli sviluppatori condurranno a uno strumento rivoluzionario che trasformerà la generazione automatica di test per sempre.

Contatta con me su LinkedIn e Twitter se questo ha aiutato.