Che cos'è il test unitario? [chiuso]


211

Ho visto molte domande che chiedevano "come" test unitario in una lingua specifica, ma nessuna domanda che chiedeva "cosa", "perché" e "quando".

  • Che cos'è?
  • Che cosa fa per me?
  • Perché dovrei usarlo?
  • Quando dovrei usarlo (anche quando non lo è)?
  • Quali sono alcune insidie ​​e idee sbagliate comuni

Uber, ci sono molte risorse disponibili e l' articolo di Wikipedia è sicuramente un ottimo punto di partenza. Una volta che hai un'idea di base, forse alcune domande più specifiche possono aiutarti a decidere tu stesso se vuoi utilizzare il test unitario.
cavallo pallido

Colloqui di codice pulito: youtube.com/watch?v=wEhu57pih5w
Kieran

1
Questa non è 1 domanda specifica. Queste sono 5 domande generali.
Raedwald,

9
Meno male che hai posto questa domanda, leggere una risposta di un programmatore che lavora è molto meglio e pertinente rispetto alla lettura di risorse online.
Pratyush Dhanuka,

Risposte:


197

Il test unitario sta, approssimativamente, testando bit del tuo codice in isolamento con il codice di test. I vantaggi immediati che vengono in mente sono:

  • L'esecuzione dei test diventa automatizzabile e ripetibile
  • È possibile eseguire il test a un livello molto più dettagliato rispetto al test point-and-click tramite una GUI

Nota che se il tuo codice di test scrive su un file, apre una connessione al database o fa qualcosa sulla rete, è più appropriatamente classificato come test di integrazione. I test di integrazione sono una buona cosa, ma non devono essere confusi con i test unitari. Il codice dell'unità di prova deve essere breve, dolce e rapido da eseguire.

Un altro modo di esaminare i test unitari è quello di scrivere prima i test. Questo è noto come Test-Driven Development (TDD in breve). TDD offre ulteriori vantaggi:

  • Non scrivi il codice speculativo "Potrei averne bisogno in futuro" - quanto basta per far passare i test
  • Il codice che hai scritto è sempre coperto da test
  • Scrivendo prima il test, sei costretto a pensare a come vuoi chiamare il codice, che di solito migliora il design del codice a lungo termine.

Se non stai eseguendo test di unità ora, ti consiglio di iniziare. Prendi un buon libro, praticamente qualsiasi libro xUnit lo farà perché i concetti sono molto trasferibili tra loro.

A volte scrivere test unitari può essere doloroso. Quando arriva in questo modo, prova a trovare qualcuno che ti aiuti e resisti alla tentazione di "scrivere semplicemente quel dannato codice". Il test unitario è molto simile al lavaggio dei piatti. Non è sempre piacevole, ma mantiene pulita la tua cucina metaforica e vuoi davvero che sia pulita. :)


Modifica: mi viene in mente un malinteso, anche se non sono sicuro che sia così comune. Ho sentito un project manager dire che i test unitari hanno permesso al team di scrivere tutto il codice due volte. Se sembra e si sente in quel modo, beh, stai sbagliando. Non solo scrivere i test di solito accelera lo sviluppo, ma ti dà anche un comodo indicatore "ora ho finito" che non avresti altrimenti.


2
Espanderesti sul tuo punto su come TDD acceleri lo sviluppo?
Martin,

70

Non sono in disaccordo con Dan (anche se una scelta migliore potrebbe non essere quella di rispondere) ... ma ...

Il test unitario è il processo di scrittura del codice per testare il comportamento e la funzionalità del sistema.

Ovviamente i test migliorano la qualità del tuo codice, ma questo è solo un vantaggio superficiale dei test unitari. I veri vantaggi sono:

  1. Semplifica la modifica dell'implementazione tecnica assicurandoti di non modificare il comportamento (refactoring). Il codice testato correttamente dall'unità può essere sottoposto a refactoring / ripulitura aggressivo con poche possibilità di rompere qualcosa senza accorgersene.
  2. Dai agli sviluppatori la fiducia quando aggiungi comportamenti o correzioni.
  3. Documenta il tuo codice
  4. Indica le aree del codice strettamente collegate. È difficile un codice di test unitario strettamente accoppiato
  5. Fornisci un mezzo per utilizzare la tua API e cercare le difficoltà all'inizio
  6. Indica metodi e classi che non sono molto coerenti

Dovresti testare le unità perché è nel tuo interesse fornire un prodotto sostenibile e di qualità al tuo cliente.

Ti suggerirei di usarlo per qualsiasi sistema o parte di un sistema, che modella il comportamento del mondo reale. In altre parole, è particolarmente adatto allo sviluppo aziendale. Non lo userei per programmi usa e getta. Non lo userei per parti di un sistema che sono problematiche da testare (l'interfaccia utente è un esempio comune, ma non è sempre così)

La più grande trappola è che gli sviluppatori testano un'unità troppo grande o considerano un metodo un'unità. Ciò è particolarmente vero se non si capisce Inversion of Control - nel qual caso i test delle unità si trasformeranno sempre in test di integrazione end-to-end. Il test unitario dovrebbe testare comportamenti individuali - e la maggior parte dei metodi ha molti comportamenti.

Il più grande malinteso è che i programmatori non dovrebbero testare. Solo i programmatori cattivi o pigri lo credono. Il ragazzo che costruisce il tuo tetto non dovrebbe provarlo? Il medico che sostituisce una valvola cardiaca non dovrebbe testare la nuova valvola? Solo un programmatore può testare che il suo codice fa quello che intendeva fare (il QA può testare casi limite - come si comporta il codice quando gli viene detto di fare cose che il programmatore non intendeva e il cliente può fare test di accettazione - fa il codice cosa ha pagato il cliente per farlo)


44

La principale differenza tra i test unitari, anziché "aprire un nuovo progetto e testare questo codice specifico" è che è automatizzato , quindi ripetibile .

Se si verifica manualmente il codice, è possibile che il codice funzioni perfettamente, nel suo stato attuale . Ma che dire una settimana dopo, quando hai apportato una leggera modifica? Desideri ripetere il test nuovamente ogni volta che qualcosa cambia nel tuo codice? Molto probabilmente no :-(

Ma se riesci a eseguire i test in qualsiasi momento, con un solo clic, esattamente allo stesso modo, entro pochi secondi , ti mostreranno immediatamente ogni volta che qualcosa si rompe. E se integri anche i test unitari nel tuo processo di compilazione automatizzato, ti avvertiranno dei bug anche nei casi in cui una modifica apparentemente completamente non correlata ha rotto qualcosa in una parte distante della base di codice - quando non ti verrebbe nemmeno in mente che c'è una necessità di ripetere il test di quella particolare funzionalità.

Questo è il principale vantaggio dei test unitari rispetto ai test manuali. Ma aspetta, c'è di più:

  • i test unitari riducono drasticamente il ciclo di feedback sullo sviluppo : con un reparto di test separato potrebbero essere necessarie settimane per sapere che c'è un bug nel tuo codice, a quel punto hai già dimenticato gran parte del contesto, quindi potrebbero volerci ore per trova e corregge il bug; OTOH con unit test, il ciclo di feedback viene misurato in pochi secondi e il processo di correzione dei bug è in genere sulla falsariga di un "oh sh * t, ho dimenticato di verificare questa condizione qui" :-)
  • i test unitari documentano efficacemente (la tua comprensione) del comportamento del tuo codice
  • i test unitari ti costringono a rivalutare le tue scelte di progettazione, il che si traduce in una progettazione più semplice e pulita

I framework di unit test, a loro volta, facilitano la scrittura e l'esecuzione dei test.


+1 Inoltre, la mia parte preferita sul codice di test (specialmente quando viene data una nuova base di codice): dimostra l'uso previsto del codice in prova.
Steven Evers,

34

Non mi è mai stato insegnato il test unitario all'università e mi ci è voluto un po 'per "ottenerlo". L'ho letto, sono andato "ah, giusto, test automatizzati, potrebbe essere bello, immagino", e poi me ne sono dimenticato.

Ci è voluto un po 'più di tempo prima che capissi davvero il punto: supponiamo che tu stia lavorando su un sistema di grandi dimensioni e tu scriva un piccolo modulo. Si compila, lo si mette alla prova, funziona alla grande, si passa al compito successivo. Nove mesi dopo e due versioni dopo qualcun altro apporta una modifica a una parte del programma apparentemente non correlata e rompe il modulo. Peggio ancora, testano le loro modifiche e il loro codice funziona, ma non testano il tuo modulo; diavolo, potrebbero anche non sapere che esiste il tuo modulo .

E ora hai un problema: il codice rotto è nel bagagliaio e nessuno lo sa nemmeno. Il caso migliore è che un tester interno lo trovi prima della spedizione, ma la correzione del codice che alla fine del gioco è costosa. E se nessun tester interno lo trova ... beh, può davvero diventare molto costoso.

La soluzione è test unitari. Incontreranno problemi quando scrivi il codice - il che va bene - ma avresti potuto farlo a mano. Il vero vantaggio è che colpiranno i problemi nove mesi dopo che stai lavorando a un progetto completamente diverso, ma un stagista estivo pensa che sembrerà più ordinato se quei parametri fossero in ordine alfabetico - e quindi il test unitario hai scritto molto tempo fa, e qualcuno lancia le cose all'interno finché non cambia l'ordine dei parametri. Questo è il "perché" dei test unitari. :-)


13

Chipping in the filosofical pro of unit testing and TDD ecco alcune delle loro osservazioni chiave sulla "lampadina" che mi hanno colpito sui miei primi tentativi sulla strada verso l'illuminazione TDD (nessuna originale o necessariamente una novità) ...

  1. TDD NON significa scrivere il doppio della quantità di codice. Il codice di test è in genere abbastanza veloce e indolore da scrivere ed è una parte fondamentale del processo di progettazione e in modo critico.

  2. TDD ti aiuta a capire quando smettere di scrivere codice! I tuoi test ti danno la certezza di aver fatto abbastanza per ora e possono smettere di modificare e passare alla prossima cosa.

  3. I test e il codice lavorano insieme per ottenere un codice migliore. Il tuo codice potrebbe essere errato / difettoso. Il TEST potrebbe essere difettoso / difettoso. In TDD stai scommettendo sulle probabilità che ENTRAMBI siano cattivi / buggy che siano abbastanza bassi. Spesso è il test che deve essere risolto ma è comunque un buon risultato.

  4. TDD aiuta con costipazione di codifica. Sai quella sensazione di avere così tanto da fare che a malapena sai da dove cominciare? È venerdì pomeriggio, se procrastini ancora per un altro paio d'ore ... TDD ti consente di dare una svolta molto rapida a ciò che pensi di dover fare e di far muovere rapidamente la tua programmazione. Inoltre, come i topi di laboratorio, penso che tutti rispondiamo a quella grande luce verde e lavoriamo di più per vederla di nuovo!

  5. Allo stesso modo, questi tipi di designer possono VEDERE su cosa stanno lavorando. Possono andarsene per una pausa succo / sigaretta / iphone e tornare a un monitor che fornisce loro immediatamente un segnale visivo su dove sono arrivati. TDD ci dà qualcosa di simile. È più facile vedere dove siamo arrivati ​​quando la vita interviene ...

  6. Penso che sia stato Fowler a dire: "I test imperfetti, eseguiti frequentemente, sono molto meglio dei test perfetti che non sono mai stati scritti". Lo interpreto come dandomi il permesso di scrivere test dove penso che saranno più utili anche se il resto della mia copertura del codice è tristemente incompleto.

  7. TDD aiuta in tutti i modi sorprendenti lungo la linea. Buoni test unitari possono aiutare a documentare ciò che qualcosa dovrebbe fare, possono aiutarti a migrare il codice da un progetto a un altro e darti una sensazione ingiustificata di superiorità rispetto ai tuoi colleghi non test :)

Questa presentazione è un'eccellente introduzione a tutti i deliziosi test di bontà che comporta.



5

Uso i test unitari per risparmiare tempo.

Quando si costruiscono funzionalità di test della logica di business (o dell'accesso ai dati), spesso è possibile digitare elementi in molte schermate che possono o non possono essere ancora completate. L'automazione di questi test consente di risparmiare tempo.

Per me i test unitari sono una specie di cablaggio di prova modulare. Di solito esiste almeno un test per funzione pubblica. Scrivo test aggiuntivi per coprire vari comportamenti.

Tutti i casi speciali che hai pensato durante lo sviluppo del codice possono essere registrati nel codice nei test unitari. I test unitari diventano anche una fonte di esempi su come utilizzare il codice.

È molto più veloce per me scoprire che il mio nuovo codice rompe qualcosa nei test delle mie unità, quindi controllare il codice e fare in modo che alcuni sviluppatori front-end trovino un problema.

Per i test di accesso ai dati provo a scrivere dei test che non hanno modifiche o ripuliscono dopo se stessi.

I test unitari non saranno in grado di risolvere tutti i requisiti di test. Saranno in grado di risparmiare tempo di sviluppo e testare parti fondamentali dell'applicazione.


4

Questa è la mia opinione su di esso. Direi che il test unitario è la pratica di scrivere test software per verificare che il tuo vero software faccia quello che è destinato. Questo è iniziato con jUnit nel mondo Java ed è diventato una buona pratica in PHP, nonché con SimpleTest e phpUnit . È una pratica di base della programmazione estrema e ti aiuta a essere sicuro che il tuo software funzioni come previsto dopo la modifica. Se disponi di una copertura di prova sufficiente, puoi eseguire importanti refactoring, correzione di errori o aggiungere funzionalità rapidamente con molta meno paura di introdurre altri problemi.

È più efficace quando tutti i test unitari possono essere eseguiti automaticamente.

I test unitari sono generalmente associati allo sviluppo di OO. L'idea di base è creare uno script che imposta l'ambiente per il codice e quindi lo esercita; scrivi asserzioni, specifichi l'output previsto che dovresti ricevere e quindi esegui il tuo script di test usando un framework come quelli sopra menzionati.

Il framework eseguirà tutti i test in base al codice e quindi riporterà il successo o il fallimento di ciascun test. phpUnit viene eseguito dalla riga di comando di Linux per impostazione predefinita, sebbene siano disponibili interfacce HTTP. SimpleTest è basato sul Web per natura ed è molto più facile da avviare e da utilizzare, IMO. In combinazione con xDebug, phpUnit può fornire statistiche automatizzate per la copertura del codice che alcune persone trovano molto utili.

Alcuni team scrivono hook dal loro repository di sovversione in modo che i test unitari vengano eseguiti automaticamente ogni volta che si commettono modifiche.

È buona norma conservare i test unitari nello stesso repository dell'applicazione.


4

Librerie come NUnit , xUnit o JUnit sono obbligatorie solo se vuoi sviluppare i tuoi progetti usando l' approccio TDD reso popolare da Kent Beck:

Puoi leggere Introduzione al Test Driven Development (TDD) o il libro di Kent Beck Test Driven Development: Per esempio .

Quindi, se vuoi essere sicuro che i tuoi test coprano una parte "buona" del tuo codice, puoi usare software come NCover , JCover , PartCover o altro. Ti diranno la percentuale di copertura del tuo codice. A seconda di quanto sei esperto in TDD, saprai se l'hai praticato abbastanza bene :)


3

Il test unitario è il test di un'unità di codice (ad esempio una singola funzione) senza la necessità dell'infrastruttura su cui si basa tale unità di codice. cioè testarlo in isolamento.

Se, ad esempio, la funzione che stai testando si connette a un database ed esegue un aggiornamento, in un test unitario potresti non voler eseguire quell'aggiornamento. Lo faresti se fosse un test di integrazione, ma in questo caso non lo è.

Quindi un unit test eserciterebbe la funzionalità racchiusa nella "funzione" che stai testando senza effetti collaterali dell'aggiornamento del database.

Supponiamo che la tua funzione abbia recuperato alcuni numeri da un database e quindi abbia eseguito un calcolo di deviazione standard. Cosa stai provando a provare qui? Che la deviazione standard sia calcolata correttamente o che i dati vengano restituiti dal database?

In un unit test vuoi solo verificare che la deviazione standard sia calcolata correttamente. In un test di integrazione si desidera verificare il calcolo della deviazione standard e il recupero del database.


3

Il test unitario riguarda la scrittura di codice che verifica il codice dell'applicazione.

La parte Unit del nome riguarda l'intenzione di testare piccole unità di codice (un metodo per esempio) alla volta.

xUnit è lì per aiutare con questo test - sono quadri che aiutano con questo. Parte di ciò sono i test runner automatici che ti dicono quale test fallisce e quali passano.

Hanno anche le strutture per impostare prima il codice comune necessario in ogni test e smontarlo al termine di tutti i test.

Puoi fare un test per verificare che sia stata generata un'eccezione prevista, senza dover scrivere tu stesso l'intero blocco try try.


3

Penso che il punto che non capisci sia che i framework di unit testing come NUnit (e simili) ti aiuteranno ad automatizzare i test di piccole e medie dimensioni. Di solito è possibile eseguire i test in una GUI (come nel caso di NUnit , ad esempio) semplicemente facendo clic su un pulsante e quindi - si spera - vedere la barra di avanzamento rimanere verde. Se diventa rosso, il framework mostra quale test è fallito e cosa è andato storto. In un normale test unitario, spesso si usano asserzioni, ad es. Assert.AreEqual(expectedValue, actualValue, "some description")- quindi se i due valori non sono uguali si vedrà un errore che dice "qualche descrizione: <previstaValore> atteso ma era <attualeValore>".

Quindi, in conclusione, i test unitari renderanno i test più veloci e molto più comodi per gli sviluppatori. È possibile eseguire tutti i test unitari prima di eseguire il nuovo codice in modo da non interrompere il processo di compilazione di altri sviluppatori nello stesso progetto.



3

Il test unitario è una pratica per assicurarsi che la funzione o il modulo che si intende implementare si comporti come previsto (requisiti) e anche per assicurarsi che si comporti in scenari come condizioni al contorno e input non validi.

xUnit , NUnit , mbUnit , ecc. sono strumenti che ti aiutano a scrivere i test.


2

Test Driven Development ha in qualche modo assunto il termine Unit Test. Come un vecchio timer citerò la definizione più generica di esso.

Unit Test significa anche testare un singolo componente in un sistema più grande. Questo singolo componente potrebbe essere una DLL, exe, libreria di classi, ecc. Potrebbe anche essere un singolo sistema in un'applicazione multi-sistema. Quindi, alla fine, Unit Test finisce per essere il test di qualunque cosa tu voglia chiamare un singolo pezzo di un sistema più grande.

Passeresti quindi ai test integrati o di sistema testando il modo in cui tutti i componenti lavorano insieme.


2

Prima di tutto, sia che si tratti di unit test o di qualsiasi altro tipo di test automatizzato (integrazione, carico, test dell'interfaccia utente ecc.), La differenza fondamentale rispetto a ciò che si suggerisce è che è automatizzato, ripetibile e non richiede risorse umane da consumare (= nessuno deve eseguire i test, di solito vengono eseguiti premendo un pulsante).


1

Sono andato a una presentazione sui test unitari a FoxForward 2007 e mi è stato detto di non testare mai nulla che funzioni con i dati. Dopotutto, se esegui test su dati live, i risultati sono imprevedibili e se non esegui test su dati live, non stai effettivamente testando il codice che hai scritto. Sfortunatamente, questa è la maggior parte del codice che faccio in questi giorni. :-)

Recentemente ho fatto uno scatto a TDD mentre stavo scrivendo una routine per salvare e ripristinare le impostazioni. Innanzitutto, ho verificato che potevo creare l'oggetto di archiviazione. Quindi, che aveva il metodo che dovevo chiamare. Quindi, che potrei chiamarlo. Quindi, che ho potuto passare parametri. Quindi, che ho potuto passare parametri specifici. E così via, fino a quando non stavo finalmente verificando che avrebbe salvato l'impostazione specificata, mi permettevo di cambiarlo e poi ripristinarlo, per diverse sintassi diverse.

Non sono arrivato alla fine, perché avevo bisogno della routine, adesso, dannazione, ma è stato un buon esercizio.


1

Cosa fai se ti viene dato un mucchio di schifezze e sembra che tu sia bloccato in uno stato perpetuo di pulizia che sai con l'aggiunta di qualsiasi nuova funzionalità o codice può interrompere il set corrente perché il software attuale è come una casa di carte?

Come possiamo quindi eseguire i test unitari?

Inizi in piccolo. Il progetto che ho appena avviato non ha avuto test unitari fino a pochi mesi fa. Quando la copertura era così bassa, sceglieremmo semplicemente un file che non aveva copertura e fare clic su "aggiungi test".

In questo momento siamo fino a oltre il 40% e siamo riusciti a raccogliere la maggior parte dei frutti a bassa quota.

(La parte migliore è che anche a questo basso livello di copertura, ci siamo già imbattuti in molte istanze del codice che fanno la cosa sbagliata e i test lo hanno colto. Questo è un grande motivatore per spingere le persone ad aggiungere altri test.)


1

Questo risponde al motivo per cui dovresti fare test unitari.


I 3 video seguenti descrivono i test unitari in javascript ma i principi generali si applicano in molte lingue.

Test unitari: i minuti ora risparmieranno ore dopo - Eric Mann - https://www.youtube.com/watch?v=_UmmaPe8Bzc

Test di unità JS (molto buono) - https://www.youtube.com/watch?v=-IYqgx8JxlU

Scrivere JavaScript testabile - https://www.youtube.com/watch?v=OzjogCFO4Zo


Ora sto solo imparando sull'argomento, quindi potrei non essere al 100% corretto e c'è di più rispetto a quello che sto descrivendo qui, ma la mia comprensione di base del test unitario è che scrivi un codice di test (che è tenuto separato dal tuo codice principale) che chiama una funzione nel codice principale con input (argomenti) richiesti dalla funzione e il codice controlla quindi se restituisce un valore di ritorno valido. Se restituisce un valore valido, il framework di unit testing che si sta utilizzando per eseguire i test mostra una luce verde (tutto bene) se il valore non è valido si ottiene una luce rossa e quindi è possibile risolvere immediatamente il problema prima di rilasciare il nuovo codice in produzione, senza il test potresti non aver effettivamente riscontrato l'errore.

Quindi scrivi i test per il tuo codice corrente e crei il codice in modo che superi il test. Mesi dopo, tu o qualcun altro devi modificare la funzione nel tuo codice principale, perché in precedenza avevi già scritto il codice di test per quella funzione, ora esegui di nuovo e il test potrebbe fallire perché il programmatore ha introdotto un errore logico nella funzione o restituisce qualcosa completamente diverso da quello che dovrebbe restituire quella funzione. Ancora una volta senza il test in atto quell'errore potrebbe essere difficile da rintracciare in quanto potrebbe influire anche su altro codice e passerà inosservato.


Inoltre, il fatto di disporre di un programma per computer che esegue il codice e lo verifica invece di farlo manualmente nella pagina del browser pagina per pagina consente di risparmiare tempo (unit test per javascript). Supponiamo che modifichi una funzione utilizzata da alcuni script in una pagina Web e che funzioni perfettamente per il suo nuovo scopo. Ma diciamo anche che, per amor di argomenti, c'è un'altra funzione che hai da qualche altra parte nel tuo codice che dipende da quella funzione appena modificata perché funzioni correttamente. Questa funzione dipendente ora potrebbe smettere di funzionare a causa delle modifiche apportate alla prima funzione, tuttavia senza i test in atto che vengono eseguiti automaticamente dal tuo computer non noterai che c'è un problema con quella funzione fino a quando non viene effettivamente eseguita e tu'

Per ribadire, avere test eseguiti durante lo sviluppo della tua applicazione rileverà questo tipo di problemi mentre stai programmando. Non avendo i test in atto dovresti passare manualmente attraverso l'intera applicazione e anche in questo caso può essere difficile individuare il bug, ingenuamente lo invii in produzione e dopo un po 'un gentile utente ti invia una segnalazione di bug (che non sarà buono come i tuoi messaggi di errore in un framework di test).


È abbastanza confuso quando senti parlare per la prima volta dell'argomento e pensi a te stesso, non sto già testando il mio codice? E il codice che hai scritto funziona come dovrebbe già, "perché ho bisogno di un altro framework?" ... Sì, stai già testando il tuo codice ma un computer è più bravo a farlo. Devi solo scrivere test abbastanza buoni per una funzione / unità di codice una volta e il resto è curato per te dalla potente cpu invece di dover controllare manualmente che tutto il tuo codice funzioni ancora quando apporti una modifica a il tuo codice.

Inoltre, non è necessario testare l'unità del codice se non lo si desidera, ma paga quando il progetto / base di codice inizia a crescere man mano che aumentano le possibilità di introdurre bug.


0

Unit test e TDD in generale consentono di avere cicli di feedback più brevi sul software che si sta scrivendo. Invece di avere una grande fase di test alla fine dell'implementazione, test in modo incrementale tutto ciò che scrivi. Ciò aumenta notevolmente la qualità del codice, come si vede immediatamente, in cui si potrebbero avere bug.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.