TDD con copilota GitHub
di Paul Sobocinski
L’avvento degli assistenti di codifica AI come Github Copilot significherà che non avremo bisogno di check? TDD diventerà obsoleto? Per rispondere a questo, esaminiamo due modi in cui TDD aiuta lo sviluppo del software program: fornire un buon suggestions e un mezzo per “dividere e conquistare” quando si risolvono i problemi.
TDD per un buon suggestions
Un buon suggestions è veloce e accurato. Per entrambi i tempi, nulla batte a partire da un check unitario ben scritto. Non check manuali, non documentazione, non revisione del codice e sì, nemmeno AI generativa. In effetti, gli LLM forniscono informazioni irrilevanti e persino allucinato. TDD è particolarmente necessario quando si utilizzano assistenti di codifica AI. Per gli stessi motivi abbiamo bisogno di un suggestions rapido e accurato sul codice che scriviamo, abbiamo bisogno di suggestions rapidi e accurati sul codice che scrive il nostro assistente di codifica AI.
TDD per dividere i problemi
La risoluzione dei problemi tramite divisione e conquista significa che prima possono essere risolti problemi più piccoli di quelli più grandi. Ciò consente l’integrazione continua, lo sviluppo basato su trunk e, in definitiva, la consegna continua. Ma abbiamo davvero bisogno di tutto questo se gli assistenti di intelligenza artificiale fanno la codifica per noi?
SÌ. LLMs raramente fornisce la funzionalità esatta di cui abbiamo bisogno dopo un singolo immediate. Quindi lo sviluppo iterativo non sta ancora andando through. Inoltre, gli LLM sembrano “suscitare ragionamento” (vedi studio collegato) quando risolvono i problemi in modo incrementale tramite Provvidendo a catena. Gli assistenti di codifica AI con sede a LLM si comportano meglio quando dividono i problemi e il TDD è il modo in cui lo facciamo per lo sviluppo del software program.
Suggerimenti TDD per il copilota GitHub
A ThoughtWorks, abbiamo usato Github Copilot con TDD dall’inizio dell’anno. Il nostro obiettivo è stato quello di sperimentare, valutare ed evolvere una serie di pratiche efficaci sull’uso dello strumento.
0. Iniziare
A partire da un file di check vuoto non significa iniziare con un contesto vuoto. Iniziamo spesso da una storia dell’utente con alcune word approssimative. Parliamo anche attraverso un punto di partenza con il nostro associate di accoppiamento.
Questo è tutto un contesto che Copilot non “vede” fino a quando non lo inseriamo in un file aperto (advert esempio la parte superiore del nostro file di check). Copilot può funzionare con errori di battitura, formatura, povera grammatica: lo chiami. Ma non può funzionare con un file vuoto.
Alcuni esempi di contesto iniziale che hanno funzionato per noi:
- ASCII Artwork Mockup
- Criteri di accettazione
- Ipotesi guida come:
- “Nessuna GUI necessaria”
- “Usa la programmazione orientata agli oggetti” (vs. programmazione funzionale)
Copilot utilizza i file aperti per il contesto, quindi mantenendo sia il check che il file di implementazione aperto (advert esempio fianco a fianco) migliora notevolmente la capacità di completamento del codice di Copilot.
1. Rosso
Iniziamo scrivendo un nome di esempio di check descrittivo. Più descrittivo è il nome, migliore è la prestazione del completamento del codice di Copilota.
Troviamo che a Dato-allora-allora La struttura aiuta in tre modi. Innanzitutto, ci ricorda di fornire un contesto aziendale. In secondo luogo, consente a Copilot di fornire raccomandazioni di denominazione ricche ed espressive per gli esempi di check. In terzo luogo, rivela la “comprensione” di Copilot del problema dal contesto high di file (descritto nella sezione precedente).
Advert esempio, se stiamo lavorando sul codice backend e Copilot sta completando il codice il nostro nome di esempio di check, “Dato l’utente … Fa clic sul pulsante Acquista“questo ci cube che dovremmo aggiornare il contesto di high di file per specificare, “Supponiamo che nessuna GUI” O, “Questa suite di check si interfaccia con gli endpoint API di un’app Python Flask”.
Altri “gotchas” a cui fare attenzione:
- Copilot può completare il codice più check alla volta. Questi check sono spesso inutili (li eliminiamo).
- Man mano che aggiungiamo più check, Copilot completerà più righe full anziché una riga alla volta. Spesso inferirà i passaggi corretti “Organizza” e “Act” dai nomi dei check.
- Ecco il Gotcha: Dispone il passaggio “asserzione” corretto meno spesso, quindi siamo particolarmente attenti qui che il nuovo check è fallendo correttamente Prima di passare al passaggio “verde”.
2. Verde
Ora siamo pronti per Copilot per aiutare con l’implementazione. Una suite di check già esistente, espressiva e leggibile massimizza il potenziale di Copilot in questo passaggio.
Detto questo, Copilot spesso non riesce a fare “piccoli passi”. Advert esempio, quando si aggiunge un nuovo metodo, il “gradino del bambino” significa restituire un valore duro che supera il check. Advert oggi, non siamo stati in grado di convincere il copilota per adottare questo approccio.
Take a look at di riempimento
Invece di fare “piccoli passi”, il copilota salta in vantaggio e fornisce funzionalità che, sebbene spesso pertinenti, non sono ancora testate. Come soluzione alternativa, “riempiamo” i check mancanti. Mentre questo si discosta dal flusso TDD customary, non abbiamo ancora visto seri problemi con la nostra soluzione alternativa.
Elimina e rigenerare
Per il codice di implementazione che necessita di aggiornamento, il modo più efficace per coinvolgere Copilot è eliminare l’implementazione e fargli rigenerare il codice da zero. In caso di fallimento, l’eliminazione dei contenuti del metodo e la scrittura dell’approccio passo-passo utilizzando i commenti del codice può aiutare. In caso contrario, il modo migliore potrebbe essere quello di disattivare il copilota momentaneamente e codificare manualmente la soluzione.
3. Refactor
Il refactoring in TDD significa apportare modifiche incrementali che migliorano la manutenibilità e l’estensibilità della base di codice, tutte eseguite durante la conservazione del comportamento (e una base di codice di lavoro).
Per questo, abbiamo trovato l’abilità di Copilot limitata. Considera due scenari:
- “Conosco la mossa di refactor che voglio provare”: Scorri di refactor IDE e funzionalità come Multi-Cursor Choose Ottici dove vogliamo andare più veloce del Copilot.
- “Non so quale mossa di refactor prendere”: Il completamento del codice Copilota non può guidarci attraverso un refactor. Tuttavia, la chat di Copilota può rendere i suggerimenti per il miglioramento del codice proprio nell’IDE. Abbiamo iniziato a esplorare quella funzione e vedere la promessa di dare suggerimenti utili in un piccolo ambito localizzato. Ma non abbiamo ancora avuto molto successo per i suggerimenti di refactoring su larga scala (cioè oltre un singolo metodo/funzione).
A volte conosciamo la mossa di refactor ma non conosciamo la sintassi necessaria per eseguirla. Advert esempio, la creazione di un simulazione di check che ci consentirebbe di iniettare una dipendenza. Per queste situazioni, Copilot può aiutare a fornire una risposta in linea quando richiesto tramite un commento del codice. Questo ci fa risparmiare dal cambio di contesto alla documentazione o alla ricerca internet.
Conclusione
Il detto comune: “Rubbish In, Rubbish Out” si applica sia all’ingegneria dei dati che all’IA generativa e agli LLM. Dichiarato in modo diverso: gli enter di qualità superiore consentono di sfruttare meglio la capacità di LLMS. Nel nostro caso, TDD mantiene un alto livello di qualità del codice. Questo enter di alta qualità porta a migliori prestazioni di copilota di quanto sia altrimenti possibile.
Pertanto, consigliamo di utilizzare Copilot con TDD e speriamo che tu trovi i suggerimenti di cui sopra utili per farlo.
Grazie al workforce “ensemling with Copilot” è iniziato presso il ThoughtWorks Canada; Sono la fonte principale dei risultati trattati in questo memo: OM, Vivian, Nenad, Rishi, Zack, Eren, Janice, Yada, Geet e Matthew.