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...
Se avete seguito i passi del post precedente
e provate a lanciare il test dovrebbe aprirsi una finestra che si chiude quasi istantaneamente.
Proviamo ora a simulare il click ad un pulsante. Per prima cosa aggiungiamo il controllo alla main window ricordandoci
di dargli un nome (nel nostro caso buttonControl).
Lo xaml dovrebbe essere qualcosa di analogo:
<Window x:Class="WPFAndNUnit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Button Name="buttonControl" >A button</Button>
</Canvas>
</Window>
Ora...
Gli acceptance test servono a verificare che una user story
sia stata realizzata correttamente, quindi sono test definiti insieme al cliente o addirittura scritti dal cliente.
L'applicazione che stiamo scrivendo utilizza wpf, quindi la nostra necessità è quella di poter aprire finestre,
cliccare sui pulsanti, ecc. all'interno di un test automatico.
Esistono approcci alternativi a quello che propongo in questo post, come ad esempio le
TestApi, le quali utilizzano le
automation api mentre per l'input del mouse e della tastiera
utilizzano l'API SendInput.
Le TestApi fanno molto di più di quello che a noi serve e quindi ho cercato un approccio più adatto al nostro caso.
Per...
Nel mio precedente post ho rivolto la domanda su come testare la classe Alarm senza modificarla. Matteo Baglini ha provato a rispondere alle domande esprimendo qualche perplessità proprio sull'ultima. In effetti rispondere è meno banale di quello che sembra.
Riporto nuovamente la classe Alarm originale:
public class Alarm
{
private const double LowPressureTreshold = 17;
private const double HighPressureTreshold = 21;
Sensor _sensor = new Sensor();
bool _alarmOn = false;
private long _alarmCount = 0;
public void Check()
{
double psiPressureValue = _sensor.PopNextPressurePsiValue();
...
Affrontare l'integrazione il prima possibile. Una feature è consegnata solo quando gira in produzione. Le feature in code complete non sono consegnate. Su questo punto ho sentito molte rimostranze diciamo che il concetto è di anticipare tutto ciò che si puo' anticipare in modo da non avere sorprese alla fine.
Cercare di capire qual è l'obiettivo da raggiungere e partire da quello, lasciando perdere tutto il resto. Ridurre lo scope il più possibile.
Imparare a dire di no è difficile e costa fatica, ma nel...
Prendo spunto dal post di Luka su come ridurre la complessità del codice eliminando i conditional statement come if, swicth ecc. per fare qualche considerazione.
Premetto che ho aderito alla campagna anti-if e che sono pienamente d'accordo ad avere un codice con una complessità ciclomatica molto bassa.
Ci sono if che secondo me non è conveniente eliminare.
Partiamo da un esempio:
Ho un software che simula una tastiera elettronica con la tastiera del PC e ad ogni tasto premuto corrisponde un suono. Nel caso in cui...
Fishbowl conversation - Una tecnica per moderare una discussione tra molte persone
Questa settimana allo xpug di Milano,
che si è tenunto in Sourcense, eravamo
in più di venti persone e dovevamo discutere sull'
architettura esagonale.
Matteo, il nostro coach, ci ha proposta la
Fishbowl conversation,
che si è rivelata una tecnica semplice ed efficace.
Si prendono cinque sedie e le si mettono al centro della stanza. Quando ci sono quattro persone sedute,
solo quelle quattro,
possono...
Chi ha dovuto cercare un appartamento in affitto a Milano sa di cosa sto parlando, per gli altri, sembreranno un cumulo di stronzate.
Sostituire le parole in grassetto che trovate in un annuncio con il corrispettivo a destra:
Centralissimo: probabilmente in una cabina telefonica c'è più spazio
Luminossisimo: Sesto piano senza ascensore.
Ideale per studenti: l'arredamento è stato acquistato in una discarica ed una persona sola non se lo può permettere
Ideale per coppie: Una persona sola non se lo può permettere e il padrone non vuole studenti.
Zona XXX (qualunque nome): Come minimo è a Gessate.
Loft: negozio di macelleria trasformato in apparamento.
Solo referenziati: non vogliamo...
In questi giorni un mio amico mi ha chiesto un softwarino (chissà perchè quando si chiede un favore si usa il diminutivo ) che partendo da una tabella di Access generasse una serie di Moduli F24 compilati.
Il modulo dell'F24 da compilare si può scaricare dal sito dell' agenzia delle entrate
A questo punto mi manca una libreria, possibilmente open source, per aggiungere le informazioni necessarie.
Dopo un paio di ricerche ho provato iTextSharp porting...
Sto sviluppando un'applicazione che utilizza le Windows Forms e dovrà supportare più lingue. Vorrei condividere la soluzione che sto progettando/implementando.
L'idea è quella di utilizzare la classe
ResourceManager la quale si occupa di leggere
le stringhe in base alla lingua corrente. Vediamolo in pratica:
Per prima cosa creiamo un progetto che chiameremo MultilingualWindowsApplication
...
Tutti i passi necessari per creare una macro per Visual Studio 2005 che esegua un comando passando come parametro il path dell'item selezionato nel Solution Explorer...
In questo post analizzerò il problema di testare il risultato di un operazione che ritorni un oggetto complesso anzichè un semplice value type (int, double, ...), nel post propongo una serie di possbili soluzioni.
Supponiamo di avere una classe che calcola alcune statistiche su una serie di valori:
class StatisticCalculator
{
public StatisticValues Calculate(double[] values)
{
StatisticValues result = new StatisticValues();
// ...
return result;
}
}
(Questa classe soffre di un problema di design, il metodo Calculate fa troppe cose insieme; in un progetto...
Nel progetto su cui sto lavorando avevo bisogno di un controllo Datagrid flessibile e semplice da usare.
Mi sono ricordato dell'elenco di progetti
open source legati al mondo .NET creato da Jeff Atwood per un
contest con in
palio 10.000$ (5.000 da Jeff e 5.000 da Microsoft).
In quell'elenco viene segnalato il progetto
SourceGrid.
Leggendo la documentazione, a prima vista molto ben fatta, ci sono due tipi di...
In questi giorni cercavo un tool per creare velocemente Sequence Diagram ed ho trovato sdedit.
Ad una prima occhiata sembra sufficientemente semplice da usare, in quanto i sequence diagram si specificano tramite un linguaggio la cui sintassi è descritta qui.
Ho provato a buttarne giù uno alla veloce ed ecco il risultato:
...
E' estate, tempo di vacanze, quale migliore occasione per migliorare il proprio inglese. L'inglese di uso comune, magari imparando qualche nuovo idiom, visto che quello tecnico lo utilizziamo per il nostro lavoro.
Partiamo con English as a Second Language Podcast una serie di podcast in inglese in cui vengono usati termini semplici per introdurre concetti più complessi. I podcast sono stati studiati per chi si trova ad un livello lower intermediate perchè vengono pronunciati al 70% della velocità a cui un inglese normalmente parla.
In questo podcast vengono dati alcuni consigli su come migliorare la conoscenza della lingua.
Ho trovato ben fatto...
In questi giorni ho avuto la necessità di eseguire n operazioni in gruppi al max di x operazioni contemporaneamente. In pratica devo estrarre alcune informazioni da pagine web e per ottimizzare le performance eseguo 5 (parametro configurabile) scaricamenti contemporaneamente da altrettanti thread.
Per gestire il tutto ho usato la classe Semaphore, vediamo come.
Partiamo dal main:
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4
5 namespace MultithreadingExperiments
6 {
7 static class Program
8 {
9 [STAThread]
10 static void Main()
11 {
12 Semaphore pool = new Semaphore(5, 5);
13 Random rand = new Random();
14 List threads = new List();
15 for (int i =...
Nel progetto che sto sviluppando è presente una GUI molto complessa, per cui ho provato a cercare del materiale che mi aiutasse a progettare tramite TDD l'architettura.
Ho trovato un articolo in formato pdf molto interessante: Presenter First: Organizing Complex GUI Applications for Test-Driven Development
Segnalo anche questo post per testare eventi su interfacce tramite Rhino Mocks: Using Rhino Mocks To Unit Test Events on Interfaces
Ed infine gli articoli di Martin Fowler: Supervising Controller e Passive View
Oggi ho avuto la necessità di rimpiazzare il seguente testo che corrisponde alla visualizzazione di un byte array dalla Watch Window del debugger di Visual Studio:
[0] 210 byte
[1] 7 byte
[2] 0 byte
[3] 0 byte
[4] 6 byte
[5] 0 byte
[6] 0 byte
...
Nel seguente modo:
210, 7, 0, 0, 6, 0, 0, ...
In modo da poter creare agevolmente tramite codice c# un array di byte. Chiaramente il buffer è molto più lungo altrimenti avrei impiegato meno tempo a modificare il testo a mano. Armato di...
Sono rimasto favorevolmente colpito dal tempo di startup di SharpDevelop un IDE Open Source per .NET.
Ho visto che il setupkit ad un certo punto esegue l'utility NGen (Native Image Generator). La quale come documentato sulle MSDN migliora le performance in:
Native images load faster than MSIL because they eliminate the need for many startup activities, such as JIT compilation and type-safety verification.
Native images require a smaller initial working set because there is no need for the JIT compiler.
Inoltre nel file AssemblyInfo.cs dei sorgenti di SharpDevelop hanno inserito i seguenti attributi:
// Use hard-binding for ICSharpCode.SharpDevelop:
[assembly: Dependency("ICSharpCode.Core", LoadHint.Always)]
[assembly: Dependency("ICSharpCode.TextEditor",...
Segnalo l'articolo Asynchronous Code Blocks su CodeProject usa gli Anonymous Methods e i ManagedIOCP.
Quante volte di fronte ad una segnalazione di un problema da parte di un utente abbiamo pensato o detto "Questo è impossibile...".
Trovo molto efficace il Tip 33 del libro The Pragmatic Programmer:
If It Can't Happen, Use Assertions to Ensure That it Won't
Il modo più semplice per seguire questo consiglio è quello di usare il metodo Assert del framework. Segue un semplice esempio:
public void WriteString(string s){ Debug.Assert(s != null); // Segue il codice della funzione}
Si deve fare attenzione che il codice della Assert non abbia side effects e, soprattutto, non inserire codice che deve essere eseguito per...
Pensavo che con MbUnit non ci fosse la possibilità di impostare il timeout di un test. Oggi ho trovato questo post del blog testingReflections.com il quale spiega che basta impostare la property Timeout dell'attributo [TestFixture]:
[TestFixture(TimeOut = 1)] public class MyFixture{ ...}
Ho provato a lanciare un test che impiegasse più tempo del timeout e TestDriven.NET mi ha segnalato, correttamente in output:
TestCase 'MyFixture.SetUp.Test1.TearDown' failed: Fixture Timed Out MbUnit.Core.Exceptions.FixtureTimedOutException Message: Fixture Timed Out Source: StackTrace:
Quello che trovo poco intuitivo è che sia una property della TestFixture e non un attributo da aggiungere ad un metodo di test, come avviene su TeamSystem, come nel...
la prima differenza sta nei reference da:
MbUnit.Framework a: Microsoft.VisualStudio.QualityTools.UnitTestFramework
Segue una tabella, incompleta con il mapping degli attributi e delle classi, usate dal mio progetto da MbUnit a Visual Studio:
MbUnit
Visual Studio
Descrizione
[TestFixture]
[TestClass]
Identifica una classe di test
[Test]
[TestMethod]
Identifica un metodo di test
[SetUp]
[TestInitialize]
Viene eseguito prima di ogni metodo di test di una TestFixture
[TearDown]
[TestCleanup]
Viene eseguito dopo ogni metodo di test di una TestFixture
[Ignore]
[Ignore]
Il test non viene eseguito
RowTest
???
Serve per passare dei parametri ad un test. Non ho trovato l'equivalente in Visual Studio
???
Timeout
Specifica il Timeout di un test. Non ho trovato l'equivalente in MbUnit
Assert
Assert
L'hanno mantenuta uguale incredibile
ArrayAssert
CollectionAssert
Verifica se due array sono ugualiRispetto a TestDriven.NET viene indicato...
Supponiamo di avere un Assembly che ci mette a disposizione il servizio di invio E-mail:
public class EmailSender { public virtual void Send(string from, string to, string message) { Console.WriteLine("Email from:{0}\nTo:{1}\nMessage:{2}", from, to, message); } }
Ovviamente l'implementazione nel mondo reale sarà un pò più complessa, ma per il nostro scopo è più che sufficiente.
Il nostro codice ora è in produzione e siamo tutti felici. Ad un certo punto il responsabile della sicurezza che per definizione non ha a cuore noi developers, decide che tutto ciò che viene mandato via mail deve essere loggato.
Orrore oltraggio! devo modificare...
Il codice:
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url); HttpWebResponse response = (HttpWebResponse) request.GetResponse();
Mi generava la seguente eccezione:
HttpWebRequest request = (HttpWebRequest) System.Net.WebException was unhandled Message="The server committed a protocol violation. Section=ResponseStatusLine"
Ho indagato un pò sulla causa e nelle MSDN ho trovato questo articolo; in pratica per risolvere il problema si deve editare il file App.Config del proprio progetto (se il file non è presente lo si può aggiungere dal menu Project, Add New Item... e selezionare Application Configuration File) inserendo la seguente sezione:
<configuration> <system.net> <settings> <httpwebrequest useUnsafeHeaderParsing="true" /> </settings> </system.net></configuration>
Attenzione che come riportato nell'articolo:
By...
Ho realizzato alcuni UserControl in cui la parte di disegno l'ho scritta all'interno del metodo OnPaint. Oggi dopo una modifica che lanciava un'eccezione a causa di un bug ho notato questo:
Quella simpatica X rossa non la disegno io, ma il framework, facendo clic su Continue mi rimane la form con la X rossa.
La cosa che non mi piace è che si dà la possibilità all'utente di far continuare a funzionare il programma.
Per riprodurre il problema basta creare un progetto Windows Application ed aggiungere alla form principale il seguente codice: protected override void OnPaint(PaintEventArgs e){ base.OnPaint(e); throw...
Ho iniziato ad usare i Live Templates di Resharper. Devo dire che sono molto comodi. Esempio se scrivo foreach ottengo:
Dopo aver premuto tab:
Ciò che mi fa risparmiare parecchio tempo è che se esiste una variabile membro della classe di tipo ArrayList automaticamente viene inserita nel foreach. (Come nell'immagine precedente).
Oggi mi serviva un nuovo live template che non è presente tra quelli standard, in sintesi quando scrivo tryf e premo tab vorrei venisse inserito il codice: try{}finally{}
Dal menu Resharper selezionando Options e poi Live Templates si possono vedere quelli già esistenti ed aggiungerne di nuovi. Dopo...
Lavoro su solution che hanno decine di progetti al loro interno e mi trovo spesso nel noiosissimo lavoro di chiudere i nodi di progetto uno per uno a mano. Purtroppo non esiste un comando già pronto in Visual Studio.NET 2003; per risolvere il problema ho trovato questa macro su code project:
Sub CollapseAll() ' Get the the Solution Explorer tree Dim UIHSolutionExplorer As UIHierarchy UIHSolutionExplorer = DTE.Windows.Item( _ Constants.vsext_wk_SProjectWindow).Object() ' Check if there is any open solution If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then Return End If ' Get the...