Non ci sono sostituti per il test?

3

Entscheidungsproblem ha lanciato una sfida nel 1926,

Can we write an algorithm that checks to see if a proof can be solved without actually doing the proof?

Alan Turing ha ridotto il problema di Halting a questo problema, dicendo nel suo articolo: "Corrispondente a ciascuna macchina di calcolo 'essa' costruiamo una formula 'Un (it)' e mostriamo che, se c'è un metodo generale per determinare se 'Un (it)' è dimostrabile, allora c'è un metodo generale per determinare se 'esso' stampa mai 0 "

Quindi, implica che un programma di lavoro (algoritmo) come prova di una soluzione a un problema, rende il problema dire calcolabile.

Ma testare che la prova in realtà verifica, se un programma effettivamente soddisfa i suoi requisiti ed esegue le operazioni desiderate, allora il programma di lavoro è considerato una prova di soluzione.

Di seguito è riportato il tipico modello di caso d'uso con requisiti e parametri di accettazione. Sotto il framework Agile SCRUM, abbiamo user story per lo stesso.

Nonèpossibileprogettareunasoluzioneconunapprocciocome Progettare per contratto per creare una soluzione priva di bug? Al fine di evitare test.

    
posta user1787812 14.09.2017 - 14:34
fonte

6 risposte

10

Ci sono linguaggi come Haskell che hanno sistemi di tipi molto sofisticati che possono eliminare alcune classi di errori. Ho sentito (anche se non l'ho sperimentato personalmente) che se riesci a correggere i tuoi tipi, un programma Haskell spesso viene eseguito correttamente al primo tentativo.

Detto questo, no, non c'è alcun sostituto per i test. Il motivo è che ogni sistema software non banale ha anche una specifica dei requisiti, e è necessario testare per dimostrare che i requisiti sono stati soddisfatti. I requisiti senza test di accettazione non sono affatto requisiti; sono auguri.

    
risposta data 14.09.2017 - 14:55
fonte
5

Ho pensato di conoscere poco il soggetto, penso che tu stia mescolando due concetti differenti:

  • Non essere in grado di risolvere un problema teorico
  • Un bug

La tua citazione riguarda la soluzione di un problema teorico, tuttavia stai chiedendo un programma privo di bug. Solitamente risolvendo un problema teorico non si prendono in considerazione i problemi "fisici / reali" dell'informatica. Ovviamente quando scrivi un'applicazione per un cliente, se la tua soluzione si imbatte in uno di questi problemi fisici avrai ciò che chiamiamo "un bug" anche se il tuo algoritmo funziona teoricamente. Quindi un bug può essere:

  • uno che non risolve il problema specificato correttamente (non del tutto, casi limite, ...)
  • Prestazioni temporali: il tuo algoritmo funziona ma in produzione ci vuole troppo tempo per essere eseguito.
  • Consumo di memoria: errori OOM
  • Prestazioni spaziali: scrivi dati e non hai più spazio.
  • Precisione numerica (virgola mobile ...) che termina con risultati errati, dividendo per 0, ...
  • ...

Per concludere: nella migliore delle ipotesi potresti dimostrare di essere in grado di dire cosa farà un algoritmo in un mondo perfetto in cui tutta quella materia "fisica" non esiste, ma non di più.

Ecco un riferimento DailyWTF sull'argomento.

    
risposta data 14.09.2017 - 16:35
fonte
4

In senso molto ampio, ci sono sostituti per i test e ne hai suggerito uno. Come nella vita reale, tuttavia, i sostituti sono spesso inferiori a quello che sostituiscono.

La domanda che stai ponendo ha una lunga storia nella filosofia e in quel dibattito l'empirismo è diventato la credenza dominante. È il cuore della scienza, come lo comprendiamo ora.

Un grande filosofo scientifico del suo tempo, Empedocles ha creato la teoria della visione delle emissioni . Questa teoria sosteneva che la visione era il risultato di raggi emessi dagli occhi. Era logicamente valido ed era considerato corretto per secoli da persone davvero intelligenti come Platone. Ma ora sappiamo che questo è completamente sbagliato. Quando usi il ragionamento puro per giungere a una conclusione, devi fare delle ipotesi; non c'è modo di aggirarlo. Ed è quelle supposizioni che possono portare al fallimento.

Diciamo che è possibile utilizzare la progettazione per contratto per "provare" una soluzione corretta e utilizzare alcuni strumenti per creare software. Si presume che lo strumento non abbia bug. Walfrat enumera una serie di altre possibili insidie. Non puoi evitare che la prova del budino sia nel mangiare.

    
risposta data 14.09.2017 - 17:28
fonte
2

Sì, questo tipo di software è scritto per avionica e altre aree in cui la normativa lo richiede. La progettazione per contratto non è esattamente il modo in cui viene eseguita, ma per il tipo di software che probabilmente stai scrivendo, è un buon approccio. Crei una gerarchia di prove:

  • Precondizioni, postcondizioni e invarianti per i tipi di livello più basso.
  • Devi essere in grado di dimostrare la correttezza dei tipi di livello più basso: idealmente utilizzando strumenti automatici, non a mano. Ciò significa che hai bisogno di una lingua del contratto.
  • I tipi di livello superiore hanno invarianti di livello superiore, basati sulle dimostrazioni fornite dai tipi di livello inferiore.
  • A livello di applicazione, puoi provare gli invarianti delle applicazioni.

Con gli strumenti corretti, è possibile assemblare componenti corretti precedentemente provati per creare programmi collaudati. Tuttavia, potresti non pensare più a questo come a scrivere software ... potresti utilizzare solo strumenti grafici.

Ecco un progetto interessante che è rilevante sia per la tua domanda sia per i tipi di vulnerabilità continuamente introdotte utilizzando lo sviluppo tipico del software (cioè test anziché prove): link

    
risposta data 15.09.2017 - 01:43
fonte
1

Prima di iniziare, penso che valga la pena menzionare Philip Wadler "Propositions as Types ", che offre un'eccellente panoramica della storia antica della teoria della computabilità con un'enfasi sulla logica del primo ordine. Di questo c'è anche una presentazione video . Consiglio vivamente chiunque sia interessato a questo argomento, guarda il video e leggi il giornale.

Alan Turing reduced his Halting problem to this problem, by saying in his paper: "Corresponding to each computing machine 'it' we construct a formula 'Un(it)' and we show that, if there is a general method for determining whether 'Un(it)' is provable, then there is a general method for determining whether 'it' ever prints 0"

Sì, se Entscheidungsproblem è computabile allora il problema di interruzione è computabile. Il problema dell'arresto è stato provato come non classificabile, pertanto il problema di Entscheidungsproblem è inaccessibile. In altre parole, un algoritmo generale per dimostrare se qualsiasi programma arbitrario è corretto o meno non esiste. Tuttavia, ciò non significa che non esistono algoritmi per provare se alcuni programmi sono corretti o meno.

So, it implies, that a working program(algorithm) as a proof of a solution to a problem, makes the problem say computable.

Se con "lavoro" intendi "corretto" (inclusa la condizione di interruzione), allora sì, possiamo dire che un algoritmo provabilmente corretto che risolve un problema è la prova che il problema è computabile. Tuttavia, come sai che un programma è corretto? Sappiamo che non può esserci un algoritmo generale per dimostrarne la correttezza. Questo ci lascia due opzioni:

  • Possiamo (provare a) fare la prova da soli. Tuttavia, l'inconoscibilità del problema Entscheidungs implica che alcune cose non sono dimostrabili. Se ci imbattiamo in uno di questi problemi, le prove formali sono un vicolo cieco. Inoltre, non c'è modo (in generale) di sapere anche se stiamo cercando di dimostrare qualcosa che è indimostrabile. Quindi potremmo spendere qualsiasi quantità di risorse verso un problema che non risolveremo mai.
  • Possiamo (provare a) esprimere il programma (e il problema) come sottoinsieme dei problemi per i quali abbiamo un algoritmo per fare automaticamente la prova. Nota, tuttavia, che dobbiamo dimostrare che prover è corretto. Quindi, alla fine, qualcuno deve fare una prova a mano ad un certo punto.

Anche se teoricamente possibile, entrambe le opzioni richiedono molto tempo. Se non siamo in grado (o non vogliamo) di fare una di queste cose, il vero test è tutto ciò che ci rimane. Verificando che i risultati corretti siano prodotti almeno per alcuni dei possibili input, approssimiamo in una certa misura una prova completa.

Inoltre, ci sono molti aspetti pratici che le prove formali di correttezza non affrontano. Alcuni di loro sono:

  • Prestazioni di tempo e spazio. Non ci fa bene se il nostro programma provabilmente corretto non calcola un risultato prima della morte termica dell'universo. O se fallisce a causa di un sovraccarico dello stack. O se esaurisce la memoria principale o qualche altra risorsa. Per essere pratici, avremmo bisogno di provare anche queste proprietà. La correttezza teorica di per sé non è sufficiente.
  • Abbiamo espresso correttamente il problema nel sistema di correzione automatica? Ad esempio, stiamo effettivamente risolvendo il problema che pensiamo stiamo risolvendo.
  • Stiamo risolvendo il problema giusto ? Un programma probabilmente corretto è inutile se risolve il problema sbagliato.
  • Ogni volta che cambiano i requisiti, il problema cambia. Quindi ogni cambiamento richiede una riformulazione del problema e una nuova dimostrazione di correttezza.

Penso che questo sia il motivo per cui c'è stata relativamente poca spinta nel settore verso prove formali. Tuttavia, ciò non significa che non usiamo mai le prove. Ad esempio, il controllo di tipo statico viene utilizzato per dimostrare che un programma è ben tipizzato. Questo può eliminare una certa classe di errori, ma non può di per sé escludere tutti gli errori.

In alcuni casi, è possibile provare un programma corretto verificando che produce il risultato corretto per tutti i possibili input. In questi casi, il test stesso può effettivamente essere la prova della correttezza. La maggior parte delle volte, però, lo spazio di input è troppo grande (o addirittura infinito) perché una tale strategia sia pratica (o persino possibile). Quindi, in generale, è impossibile dimostrare un programma corretto tramite test.

Tuttavia, possiamo dimostrare che un programma è non corretto tramite test. Ciò accade osservando un fallimento in un test. Quindi l'utilità del testing si riduce ad avere "buoni" test che coprono proprietà "utili" e che hanno "molti di loro". Possiamo scrivere test a mano, ma non molti. Se disponiamo di proprietà ben definite che desideriamo testare, possiamo utilizzare strumenti come QuickCheck per generare automaticamente molti test per noi .

Quindi direi che design-by-contract, in generale, non sostituisce test, ma piuttosto complimenti .

    
risposta data 20.09.2017 - 21:49
fonte
0

So, it implies, that a working program(algorithm) as a proof of a solution to a problem, makes the problem say computable.

Sì, se hai un programma che risolve un problema, hai dimostrato che il problema è computabile.

But testing that proof actually verifies, if a program actually satisfies its requirements and performs the desired operations, then working program is considered proof of solution.

Bene - il programma deve funzionare correttamente per diversi input (specialmente i casi limite). E controllando se il tuo programma restituisce l'output previsto per input diversi è ... testing.

E la dimostrazione che il tuo programma funziona per ogni input è nella maggior parte dei casi impossibile ... o almeno molto difficile. Quindi testare è solo un approccio più fattibile.

    
risposta data 14.09.2017 - 22:43
fonte

Leggi altre domande sui tag