Stanco di prove non semantica per compensare la tipizzazione dinamica - suggerimenti?
-
09-10-2019 - |
Domanda
ho usato per fare un sacco di programmazione web in Rails (PHP prima) prima ho iniziato a studiare ingegneria informatica.
Da allora, ho fatto un sacco di lavoro scolastico in C, e alcune cose personali in Objective-C (roba Mac). Ho imparato a tipizzazione statica amore.
Ma ora sto avendo a che fare un po 'di sviluppo web professionale (freelance) e hanno raccolto Rails, ancora una volta. Mi sto trovando davvero fastidioso per scrivere non semantici prove di verifica. Mi è stato sempre quelli gratuitamente dal C e compilatori Objective-C. Amavo colpire Costruire e avere il sistema di controllo tutto il mio codice per vedere che A può chiamare B, B può chiamare qualche libreria oscura C, ecc Tutto quello che dovevo fare era prova la semantica. Ma con Rails, io sono il compilatore. :(
Qualcuno ha calpestato questo stesso percorso? Sono le mie uniche opzioni per lo sviluppo web ASP.NET MVC con C # e Java + x quadro? Alla ricerca di alcuni suggerimenti, o anche una certa simpatia ...: P
A proposito, io faccio un riferimento specifico alla Rails, piuttosto che di Ruby, perché non mi dispiace la natura dinamica di Ruby per cose semplici come script o cosa no. Ma dal momento che Rails dipende da tante gemme e dal momento che uno di solito aggiunge un certo numero di altre gemme, la tipizzazione dinamica diventa un problema.
Grazie!
modifica
Ho seguito il suggerimento di PST e guardato in Scala. Nel leggere il libro Programming in Scala, scritto dal creatore del linguaggio, Martin Odersky, ho mai incontrato questo po 'di testo che per molti versi esprime le mie preoccupazioni e un po' di più. lettura molto interessante.
Tratto da pagina 52 di programmazione di Martin Odersky a Scala:
Scala è staticamente tipizzato
Un tipo statico classifica sistema variabili ed espressioni secondo i tipi di valori in loro possesso e calcolare. Scala si distingue come un lingua con una statica molto avanzata sistema tipo. Partendo da un sistema di tipi di classe nidificati molto simile Java, ti permette di parametrizzare i tipi con i generici, di combinare i tipi utilizzando intersezioni, e per nascondere i dettagli di tipi che utilizzano i tipi astratti. questi danno una solida base per la costruzione e comporre i propri tipi, in modo da in grado di progettare interfacce che sono alla stesso tempo sicura e flessibile per l'uso.
Se ti piace dinamica lingue come Perl, Python, Ruby, o Groovy, è potrebbe trovare un po 'strano che sistema di tipo statico di Scala è elencato come uno dei suoi punti di forza. Dopo tutto, l'assenza di un tipo statico sistema è stato citato da alcuni come un dei principali vantaggi di linguaggi dinamici. La maggior parte dei argomenti comuni contro tipi statici sono che fanno programmi troppo prolisso, impediscono i programmatori di esprimersi come vogliono, e rendono impossibile certi modelli di dinamica modifiche dei sistemi software.
Tuttavia, spesso questi argomenti non fanno andare contro l'idea di tipi statici in generale, ma contro tipo specifico sistemi che sono percepiti come troppo verbose o troppo poco flessibile. Per esempio, Alan Kay, l'inventore del il linguaggio Smalltalk, una volta osservò: “Io non sono contro i tipi, ma non lo faccio conoscere di qualsiasi tipo systemsthat non sono dolore completo, così mi piace ancora dinamica digitazione “.
Speriamo di convincere voi in questo libro che il sistema di tipi di Scala è ben lungi dall'essere essere un “dolore completo”. In realtà, indirizzi ben due dei soliti le preoccupazioni circa tipizzazione statica: verbosità viene evitata tipo passante inferenza e flessibilità si ottiene attraverso pattern matching e diversi nuovi modi di scrivere e tipi di composizione. Con questi impedimenti fuori del modo, i vantaggi classici di tipo statico sistemi possono essere meglio apprezzati. Tra i più importanti di questi benefici sono proprietà verificabili astrazioni programma, cassetta di sicurezza refactoring, e una migliore documentazione.
proprietà verificabili
tipo statico systeli può dimostrare la assenza di alcuni errori run-time. Per esempio, possono dimostrare proprietà come: booleani non sono mai aggiunto ai numeri interi; variabili private Non si accede dall'esterno loro classe; funzioni sono applicate al giusto numero di argomenti; solo stringhe vengono mai aggiunti a una serie di stringhe.
non vengono rilevati altri tipi di errori dai sistemi di tipo statico di oggi. Per esempio, che di solito non rilevare funzioni non-terminazione, un array delimita violazioni, o divisioni da zero. Essi potranno anche non rileva che il vostro programma non è conforme alla sua specifica (supponendo che vi sia un spec, che è!). sistemi di tipo statico sono quindi stati licenziati da alcuni come non essere molto utile. L'argomento va che poiché tali sistemi tipo può solo rilevare errori semplici, mentre test di unità forniscono più ampia la copertura, perché perdere tempo con tipi statici affatto?
Noi crediamo che questi argomenti perdere il punto. Anche se un tipo statico Sistema non può certo sostituire l'unità di test, può ridurre il numero di unit test necessari curando alcune proprietà che altrimenti necessità di essere testato. Analogamente, unità test non può sostituire tipizzazione statica. Dopo tutto, come detto Edsger Dijkstra, test può dimostrare solo la presenza di gli errori, non la loro assenza. Così la garantisce che tipizzazione statica dà può essere semplice, ma sono reali garanzie di una forma nessuna quantità di test in grado di fornire.
refactoring sicuro
sistema Un tipo statico fornisce una rete di sicurezza che permette di apportare modifiche ad una base di codice con un alto grado di fiducia. Si consideri ad esempio un refactoring che aggiunge un ulteriore parametro a un metodo. In uno staticamente linguaggio tipizzato si può fare il cambiamento, ri-compilare il sistema e semplicemente fix tutte le linee che causano un errore di tipo. Una volta che hai finito con questo, sono sicuri di aver trovato tutti i luoghi che necessità di essere cambiato. Lo stesso vale per molti altri refactoring semplici come modifica di un nome di metodo, o in movimento i metodi di una classe ad un altro. Nel tutti i casi un controllo di tipo statico fornire abbastanza garanzia che il nuovo sistema funziona proprio come il vecchio.
Documentazione
tipi statici sono documentazione del programma che viene controllato dal compilatore per correttezza. A differenza di un normale commento, un tipo di annotazione non può mai essere fuori data (almeno non se il file sorgente che lo contiene ha recentemente approvato una compilatore). Inoltre, compilatori e ambienti di sviluppo integrati può fare uso di annotazioni di tipo a fornire una migliore aiuto contesto. Per esempio, uno sviluppo integrato ambiente in grado di visualizzare tutte le membri disponibili per una selezione determinare il tipo statico del Espressione su cui la selezione è fatta e alzando lo sguardo tutti i membri del quel tipo.
Soluzione
Questa è una delle mie "lamentele" su linguaggi dinamici. Voglio testare per la semantica, non digitare errori ;-) Detto questo, un buon test framework / setup è davvero un must in tutte le situazioni non banali e buon codice-copertura e requisiti testato è / sono importanti.
Se si vuole andare giù il percorso statico-digitando su JVM (ho), vi consiglio vivamente guardando Scala . Venendo da Ruby, è molto meno doloroso (e in realtà un sacco di divertimento in modi diversi) che andare a Java. Si arriva a "mantenere" le cose che diamo per scontato - una sintassi delle espressioni-based, chiusure, la possibilità di omettere tipi in molti luoghi (non aperto come Ruby, ma ottieni tipo in fase di compilazione controllo ;-), tutto (*) - è-un-oggetto OO, unificato di accesso metodi, capacità di DSL costrutto facilmente, e lo zucchero - e ottenere i vantaggi di un linguaggio a tipizzazione statica con inferenza di tipo locale, pattern matching, un quadro per la raccolta relativamente ricca, e integrazione decente con Java (tra cui le numerose web-quadri, ci sono alcuni quadri Scala-specifici e che sfruttano il linguaggio Scala).
C # 3.0 / 4.0 (e .NET3.5 +) non è troppo malandato o (ma evitare C # 2.0, che ora si spera una reliquia), con l'introduzione di LINQ / chiusure, inferenza di tipo base e altri bella lingua presenta lo trovo "accettabile" per la maggior parte delle attività (prendere una congettura come darei Java come linguaggio ;-). Tuttavia, C # è un linguaggio CLR-bersaglio (non v'è / era una porta NET Scala, ma non sono sicuro dello stato - non è la piattaforma di destinazione principale però).
Da quando ho accennato Scala, Vorrei anche ricordare F # (ormai una lingua "ufficiale" NET), che adotta l'approccio "funzionale con OO" essere simile a OCaml - Scala è più il contrario e lo descriverei come "OO con funzionale". Ho sentito argomenti a favore / contro F # rispetto a C # w.r.t il sistema tipo, ma non hanno alcuna esperienza pratica con F #. Si può o non può, come il cambiamento di paradigma.
Felice di codifica.
Altri suggerimenti
Come si menziona Rails, e dato che sei diventato interessati a Scala, si dovrebbe verificare Ascensore . Ecco un 2008 intervista con il suo creatore, e un 2009 presentazione (video), che collego perché, anche se vecchio, si confronta con Ascensore alternative in altre lingue.
Se Ascensore non è la vostra cosa, però, certi che ci sono altri web Scala quadri .
Questo tipo di test non è in genere fatto in Rails. Invece di essere infastidito da doverlo fare, non considerare preoccupante su di esso. O forse fare un lavoro migliore di spiegare il motivo per cui si pensa che è un problema, poiché la maggior parte Rails programmatori non.
Aggiorna
La persona che ha scritto test_include_with_order_works
è fare in modo che Rails interpreterà un simbolo stesso come una stringa in questo caso particolare. Non mi sembra come qualcosa che avrebbe dovuto prova, dal momento che Rails ha già fornito e testato questa funzionalità per voi. Francamente, sono un po 'sorpreso che qualcuno sarebbe nemmeno preoccuparsi se non un simbolo funzionerà come una corda. Sappiamo tutti che il possibile e spesso lo fa.
In generale, credo che il quadro Rails deve garantire le cose che non lo fai in modo che la sua attuazione sarà conforme al suo design. Credo che la filosofia di lavoro in lingue dinamicamente tipizzati è che il codice client non passerà nei parametri che si rompono i metodi stanno chiamando. Se lo fanno, ottengono alcun uso di chiamare i metodi. Non dovete sprecare il vostro tempo fare in modo che i vostri metodi getterà eccezioni quando fornito troppi parametri, quando il vostro metodo può altrettanto facilmente (e dovrebbe) ignorare i parametri extra.
Quindi, io non sono sicuro se gli esempi che hai fornito in realtà dimostrano la necessità di test non-semantica in Rails.