Tips
In questo post vedremo come accedere ad un database sqlite utilizzando Ruby.
La scelta di sqlite è dovuta alla sua estrema semplicità di gestione, in quanto il database consiste in un unico file.
Per prima cosa occorre installare una libreria per poterlo utilizzare da ruby. Basta digitare da terminale gem install sqlite3-ruby.
Ora creiamo il file sqlite-test.rb con il seguente contenuto:
require 'sqlite3'
require 'test/unit'
class DatabaseTest < Test::Unit::TestCase
def setup
@db = SQLite3::Database.new 'test.db'
end
def teardown
@db.close
end
def test_create
assert...
In questo post illustrerò un modo per sviluppare un sito web che usa Sinatra usando la pratica del TDD. Per poter provare gli esempi occorre aver seguito
i passi del mio precedente post.
Sinatra, come altri framework scritti in Ruby, aderisce allo standard Rack. In sintesi basta realizzare un oggetto
che risponde al messagio call, prende un hash come parametro e risponde con un vettore di tre elementi: lo status code, l'header http e il body.
Un esempio di un oggetto che rispetta lo standard è:
class HelloWorld
def call(env)
...
Un collega mi ha suggerito una tecnica interessante quando si è in presenza di codice legacy.
Nella nostra codebase abbiamo creato l'astrazione ICommitCommand per modificare i dati delle risorse esterne nei setup dei un test di accettazione in cui utilizziamo
i sistemi reali e non dei fake. Nel caso specifico la scrittura su un indice di Lucene e la modifica di alcuni dati nel db.
interface ICommitCommand
{
void Execute();
}
Inizialmente avevo creato l'oggetto:
class LuceneCommand : ICommitCommand
{
LuceneClient _client;
public LuceneCommand(LuceneClient client)
{
_client = client;
}
public void Execute()
{
...
Dopo che ci è scappato un errore nell'html del sito su cui stiamo lavorando, abbiamo deciso di scrivere un test
che validi l'html prodotto.
Per raggiungere l'obiettivo utilizziamo l'utility Tidy che si puo' scaricare da
qui
È un piccolo eseguibile a cui si puo' passare un html e verificare che non contenga errori.
Il codice del test è piuttosto semplice:
[Test]
public void ValidateHtml()
{
var html = new WebClient().DownloadString(@"http://someurl.com");
process = new Process();
process.StartInfo.FileName = "tidy.exe";
process.StartInfo.Arguments = "-e";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError...
Oggi mi sono imbattuto in un problema imprevisto e voglio condividerlo perché potrebbe tornare utile a chi non padroneggia Javascript.
Supponiamo di avere un oggetto definito come segue:
function AnObject() {
this.value = 1000;
var set_value = function(new_value) {
this.value = new_value;
};
this.start = function() {
set_value(5);
}
}
L'oggetto ha un field pubblico chiamato value, un metodo pubblico chiamato start ed un metodo privato chiamato...
Prima di proseguire consiglio la lettura della
prima parte e della
seconda parte.
In questo post affronteremo l'argomento dei mock object. Una prima tentazione potrebbe essere quella di cercare una libreria di mock per
Javascript, ma vista la sua natura dinamica proviamo a farne a meno.
Partiamo da un esempio per introdurre l'argomento. Supponiamo di voler testare il seguente metodo:
function show_alert(text) {
alert(text);
}
Ovviamente se eseguiamo tale metodo vedremo comparire una message box. Vediamo se riusciamo a testare l'interazione.
Per prima cosa occorre che quando viene chiamato alert venga eseguita una function nostra e non quella standard.
Occorre anche che quando il test...
Nello scorso post
ho descritto come scrivere test automatici per Javascript. Uno degli svantaggi della soluzione proposta
sta nel ricordarsi di chiamare le function di test. Infatti se guardiamo il codice della pagina html:
$(document).ready(function(){
sum_test();
})
Vediamo la chiamata a sum_test che contine il test. Se abbiamo molti di questi metodi la manutenzione dell'elenco puo'
diventare piuttosto noiosa e error-prone.
Una soluzione è quella di creare un oggetto Javascript che esegua automaticamente tutte le function
che terminano per _test.
In Javascript esiste l'oggetto globale window il quale contiene, tra le altre cose,...
Ultimamente sto lavorando con il linguaggio Javascript.
All'inizio ho avuto qualche difficoltà, perché la sintassi è molto
lontana da quella dei linguaggi con cui ho sviluppato in passato o sviluppo abitualmente (C#, C++, Java),
ma con il tempo ha iniziato a piacermi, soprattutto per la semplicità e potenza espressiva.
L'attività che sto svolgendo è la copertura di test di codice esistente e un refactoring
per migliorarne la leggibilità, in modo da poter aggiungere funzionalità limitando la
probabilità di regressioni.
Per i test automatici utilizziamo QUnit.
Vediamo un esempio. Supponiamo di avere il file sum.js con il seguente metodo da testare:
function sum() {
...
Supponete di avere due oggetti uno di tipo A e l'altro di tipo B, dove A chiama un metodo di B e viceversa.
In pratica esiste una dipendenza circolare tra i due oggetti (il discorso si puo' ampliare facilmente ad n oggetti).
Proviamo a visualizzare tale interazione con un communication diagram (ne avevo già parlato in questo
post).
Come vedete dal disegno il refactoring risulta molto semplice da capire. In pratica creiamo un nuovo oggetto di tipo C che chiama
gli oggetti di tipo A e tipo B ed in questo modo abbiamo tolto la referenza circolare.
Non so se esiste già da qualche parte...
Ogni tanto, nello sviluppo software, emerge qualche meme come ad esempio: tutte le dipendenze devono essere
disaccoppiate tramite un interface, tutte gli oggetti devono essere creati tramite factory, l'accesso ad un database
deve avvenire tramite un ORM, il TDD genera un buon design ecc.
Cosa hanno in comune tutte le frasi precedenti? Semplice: creano scorciatoie per evitare di pensare.
Sarebbe bello se potessimo scrivere codice seguendo alla lettera un manuale, ma sarebbe anche terribilmente noioso
e probabilmente verremmo sostituiti da qualche tipo di bot.
Prendiamo la prima affermazione: tutte le dipendenze devono essere disaccoppiate tramite un interface
e cerchiamo di capire da dove nasce questa esigenza. Il...
Full Tips Archive