Software/verktøy

Her skriver jeg om ulike verktøy som interesserer meg som utvikler. Produktivitetsverktøy og Visual Studio add-ins, continuous integration tools, ulike .net biblioteker.., alt får plass i denne kategorien.

AutoIt

Er du lat, og vil at noen gjør alle de kjedelige og repetetive oppgavene for deg? Hvis du i tillegg befinner deg på Microsoft’s Windows-plattform bør du i såfall ta en titt på automasjonsspråket AutoIt!

autoit

AutoIt er et BASIC-lignende språk med bibloteker og verktøy for å lage makroer. Gjennom kode kan du enkelt bevege og klikke med musen, starte programmer, sende tastetrykk fra tastaturet, og generelt simulere og automatisere alt det du kan gjøre som en bruker i Windows.

AutoIt-kodefiler kan normalt kjøres ved dobbeltklikk på maskiner som har AutoIt installert. I tillegg kan skriptene kompileres til en komprimert, frittstående, eksekverbar fil som kan kjøres på andre maskiner.

La oss se på litt kode

La oss igjen lage en løsning på Eulerproblem nummer 1, hvor vi skal finne summen av alle tall under 1000 som er multipler av enten 3 eller 5. Jeg bruker den imperative løsningsmodellen, og har valgt å splitte det opp i to separate funksjoner – en for å finne ut om et tall skal inkluderes, og en funksjon med en løkke som summerer opp tallene.

10 Func MultipleOf3Or5($value)
11     Return Mod($value, 3) == 0
12         OR Mod($value, 5) == 0
13 EndFunc
14 
15 Func SolveEuler1()
16     Dim $sum = 0
17     For $i = 1 to 999
18         If MultipleOf3Or5($i) Then
19             $sum += $i
20         EndIf
21     Next
22     Return $sum
23 EndFunc

Ikke spesielt spennende dette her. Men nå kommer rosinen i pølsa..

For å skrive ut resultatet vil jeg benytte noen av de tingene som AutoIt egner seg best til, nemlig å manipulere vinduer. I koden nedenfor åpner jeg først Notepad, skriver ut svaret i vinduet, og lukker så programmet.

Når Notepad lukkes vil det dukke opp en advarsel om at jeg har endringer som ikke er lagret. Det er jeg forberedt på, og sender tastekombinasjonen Alt+S, som trigger lagre-dialogen. Der skriver jeg inn stien jeg ønsker å lagre svaret mitt til, og sender igjen Alt+S som fullfører lagringen, og Notepad avsluttes.

25 Run("notepad")
26 Dim $answer = SolveEuler1()
27 WinWaitActive("Untitled - Notepad")
28 Send("The answer is " & $answer & "{ENTER}")
29 
30 ; Provoke unsaved changes dialog, click "Save"
31 WinClose("Untitled - Notepad")
32 WinWaitActive("Notepad", "Save")
33 Send("!s") ; Alt+S for "Save"
34 
35 ; Enter save location in file dialog, click "Save"
36 WinWaitActive("Save As")
37 Send(@MyDocumentsDir & "\EulerProblem1_Answer.txt")
38 Send("!s") ; Alt+S

Når jeg kjører dette skriptet vil jeg se at Notepad dukker opp, at svaret tastes inn, og at skriptet går gjennom lagre-dialogene. Til slutt er svaret lagret i My Documents-katalogen min.

Hvorfor bruke tid på AutoIt?

AutoIt er ikke et interessant språk i seg selv. Men for automatisering av Windows er det perfekt, og et slikt verktøy burde alle utviklere på den plattformen beherske.

Mange anbefaler også AutoIt som et bra sted å begynne å lære seg programmering. BASIC-syntaksen er enkel å forholde seg til, og den direkte interaksjonen mot brukergrensesnittet kan være motiverende og inspirerende i starten.

Svakheter

AutoIt er en-trået. Dette gjør det vanskelig (men ikke umulig) å programmere asynkrone og paralelle ting.

Personlig synes jeg dessuten at BASIC-lignende språk er veldig slitsomme – dette til tross for at jeg først og fremst var en Visual Basic-programmerer for noen år tilbake, og til tross for at mitt aller første språk var en BASIC-dialekt, nemlig AMOS på Amiga.

Et annet språk/verktøy du kan vurdere er AutoHotKey. I stedet for å fokusere på å simulere brukere og automatisere vinduer er AutoHotKey først og fremst laget for å knytte makroer til spesielle tastekombinasjoner. Selve AutoHotKey-språket er litt mer kryptisk enn AutoIt.

Hvordan komme i gang?

Du finner AutoIt på autoitscript.com. Når du installerer det får du i tillegg et utviklingsmiljø basert på SciTE-editoren. Her er kompilatoren integrert, og man har tilgang til hjelpefiler med den informasjon man trenger for å begynne å lære språket og verktøyet, og for å lage scrips som utfører de aller fleste oppgaver.

JavaScript revolution

JavaScript har i løpet av 15 år gått fra å være et forferdelig mareritt til å bli en av de mest spennende og pulserende teknologiene man kan holde på med. Det skjer så mye rundt JavaScript for tiden at det rett å slett er vanskelig å henge med.

Denne artikkelen er et forsøk på å skape en oversikt over viktige open-source biblotek det kan være nyttig å vite om. I takt med modningen av HTML5 har jeg blitt mer og mer interessert i JavaScript-utvikling det siste året. Denne listen inneholder noen ting jeg har testet ut, men vel så mange ting jeg ikke har jobbet med, men ønsker å få sett nærmere på i tiden fremover.

Finner du noen åpenbare mangler i listen min – spennende biblotek eller rammeverk jeg har utelatt – så må du slenge inn en kommentar!

De generelle bibloteken

Først og fremst bør alle webutviklere kjenne til det jeg tenker på som de store, generelle JavaScript/Ajax-biblotekene. Jeg tenker da på Prototype, DOJO, Moo Tools, YUI Library, og sist men ikke minst jQuery, som er det som nå er aller mest populært. Siden jeg bruker jQuery selv, ser jeg ingen åpenbar grunn til å se på de andre.

jQuery har som kjent også et hav av plugins for alt mulig man kan komme til å trenge. Det kan være viktig å lete litt blant dem før man begynner å lage noe selv.

JavaScript også utenfor browseren

JavaScript er et kraftig språk med noen av de raskeste, dynamiske tolkerne (interpreters) som finnes. Og det brukes til langt mer enn å bare lage websider. Node.js er det mest populære rammeverket som tar JavaScript server-side, og er basert på Google’s V8-motor som kjører i Chrome. Jeg har lekt meg litt med Node tidligere, og synes det er veldig spennende.

CommonJS er et initiativ som skal definere et standard API for JavaScript utover det som språket selv definerer. Fokuset her er nettopp på det å bruke JavaScript utenfor browseren – til å lage server-applikasjoner, kommandolinje-verktøy, desktop GUI-applikasjoner, og hybridapplikasjoner i f.eks. Titanium og Adobe AIR. Titanium har jeg også testet litt, og det er et veldig spennende alternativ hvor du lager programmer som kjører på Windows/Mac/Linux ved å bruke HTML og CSS pluss en valgfri kombo av JavaScript, Ruby og Python.

Når jeg sier JavaScript så mener jeg forresten egentlig CoffeeScript. Dette er en rykende ferskt språk som kompileres ned til JavaScript. Man kan bruke alt som finnes av biblotek fra JavaScript-verdenen, men koder selv i en mye mere behagelig syntaks. Jeg har allerede konvertert teamet mitt på jobben til å bruke CoffeeScript fremfor JavaScript, og anbefaler deg til å vurdere det samme.

Noen sentrale byggeklosser

RequireJS laster JavaScript-filer og moduler. Å bruke dette vil gjøre løsningen din både raskere og enklere å holde oversiktelig etterhvert som den vokser seg større. RequireJS gjør det enklere for deg som utvikler å lage større JavaScript-løsninger, samtidig som den optimaliserer selve deploymenten av løsningen.

Underscore.js er en verktøykasse som gir JavaScript bedre støtte for funskjonell programmering. Her finner du rundt 60 generelle funksjoner som each, map, select, reduce, range osv.

HTML5_Logo_128

Modernizr er et biblotek som skal hjelpe deg å bygge neste generasjons HTML5- og CSS3-løsninger som også vil virke for dem som bruker browsere som ikke støtter de nye featurene. Dvs., Modernizr utfører ikke mirakler – det får ikke disse nye tingene til å virke i gamle browsere – men det forteller deg hva som virker, slik at du kan ta høyde for det og kode deretter.

WebSockets har potensialet til å revolusjonere hvordan vi lager rike webapplikasjoner, og er noe av det aller mest spennende som ligger i HTML5-standarden (en bra presentasjon om dette). Socket.IO er et biblotek som skal gi deg realtime apps, uavhengig av hvilken browser eller mobil-device brukeren har. Det bruker WebSockets om det er tilgjengelig, og faller tilbake på andre løsninger om det ikke er det. Socket.IO kan også brukes på server-siden i f.eks. Node.js.

Og så må jeg få nevne Date.js, et lite biblotek som lar deg jobbe med datoer i JavaScript på en enkel måte.

MVC-aktige rammeverk

Nå har vi kommet til de rammeverkene som skal legge til rette for å lage JavaScript-tunge webløsninger. Jeg tenker da spesielt på såkalte single-page JavaScript applications. GMail er et typisk eksempel på en sånn app.

Backbone.js gir deg (meget kort fortalt) muligheten til å lage datamodeller, definere views, og å knytte disse sammen med en toveis databinding. Backbone.js bruker også Underscore.js for å tilby et rikt API.

Sammy.js er et lite men veldig spennende rammeverk som lar deg designet single-page JavaScript apps etter en restfull tankegang med ruter (routing). Du kan bruke ulike template/rendering-motorer, og Sammy føles både enkel og elegant.

Brunch beskrives også som et lettvekts rammeverk for å lage HTML5-applikasjoner med fokus på eleganse og enkelhet. Det kombinerer CoffeeScript, Backbone.js, Underscore.js, jQuery og flere andre biblotek til en pakke for å lage MVC-lignende løsninger.

Andre rammeverk jeg har fått med meg som er populære, men som virker noe større (men ikke dårligere av den grunn) inkluderer SproutCore, Cappuccino og Sencha. For rendering / templates finnes det enda flere muligheter, som Eco, Stitch, mustache, EJS, pure og meld. Ett av disse bør man nok lære seg å bruke.

Grafikk og effekter

Det finnes mange, gode biblotek for å lage ulike typer grafer, men jeg orker ikke liste dem her. Det finnes også flere biblotek som fokuserer på å tilby ulike JavaScript-effekter, som f.eks. Script.aculo.us.

$fx() er et annet biblotek for å animere HTML-elementer. Med bare 4k JavaScript lar det deg endre CSS-properties over en tidslinje på en ganske så elegant måte. Er du kreativ kan du lage noen veldig spennende websider med dette kompakte scriptet.

Er du en av dem som behersker 3D-grafikk er WebGL noe du bør se på. Ved å bruke canvas-elementet i HTML5 gir det deg 3D rett i browseren, uten å bruke plug-ins. WebGL er basert på OpenGL.

Og er du helt sprø så lærer du deg Processing.js. Processing er et programmeringsspråk og en utviklingsplattform for å lage elektronisk kunst og visuelt design, og Processing.js er en portering av dette til JavaScript. Ta en titt på linken for å se hva du kan gjøre med det.

Testdreven JavaScript

Når det kommer til testing så virker det som om det mest populære rammeverket en stund har vært QUnit (det er det jQuery bruker). Et alternativ som bruker begreper som er mer kjente for dem som driver med BDD er Jasmine. I tillegg kan det være nyttig å bruke Sinon.JS for mocking, og jsTestDriver for å kjøre testene.

Buster.JS er et annet testrammeverk som det snakkes mye om, men som ikke har nådd noen release enda. Det virker som det vil være kompatibelt med QUnit, bruke Sinon.JS for mocking, ha BDD-syntax for dem som ønsker det, og ha støtte for det samme som man finner i jsTestDriver. Her blir det altså en mere komplett løsning i én pakke.

Headless browser

Helt til slutt vil jeg nevne PhantomJS. Dette er et kommandolinje-verktøy som inneholder en “usynlig” web-browser. Man kan gjøre alt man kan gjøre med en vanlig browser, og styre den med JavaScript. Dette egner seg veldig godt til ting som testing av webapplikasjoner, “webskraping”, og mye, mye mer om du har litt fantasi.

Mye å sette klærne i her altså. Har du noen erfaring med disse biblotekene som du vil dele?

Pomodoro

POMODORO1

Pomodoro er en teknikk for å administrere sin egen tid mens man jobber, en teknikk som skal hjelpe deg å fokusere på det du holder på med, og gjøre deg mer effektiv.

Det fungerer slik at man jobber i sprinter a 25 minutter om gangen – de kalles “pomodori”, med en fem minutters tvungen pause mellom hver. Etter fire pomodori tar man en noe lengre pause.

Når man jobber skal man være helt fokusert. Hvis man blir forstyrret er det viktig at man håndterer dette riktig. Typiske forstyrrelser er at man selv begynner å tenke på noe urelatert til oppgaven man holder på med. Da skal man raskt skrive ned hva man tenkte, slik at man kan “glemme det” og fortsette på oppgaven.

Jeg ble introdusert for Pomodoro på QCon-konferansen i London i 2010, og har siden den gang hatt en intensjon om å prøve det ut. For noen uker siden fant jeg et ganske bra Adobe Air-basert verktøy for å holde track på prosessen som het Pomodairo. Og nå har jeg endelig fått testet ut Pomodoro-teknikken over litt tid.

Det finnes mange slike Pomodoro-vertøy, men dette er nok det beste jeg har funnet. I tillegg til å holde track på tiden, og gi alarm når man skal starte og stoppe å jobbe, så lar det deg også legge inn oppgavene man jobber på. Man kan estimere hvor mange pomodori man tror man vil bruke på hver oppgave, og man kan enkelt registrere inn forstyrrelsene underveis. Til slutt gir Pomodairo deg oversikt over hvordan det har gått.

POMODORO2

Her er rapporten som viser hvordan de ulike dagene har gått. Som du ser får jeg en delta som viser avviket mellom estimat og faktisk antall pomodori, og antall forstyrrelser hver dag.

POMODORO3

Og i dette skjermbildet kan jeg søke i og analysere alle forstyrrelsene.

Etter å ha forsøkt pomodoro i et par uker føler jeg at dette er noe jeg bør fortsettet med – i alle fall deler av tiden. Under pomodoriene jobbet jeg intenst, og med veldig høyt fokus. I begynnelsen opplevde jeg også litt stress, fordi jeg jobbet med en klokke som telte ned, og forsøkte å bli “ferdig” med ting før klokken ringte. Denne intensiteten og stresset bør nok kontres med perioder hvor jeg ikke bruker teknikken. Av og til er det viktig å slappe av og bare la tankene vandre.

Det var også noen ganger litt vanskelig å faktisk ta den obligatoriske pausen, når jeg var midt oppi noe spennende.

Jeg sitter og jobber i landskap med hele teamet rundt meg. Dette fører til veldig god kommunikasjon og kunnskapsdeling, men er også utfordrende i forhold til fokus. Det mest positive med pomodoro er at man blir veldig bevisst på avbrytelser, både eksterne og interne. Ikke bare slutter man å sjekke e-post og twitter i tide og utide, men man klarer etterhvert å blokkere ut både urelevante tanker og ekstern støy som ellers ville ha forstyrrer.

Etter et par uker med Pomodoro føler jeg at jeg har blitt litt bedre på å holde fokuset oppe over lengre tid om gangen. Jeg anbefaler alle å forsøke!

Til slutt vil jeg bare nevne at Pomodoro også skal egne seg bra for parprogrammering. Når jeg jobber i par føler jeg skjelden at det er noe problem å holde fokuset oppe, men da er det kanskje viktigere at man får de obligatoriske pausene, slik at man ikke blir helt utslitt.

Hvis du har noen erfaringer med bruk av Pomodoro, enten det er i par eller solo, så er jeg veldig interessert i å høre om det.

Git

git-logoI dag har jeg holdt ziptalk om Git – det raske versjonskontrollsystemet. Jeg har brukt git litt på privaten, spesielt opp mot Github da selvfølgelig, men nå følte jeg det var på tide å lære det orntlig, og å se om det kunne gi teamet vårt noen fordeler. Vi bruker subversion i dag, men har behov for å bruke branching mer effektivt – i forhold til hyppigere deployment – og jeg tror Git kan være veien å gå.

Linus Torvalds has quipped about the name “git”, which is British English slang for a stupid or unpleasant person: “I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git.”

The official Git wiki also gives a number of alternative explanations and backronyms for the name, including “Global Information Tracker”.

Ziptalken var basert på det tutorialet du finner på gitref.org, og anbefales til alle som trenger en introduksjon. Ellers finnes det en gratis online-bok som virker grei på progit.org, og git wikien en selvfølgelig også en naturlig referanse..

Ellers må jeg nevne at jeg er en typisk kommandolinje-fyr, og har stort sett brukt git på den måten. Men i går installerte jeg litt porselen i form av Git Extensions for Windows, og sålang må jeg si at jeg er imponert. Denne integrasjonspakken bør gjøre git spiselig for de fleste.

Implementere toveis SMS i .Net

At en tjeneste benytter toveis SMS vil si at den både kan motta meldinger fra brukere (mobile originated, MO), og at den kan sende meldinger til brukere (mobile terminated, MT). Å lage en slik tjenste som bruker PSWinCom’s SMS gateway er veldig enkelt, takket være gode integrasjonsgrensesnitt. I denne artikkelen vil jeg implementere en slik tjeneste i .NET / C#.

Jeg registrerer meg hele tiden på ulike nettsteder, som alle ber meg om å spesifisere et passord. Og da er det veldig dumt å bruke det samme passordet hele tiden. Jeg ønsker derfor å kunne sende kodeord PASSORD til et bestemt telefonnummer, og få tilbake et garantert tilfeldig passord jeg kan bruke. Denne tjenesten er altså tiltenkt sikkerhetsfanatikere med dårlig fantasi.

toveis_sms

For å lage tjenesten vil jeg implementere en web service som jeg kan hoste i IIS. Tjenesten har to integrasjonspunkt: Ett SOAP-endepunkt må implementeres for å motta SMS-meldinger fra gateway’en, og i tillegg må tjenesten kalle en tilsvarende SOAP-tjeneste som gateway’en eksponerer når vi ønsker å sende melding tilbake til brukeren som ber om et passord.

For å lage en slik tjeneste trenger jeg produktet Gateway standard (produktark), og PSWinCom må registrere URLen til tjenesten min for kodeordet jeg vil bruke. Det er mulig å få demokonto for dem som ønsker å teste mulighetene. Det kan også være lurt a lage sin egen test-gateway (fakeway) om man vil teste tjenesten uten å nødvendigvis sende og motta SMS’er – det vil komme en egen blogpost om hvordan man enkelt kan gjøre dette.

Grensesnitt for innkommende meldinger

Å bruke SOAP-grensesnittet for mottak av SMS-meldinger i .Net er veldig enkelt. Først starter du Visual Studio Command Prompt, og bruker kommandoen wsdl for å generere et service interface.

Kommando for å generere SMS receive service interfaces:
wsdl /namespace:RandomPasswordService /serverInterface https://secure.pswin.com/SOAP/Receive.asmx?wsdl

Dette vil resultere i en fil som heter SMSReceiveInterfaces.cs. Den inneholder blant annet et interface som heter ISMSReceiveSoap. For å kunne ta imot meldinger må vi lage en web service som implementerer dette interfacet.

Grensesnitt for utgående meldinger

For å sende SMS-meldinger fra passord-tjenesten kan vi bruke et lite bibliotek, PSWinCom SMS Gateway Client for .NET, som kan lastes ned fra pswin.com. Om du ønsker å generere en SOAP proxy selv kan du gjøre det i stedet. All informasjon du trenger finner du i dokumentasjonen over grensesnittene.

RandomPasswordService-prosjektet

Jeg oppretter så et nytt ASP.NET Web Application prosjekt i Visual Studio som skal bli passord-tjenesten vår. Jeg sletter Default.aspx, og legger i stedet til SMSReceiverInterfaces.cs som jeg genererte, samt en referanse til PSWinCom.Gateway.Client.

Deretter legger jeg til en web service jeg kaller Password.asmx. Det er i denne servicen vi skal implementere interfacet for å håndtere innkommende meldinger. Til slutt legger jeg til en ny klasse-fil jeg kaller RandomDotOrg.cs hvor jeg vil implementere generering av passord, og rydder litt opp i dll-referansene.

CropperCapture[72]

Jeg er nå klar til å implementere tjenesten. I web servicen sin code behind sørger jeg først for å endre WebService namespace til http://pswin.com/SOAP/Receive (ikke glem dette!). Deretter sier jeg at Password skal arve fra ISMSReceiveSoap, og får Visual Studio til å generere stubs for metodene jeg trenger. Etter et par minutter er tjenesten ferdig:

    1 using System;
    2 using System.Web.Services;
    3 using PSWinCom.Gateway.Client;
    4 
    5 namespace RandomPasswordService
    6 {
    7     [WebService(Namespace = "http://pswin.com/SOAP/Receive")]
    8     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    9     [System.ComponentModel.ToolboxItem(false)]
   10     public class Password : WebService, ISMSReceiveSoap
   11     {
   12         #region ISMSReceiveSoap Members
   13 
   14         public ReturnValue ReceiveSMSMessage(IncomingSMSMessage m)
   15         {
   16             try
   17             {
   18                 Send(new Message
   19                 {
   20                     ReceiverNumber = m.SenderNumber, // return to sender
   21                     SenderNumber = m.ReceiverNumber,
   22                     Text = RandomDotOrg.GetNewPassword(),
   23                 });
   24             }
   25             catch { /* Log this !! */ }
   26             return new ReturnValue { Code = 200 };
   27         }
   28 
   29         public ReturnValue ReceiveDeliveryReport(DeliveryReport dr) {
   30             throw new NotImplementedException(); // not interested
   31         }
   32 
   33         public ReturnValue ReceiveMMSMessage(IncomingMMSMessage m) {
   34             throw new NotImplementedException(); // not interested
   35         }
   36         #endregion
   37 
   38         private void Send(Message message)
   39         {
   40             var smsClient = new SMSClient()
   41             {
   42                 Username = "",          // your Gateway username
   43                 Password = "",          // your Gateway passord
   44                 PrimaryGateway = "",    // the Gateway URL
   45                 SecondaryGateway = ""// backup Gatetway URL
   46             };
   47             smsClient.Messages.Add(0, message);
   48             smsClient.SendMessages();
   49         }
   50     }
   51 }

Metoden ReceiveSMSMessage kalles av gatewayen når det ankommer en ny melding. Interfacet har et par metoder til, for å ta imot meldingskvitteringer og MMS-meldinger, men de er jeg ikke interessert i her.

Jeg har laget en egen metode for å sende ut meldinger (linje 38), og det er her jeg bruker PSWinCom.Gateway.Client. Her kan du hente inn brukernavn, passord etc. fra konfigurasjonsfilen eller lignende.

Merk at jeg må returnere statuskode 200 fra ReceiveSMSMessage for å bekrefte at jeg klarte å ta imot meldingen. Hvis jeg ikke gjør dette vil gatewayen forsøke å sende meldingen på nytt (i henhold til definerte retry-regler).

Det er selvsagt mye som kan gjøres i forhold til feilhåndtering etc. Jeg ville normalt også inkludert endel logging. I tillegg kunne jeg ha benyttet meg av informasjonen i den innkommende meldingen, som hvilket kodeord som ble benyttet, eller hva den øvrige meldingsteksten var. Jeg kunne for eksempel lagt opp en mulighet for at brukerne kunne spesifisere hvor langt passordet skulle være ved å sende PASSORD n, hvor n er antall tegn.

Random passord

Det eneste som gjenstår er å implementere generering av passord. Til det vil jeg bruke en tjeneste som heter random.org, som gir meg ekte tilfeldighet, noe jeg ikke kan få til selv på windows. Her er GetNewPassord, som gjør et web-kall til random.org for å hente en random streng á 8 tegn.

    1 using System.Net;
    2 
    3 namespace RandomPasswordService
    4 {
    5     public static class RandomDotOrg
    6     {
    7         public static string GetNewPassword()
    8         {
    9             using (var webClient = new WebClient())
   10             {
   11                 return webClient
   12                     .DownloadString(
   13                     "http://www.random.org/strings/?" +
   14                     "num=1&len=8&digits=on&upperalpha=on" +
   15                     "&loweralpha=on&unique=on&format=plain&rnd=new")
   16                     .Trim();
   17             }
   18         }
   19     }
   20 }

(Merk at random.org har en quota per IP-adresse. Les guidelines for automated clients om du ønsker å benytte deg av random.org.)

Så der har du det altså, en komplett, toveis SMS-tjeneste i .Net / C# (som i tillegg kommuniserer med en ekstern tjeneste) på 71 linjer. Så hvis du har en god idé til en SMS-tjeneste bør du i alle fall ikke la kompleksiteten stopp deg, for så veldig mye enklere blir det ikke. 

Som nevnt skal jeg også skrive en artikkel om hvordan du kan teste tjenesten din uten å bruke PSWinCom’s gateway, så følg med om du er interessert i det.

Relatert artikkel: Dagens sitat via SMS (énveis SMS m/Ruby og XML over TCP).

Avhengighetsisolering (a.k.a. Mocking) i .NET

mocking_frameworks I min forrige blogpost, om utenfra-og-inn programmering, snakket jeg om at mocking er en teknikk vi bruker når vi praktiserer testdreven utvikling. For å kunne utvikle én og én enhet om gangen er det fordelaktig å kunne erstatte enhetens avhengigheter med “jukseobjekter”.

Roy_Pic_BW_Small Enhetstest-guru Roy Osherove (som jobber for TypeMock) påpeker at vi ofte misbruker begrepet mocking. Martin Fowler har også skrevet en mye lest artikkel kalt Mocks Aren’t Stubs om dette: En MOCK er ifølge dem et objekt som brukes til å registrere og validere forventninger, mens en STUB er et objekt som inneholer predefinerte svar. FAKE er et objekt med en faktisk implementasjon, som for eksempel en in-memory database som erstatter en faktisk database. Vi bruker normalt en blanding av disse i testene våre, og jeg ser ikke noen spesiell grunn til å kunne skille mellom dem.

Roy anbefaler å bruke begrepet avhengighetsisolering for å samle disse teknikkene, og kaller TypeMock for et avhengighetsisoleringsrammeverk (det ble veldig fint på norsk gitt). Jeg bruker likevel mocking-begrepet, siden det er mest kjent – alle forstår hva jeg mener da.

Uansett hva man kaller dem – fordelen med disse falske objektene er at de er til å stole på. Mens faktiske implementasjoner kan gi ulike svar (basert på eksterne data, randomness etc.) kan vi fullstendig kontrollere hvordan en fake skal oppføre seg i enhver situasjon. For eksempel kan vi simulere ulike unntasksituasjoner ved å få dem til å kaste exceptions på kommando.

Testene blir i mange tilfeller også enklere å skrive, gitt at du behersker et godt mockingrammeverk. Testene kan dessuten eksekvere raskere, fordi avhengighetene blir “lettere” enn de faktiske avhengighetene.

Litt kontroverielt

Jeg føler meg forpliktet til å nevne at det er en viss diskusjon rundt bruk av mocking. Det er mange som hevder at mocking er unødvendig, og kanskje til og med uønsket, om man designer systemet sitt “riktig”. Jeg var selv av den oppfatning for ikke så alt for lenge siden. Men etter å ha forsøkt det en stund endret jeg mening.

Likevel innser jeg at mocking kan missbrukes – spesielt de kraftigste rammeverkene. Når man skriver tester er det viktig å teste adferd, ikke implementasjon – knytter man dem for hardt mot implementasjonen blir testene sårbare for endringer i systemet. Du kan få en grei oversikt over denne debatten ved for eksempel å lese et par sentrale spørsmål på stackoverflow: Why do I need a mocking framework for my unittests? | The value of high level unit tests and mock objects | Should one test internal implementation, or only test public behaviour?

Resten av denne blogposten er ment å gi en oversikt over hvilke muligheter du som utvikler på .NET-plattformen har for å praktisere avhengighetsisolering.

Manuell mocking

La oss først se på hvordan manuell gjør-det-selv-mocking fungerer. Det kan være lurt å starte der, for å få en grunnleggende forståelse for hvordan og hvorfor man mocker. La oss si at jeg skal teste en LoginController-klasse. Den har to avhengigheter; et LoginView og en UserRepository.

    1 [Test]

    2 public void Should_login_user_successfully()

    3 {

    4     var view = new FakeLoginView();

    5     new LoginController(view, new FakeUserRepository());

    6     view.TriggerAuthenticationRequested();

    7     Assert.IsTrue(view.hidden);

    8     Assert.IsTrue(view.Result == AuthenticationResult.Ok);

    9 }

Etter best practises injectes avhengighetene inn gjennom konstruktøren til kontrolleren – dette gjør det mulig for oss å mocke avhengighetene gjennom arv. I testen oppretter jeg stubs som jeg bruker til å simulere at en bruker trigger en authentiserings-request, og til å sjekke at resultatet av authentiseringen er at viewet skjules og Result-propertien settes til OK.

De to stub-klassene, som jeg koder spesifikt for denne testen, ser slik ut:

    1 class FakeLoginView : LoginView

    2 {

    3     // LoginView Members

    4     public event EventHandler AuthenticationRequested;

    5     public string Username { get { return “torbjorn”; } }

    6     public string Password { get { return “passw0rd”; } }

    7     public AuthenticationResult Result { get; set; }

    8     public void Hide() { hidden = true; }

    9     // end LoginView Members

   10 

   11     public FakeLoginView() { Result = AuthenticationResult.Pending; }

   12     public virtual void TriggerAuthenticationRequested()

   13     {

   14         if (AuthenticationRequested != null)

   15             AuthenticationRequested(null, EventArgs.Empty);

   16     }

   17     public bool hidden;

   18 }

   19 

   20 class FakeUserRepository : UserRepository

   21 {

   22     public User FindByName(string username)

   23     {

   24         return new User {

   25             PasswordHash = “BED128365216C019988915ED3ADD75FB” };

   26     }

   27 }

Stub’ene er spesialdesignet for å gi den adferden jeg trenger i testen; FakeLoginView returnerer et predefinert brukenavn og passord, og har en variabel jeg kan sjekke mot for å finne ut om Hide-metoden har blitt kalt. FakeUserRepository vil uansett input returnere en bruker med et passord-hash som korresponderer med det predefinerte passordet.

Det er endel arbeid å lage disse stub’ene, men det er ikke så vanskelig. Problemet er at slik de er nå er de bare anvendelige for et fåtall tester – for andre tester som skal simulere andre ting må jeg skrive nye stubs (eller utvide disse med mer logikk). Jo flere stubs man må lage, jo mer kompleksitet innfører man i test-suiten.

Moq

Moq er et relativt nytt, open source mockingrammeverk for .NET, utviklet av Daniel Cazzulino (@kzu). Rammeverket er designet med tanke på enkelhet, er basert på Castle DynamicProxy, og er min klare favoritt. Jeg har nylig innført Moq på jobben, og det virket ikke som om utviklerne hadde store problemer med å ta det i bruk.

Moq bruker ikke Record/Replay-semantikken som flere andre rammeverk er kjent for, det har en mere intuitiv Arrange-Act-Assert approach. Eneste potensielle ulempen med rammeverket er at du må bruke .NET 3.5 (eller høyere).

Tilsvarende test som den over blir som følger ved bruk av moq:

    1 [Test]

    2 public void Should_login_user_successfully()

    3 {

    4     var view = new Mock<LoginView>();

    5     view

    6         .Setup(v => v.Password)

    7         .Returns(“passw0rd”);

    8 

    9     var repository = new Mock<UserRepository>();

   10     repository

   11         .Setup(r => r.FindByName(It.IsAny<string>()))

   12         .Returns(new User { PasswordHash = “BED128365216C019988915ED3ADD75FB” });

   13 

   14     new LoginController(view.Object, repository.Object);

   15     view.Raise(v => v.AuthenticationRequested += null, EventArgs.Empty);

   16     view.Verify(v => v.Hide());

   17     view.VerifySet(v => v.Result = AuthenticationResult.Ok);

   18 }

I linje 4 til 12 setter jeg opp mockene (Arrange): Jeg lager et view som skal returnere et predefinert passord, og en repository som skal returnere et predefinert passord-hash. I linje 14 sender jeg inn mockene til controlleren, og i linje 15 trigger jeg autentiseringforespørselen (Act). I linje 16 verifiserer jeg at Hide-metoden har blitt kalt, og linje 17 sjekker at Result har blitt satt til OK (Assert).

Moq er under stadig utvikling, og virker ganske populært for tiden. Daniel lanserte for eksempel nettopp Linq to Mocks – en helt ny approach for å opprette mock-objekter i form av en spørring. Det eksisterer også et moq-contrib prosjekt hvor du finner støtte for Automocking (rekursiv oppretting av mocks – innebærer mindre Arrange-kode i testene). OPPDATERING: Rekursiv mocking har blitt flyttet fra moq-contrib til å bli del av moq i versjon 2.6.

TypeMock Isolator

TypeMock Isolator er det aller kraftigste mockingrammeverket vi har tilgjengelig – det kan gjøre ting ingen av de andre kan, som å mocke ikke-virtuelle metoder, statiske klasser og klasser merket som sealed. Ulempen er at det koster penger.., Ganske Mange Penger!

Mange hevder også at styrken dette rammeverket tilbyr lett kan føre til dårligere design, og det er jeg enig i. Vi tok i bruk TypeMock i min forrige jobb, og der førte det til at vi lagde dårlige og komplekse tester som var mer eller mindre umulige å vedlikeholde. Når man derimot allerede har et dårlig design som utgangspunkt – kanskje man har behov for å mocke deler av selve .net-rammeverket – så kan nok TypeMock være verdt sin vekt i gull. (Men hvor mye veier software egentlig?)

Rhino Mocks

Rhino Mocks er et open source rammeverk utviklet av Oren Eini (også kalt Ayende Rahien). Mens TypeMock er det kommersielle storebror med de kraftigste featurene, er Rhino Mocks det mest brukte mockingrammeverket blant .NET-utviklere. Tidligere hadde Rhino en lite intuitiv Record/Replay-syntax, men støtter nå Arrange-Act-Assert, og da ligner det i grunnen svært mye på Moq.

Rhino Mocks må sies å være et svært modent og fleksibelt rammeverk, og som Moq bygger det på Castle DynamicProxy. Den store fleksibiliteten kan være forvirrende, og dokumentasjonen kan være mangelfull. Dette veies opp ved at det har svært mange brukere, så noen andre har alltid gjort det du skal gjøre, og sansynligvis blogget om det.

Flere har utvidet Rhino Mocks til også å støtte automocking, bl.a. Jeremy D. Miller i sitt StructureMap-prosjekt. For det jeg vet kan det hende Ayende også har implementert dette i Rhino Mocks direkte by now.., man vet aldri hva den fyren får til på en ettermiddag.

Stubs

Microsoft Research har sluppet et rammeverk de kaller Stubs, som ble utviklet for deres nye testautomatiserings-verktøy Pex. Dette skiller seg ut fra de andre ved at det bruker kodegenerering. Det er alltid interessant å se hva som kommer ut av MS Research, og selv om jeg ikke vet om dette er interessant som en erstatning for Rhino eller Moq, så er det i alle fall en ny og spennende approach. Sjekk ut Getting Started with Stubs for en lynrask introduksjon.

Merk forøvrig at current versjonsnummer er 0.15.40714.1, så jeg vet ikke om dette er “produksjonsklart” for å si det sånn :)

NMock / Nmock2

Så vidt jeg vet var NMock det første mockingrammeverket på .NET plattformen, laget som en port av DynaMock fra Java. Versjon 2 av NMock ble utviklet av et annet team, og er implementert etter designet fra jMock. Interessen for disse rammeverkene har vært dalende, og det har flere svakheter i forhold til de mer moderne konkurrentene: Den viktigste forskjellen er at mockene ikke er typet ved compile time – man bruker “magiske strenger” for referanser, noe som kan være skummelt og vanskelig å vedlikeholde når ting i designet endres.

Er du interessert i å se nærmere på forskjellene på de fem rammeverkene jeg har nevnt sålangt – moq, TypeMock Isolator, Rhino Mocks, Stubs og NMock2 – så finnes det et prosjekt på Google Code du kan laste ned som heter Mocking Frameworks Compare. Her har du eksempeltester implementert vha. alle rammeverkene, i tillegg til en performance test som sammenligner dem.

Andre rammeverk

EasyMock er et mockingrammeverk fra Java, men det har blitt portet til .NET-plattformen under navnet EasyMock.NET. Det er egentlig alt jeg vet om dette rammeverket, jeg har ikke hørt om noen som bruker det, og det virker som om det ikke har blitt videreutviklet siden 2004, så det er neppe noe å satse på.

NUnit, “alles favorittrammeverk” for enhetstester, har også støtte for mocking – i NUnit-nedlastingen finner du nemlig en lite kjent dll som heter NUnit.Mocks. Jeg har lest at den har begrensede muligheter i forhold til andre rammeverk, men den kan kanskje være aktuell om man ikke skal ta i bruk avhengighetsisolering fullt ut, men har bruk for det i et par tilfeller, og i tillegg allerede bruker NUnit.

Så det var min oversikt over mockingrammeverk i .NET. Min neste blogpost er en praktisk toturial i utenfra-og-inn programmering hvor jeg kommer til å bruke mye mocking.., så følg med om du er interessert i det!

Til slutt: Har du erfaring med noen av disse rammeverkene er det veldig hyggelig om du legger igjen en kommentar med eventuelle mangler i blogposten. Jeg har ikke brukt alle disse vektøyene selv, og har ikke vært en aktiv “mocker” så veldig lenge. Sett meg på plass om du kan!

Knagger: , , , ,

Ultra-tiny given-when-then DSL-snippet

Jeg har testet diverse TDD/BDD-rammeverk de siste månedene (bl.a. machien specification og tinyBDD), og eksperimentert endel med hvordan jeg kan skrive tester/spesifikasjoner som dokumenterer koden best mulig. Dette har resultert i at jeg ikke bruker noe spesielt rammeverk i det hele tatt, men bare bruker deskriptive navn og et generelt given-when-then formular.

Mine tester har en stund nå sett ut omtrent som dette:

        [Test]

        public void Stupid_car_start_1()

        {

            Given_transmission_is(manual);

            Given_transmission_is_in(first_gear);

            Given_clutch_pedal_is(not_engaged);

            When_key_is_turned();

            Then_car_should_jump_forward();

            Then_engine_should_be_dead();

        }

Det virker litt teit å si given tre ganger på rad. Alternativt kunne given nummer to og tre i stedet begynt med “And_”, og det samme kunne jeg gjort med Then_engine_is_dead(). Det er derimot et problemer med den måten å gjøre det på; ofte vil den metoden som er given nummer 3 i én test plutselig bli den eneste given i en annen test, og da kan den ikke hete noe med “And”.

Et annet problem er at det som er en “When” i én test kan være kjekk å bruke som en “Given” i neste test. For å løse dette problemet legger jeg til et lite sett med properties i test-klassen:

        #region Really tiny BDD DSL / Syntactic sugar

        protected CarStartTests Given { get { return this; } }

        protected CarStartTests When { get { return this; } }

        protected CarStartTests Then { get { return this; } }

        protected CarStartTests and { get { return this; } }

        #endregion

Her ser du hvordan den forrige testen blir seende ut ved å bruke de nye propertiene:

        [Test]

        public void Stupid_car_start_2()

        {

            Given.transmission_is(manual);

            and.transmission_is_in(first_gear);

            and.clutch_pedal_is(not_engaged);

            When.key_is_turned();

            Then.car_should_jump_forward();

            and.engine_should_be_dead();

        }

Men nå står jeg også mye mer fritt til å trikse å mikse med metodene og variablene i test-klassen, samtidig som jeg beholder et flytende og naturlig språk. Samme testen kunne f.eks. lett se ut som dette:

        [Test]

        public void Stupid_car_start_3()

        {

            Given.vehicle.Transmission = manual;

            and.vehicle.Transmission.SetGear(first);

            and.vehicle.Clutch.ChangeState(not_engaged);

            When.key.Turn();

            Then.car_jump_counter.should_be(1);

            and.vehicle.Engine.State.should_be(dead);

        }

I realiteten blir det som regel en blanding av de to fremgangsmåtene: Givens skjuler ofte mye, som f.eks. oppsett av mocks/fakes, og beholdes som metoder. Thens på den andre siden er som oftest minst like lesbare om de er tester direkte på en eller annen variabel brukt for å “sanse” korrektheten av testen/spesifikasjonen. Kombinert med et sett med fluent asserts (som du finner i coreTDD) blir en sjekk av en variabel like lesbar som et metodenavn.

Nedenfor er en Visual Studio snippet-fil jeg har definert for å enkelt kunne inserte de fire BDD-propertiene i nye testklasser. Hvis du lagrer XML’en med navnet bdd.snippet under “My Documents\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets”, så vil du kunne bruke den ved for eksempel å skrive “bdd” i koden din (uten hermetegnene altså..) og trykke TAB to ganger.

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

    3     <CodeSnippet Format="1.0.0">

    4         <Header>

    5             <Title>Given-When-Then Syntax Sugar</Title>

    6             <Shortcut>bdd</Shortcut>

    7             <Author>http://blog.kjempekjekt.com</Author>

    8             <Description>Provides a really tiny dsl for doing bdd.</Description>

    9         </Header>

   10         <Snippet>

   11             <Declarations>

   12                 <Object Editable="false">

   13                     <ID>ClassName</ID>

   14                     <Function>ClassName()</Function>

   15                 </Object>

   16             </Declarations>

   17             <Code Language="CSharp">

   18                 <![CDATA[

   19                   #region Really tiny BDD DSL / Syntactic sugar

   20                   protected $ClassName$ Given { get { return this; } }

   21                   protected $ClassName$ When { get { return this; } }

   22                   protected $ClassName$ Then { get { return this; } }

   23                   protected $ClassName$ and { get { return this; } }

   24                   #endregion

   25                 ]]>

   26             </Code>

   27         </Snippet>

   28     </CodeSnippet>

   29 </CodeSnippets>

Hvis du finner noe mindre BDD-rammeverk enn dette så må du gi meg et vink ;)

Send SMS med Soap

Mens jeg vurderte å begynne å jobbe for PSWinCom fikk jeg blant annet tilgang til deres SMS Gateway produkt, slik at jeg selv kunne teste hvor enkelt og bra det var. PSWinCom lar deg sende SMS gjennom mange integrasjonspunkter, som XML over TCP, HTTP/HTTPS post, SMTP, og SOAP web services, i tillegg til deres webgrensesnitt. Jeg bestemte meg for å teste ut SOAP i C#.

Først fant jeg adressen til wsdl’en, opprettet en ny konsollapplikasjon, og la til en web service referanse i Visual Studio.

CropperCapture[53]

Den genererte proxyen gav meg alt jeg trengte. Jeg opprettet en ny SoapClient, instantierte en ny SMSMessage, og på under to minutter hadde jeg sendt min første SMS fra kode.

    1 using (SMSServiceSoapClient client = new SMSServiceSoapClient())

    2 {

    3     string username = “torbjorn”;

    4     string password = “n0tth3r331passw03d”;

    5 

    6     SMSMessage message = new SMSMessage

    7     {

    8         ReceiverNumber = “004755560122″,

    9         SenderNumber = “004755596698″,

   10         Text = “Les om SMS via SOAP på http://kjempekjekt.com !”,

   11         Tariff = 0,

   12         TimeToLive = 0

   13     };

   14 

   15     ReturnValue returnValue = client.SendSingleMessage(

   16         username,

   17         password,

   18         message);

   19 }

ReturnValue-objektet har en Code property med verdien 200 om alt gikk bra, 100 om meldingen ble forkastet (detaljert beskrivelse blir gitt i Description propertien), og 500 ved SOAP interface error.

Så enkelt er det altå å integrere systemet sitt om man vil sende SMS med PSWinCom’s Gateway.

Overvåk ledig diskplass med WMI

Med gjevne mellomrom går en eller annen disk på en eller annen server full, enten det er på grunn av ivrige logger, akkumulerende backups, voksende databaser eller noe helt annet. Uansett hva det er skaper det alltid problemer og tapt arbeidstid. Og med like gjevne mellomrom kan man høre meg klage, og si at nå vi få på plass en løsning som kan overvåke diskene våre.

I dag bestemte jeg meg derimot for å ikke klage lengre, og 20 minutter senere hadde jeg laget en liten app som viste meg hvor mye ledig diskplass det var på serverne våre. Jeg ante ikke at det skulle være enkelt.

Jeg begynte med å lage en liten dataklasse for å holde på informasjonen om en disk. Med hjelp av CodeRush tok det ikke mange sekunder eller tastetrykk. Her er DiskInfo-klassen:

    8 public class DiskInfo

    9 {

   10     public string DriveLetter { get; set; }

   11     public string VolumeName { get; set; }

   12     public double Size { get; set; }

   13     public double Free { get; set; }

   14     public double PercentFree { get { return Free / Size; } }

   15 

   16     public override string ToString()

   17     {

   18         return string.Format(“{0}{1}{2}{3}{4}”,

   19             DriveLetter.PadRight(5),

   20             VolumeName.PadRight(30),

   21             Size.ToString(“###,###,###,###”).PadLeft(15),

   22             Free.ToString(“###,###,###,###”).PadLeft(15),

   23             PercentFree.ToString(“#0%”).PadLeft(10));

   24     }

   25 }

Og så trengte jeg noe som kunne hente ut informasjonen. Jeg har hørt mye om Windows Management Instrumentation (WMI), men aldri brukt det. Men en liten titt på System.Management namespacet avslørte at dette var akkurat det jeg behøvde:

Provides access to a rich set of management information and management events about the system, devices, and applications instrumented to the WMI infrastructure. Applications and services can query for interesting management information (such as how much free space is left on the disk, what is the current CPU utilization, which database a certain application is connected to, and much more)…

Jeg laget en kjapp liten command-klasse jeg valgte å kalle DiskInfoRetriever, som gitt navnet på en server henter ut informasjon om alle diskene på den maskinen:

    9 using System.Management;

   10 

   11 public class DiskInfoRetriever

   12 {

   13     private string _Server;

   14 

   15     public List<DiskInfo> Items { get; set; }

   16 

   17     public DiskInfoRetriever(string server)

   18     {

   19         _Server = FixServerName(server);

   20         Items = new List<DiskInfo>();

   21     }

   22 

   23     private string FixServerName(string server)

   24     {

   25         return server.StartsWith(@”\\”)

   26             ? server

   27             : @”\\” + server + @”\root\cimv2″;

   28     }

   29 

   30     public void Execute()

   31     {

   32         var scope = new ManagementScope(_Server);

   33         var query = new ObjectQuery(

   34               “select FreeSpace, VolumeName, Size, Name “

   35             + “from Win32_LogicalDisk where DriveType=3″);

   36 

   37         var searcher = new ManagementObjectSearcher(scope, query);

   38         var results = searcher.Get();

   39 

   40         Items.Clear();

   41 

   42         const int MEGABYTE = 1048576;

   43         foreach (ManagementObject result in results)

   44         {

   45             Items.Add(new DiskInfo

   46             {

   47                 DriveLetter = result["Name"].ToString(),

   48                 VolumeName = result["VolumeName"].ToString(),

   49                 Size = (double.Parse(result["Size"].ToString()) / MEGABYTE),

   50                 Free = (double.Parse(result["FreeSpace"].ToString()) / MEGABYTE),

   51             });

   52         }

   53     }

   54 }

Legg merke til den SQL-lignende spørringen på linje 34/35.

Nå gjenstod det bare å definere en liste med servere, initialisere en bunch med command-objekter, eksekvere dem, og loope gjennom resultatet for å skrive objektene til konsollet. Det gjorde jeg i Main:

   10 static void Main(string[] args)

   11 {

   12     string[] servers = { “s1dev02″, “s1dev03″, “s1dev04″, “s1dev05″, “s1hvsql01″ };

   13 

   14     try

   15     {

   16         foreach (var server in servers)

   17         {

   18             Console.WriteLine(server + “:”);

   19 

   20             var diskInfoRetriever = new DiskInfoRetriever(server);

   21             diskInfoRetriever.Execute();

   22             diskInfoRetriever.Items.ForEach((disk) => Console.WriteLine(disk));

   23 

   24             Console.WriteLine();

   25         }

   26     }

   27     catch (Exception ex)

   28     {

   29         Console.ForegroundColor = ConsoleColor.Red;

   30         Console.WriteLine(ex.ToString());

   31     }

   32 

   33     Console.WriteLine();

   34     Console.WriteLine(“press ENTER to exit..”);

   35     Console.ReadLine();

   36 }

20 minutter tidligere hadde jeg ingen anelse om at jeg kom til å lage dette her, eller at det var så enkelt. For fremtiden skal jeg tenke meg om en ekstra gang før jeg klager over en manglende, teknisk løsning. Det meste lar seg løse, og mye er enklere enn man tror.

Neste steg blir å lage en ny modul til ContikiCenter som kan informere oss om når disker nærmer seg smertegrensen. Her er forresten resultatet av dagens kjøring:

Disk Watcher console app

Obs, det ser ut som om vi må foreta en liten opprydning på s1dev04. Jaja, det får vente til i morgen.. :)

Crowdsource testing av software

Crowdsourcing har vært et hot begrep lenge, men det er først nå i det siste at vi virkelig har begynt å se mange bedrifter etablere seg basert på denne modellen.

Prinsippet er å distribuere problemløsing og produksjon; en oppgave kringkastes til stor gruppe ukjente problemløsere – amatører og frivillige, eller gjerne også profesjonelle. Enkeltpersonene i denne gruppen, the crowd, leverer hver sin løsning. Gruppen kan også brukes til å stemme frem de beste løsningene. Disse blir så levert til oppdragsgiveren, the crowdsourcer, og den/de som vant blir kompansert – enten med penger, en pris, kudos, eller annen form for belønning.

Fordelene ved crowdsourcing kan være at problemer kan løses raskt, og til en relativt lav pris pga. stor konkurranse. Man betaler kun for resultater, og som oppdragsgiver kan man utnytte talentet til mange flere personer enn man tradisjonelt sett kan ansette selv.

crowdsourcing value chain

Det finnes som oftest tre ulike parter innenfor crowdsourcing, illustrert i tegningen over, og alle posisjonene i modellen er interessante. Som profesjonell utvikler kan jeg utnytte crowds til å levere verdi for meg på en kostnadseffektiv måte. Som et individ med kunnskaper og fritid kan jeg også bli medlem av et crowd community, og kanskje tjene litt penger på småoppdrag som distribueres til alle medlemmene. Og som en person interessert i inovasjon og nettverksbygging høres det utrolig spennende ut å fasilitere crowdsourcing, og å kunne høste en fortjeneste på å formidle oppdrag.

Den siste tiden har jeg blitt oppmerksom på flere, nystartede firmaer som tilbyr softwaretesting basert på crowdsourcing. Her er noen tjenester man ikke bør overse i disse trange tider:

uTestTestcrowd 1: uTest
uTest gir deg et virtuelt QA team når du trenger det. Nettverket består for tiden av over 16 tusen testere. Du gjør tilgjengelig det som skal testes, f.eks. linken til en testsite, og beskriver gjerne hva som skal testes og eventuelt hvordan. Du betaler kun for bugs som blir funnet (etter at du har kontrollert dem), og du kan også lage en liste med kjente feil, slik at du ikke trenger å betale for ting du vet om på forhånd.

Testerne bygger opp en kvalitets-score, og som oppdragsgiver kan du spesifisere hvilken type testere du ønsker, hvor mange, hvor lenge de skal teste, osv. Startup Success Podcast #22 går i dybden på uTest, og diskuterer også hvordan man bygger et crowd community. Meget insteressant.

UserTestingTestcrowd 2: UserTesting
Dette nettverket har spesialisert seg på usability testing. Dette er en form for testing som ofte er vanskelig å få til selv, og som normalt koster mye tid og penger om det skal gjøres skikkelig. For 29 dollar tilbyr UserTesting en video av en tester som bruker websiten din mens han forteller hva han opplever, samt en skriftelig oppsummering hvor testeren forteller hva han likte, ikke likte, osv.

Last gjerne ned Startup Success Podcast #20, som går i dybden på UserTesting.com.

BrowserMobTestcrowd 3: BrowserMob
Dette er en litt annen form for crowdsourcing. Kanskje er det mer riktig å kalle det cloudsourcing. BrowserMob automatiserer load-testing av websiden din ved hjelp av virtualisering, og viser deg nøyaktig hvordan siden oppfører seg i ulike browsere under høy last. Startup Success Podcast #18 intervjuer Patrick Lightbody som står bak BrowserMob.com, så lytt gjerne på det hvis du er insteressert.

Mange andre typer crowdsourcing..

Sammen med en kollega har jeg forsøkt meg litt på et crowdsourcing-konsept selv også, nemlig The Forecast Exchange, hvor man kan tappe kunnskapen til en gruppe mennesker for å spå om fremtiden. Nå i mai kjører vi andre runde med beta-testing, og tar du en titt på forsiden kan du se hvor stor tro brukerne har bl.a. på hvordan det vil gå med den norske børsen fremover, om Liverpool kommer på andreplass i premiere league, og om Norge vinner melodi grand prix.

Ting som Open Source Software, Wikipedia og StackOverflow er også varianter av crowdsourcing. Uservoice, som vi bruker på Forecast Exchange, er en crowdsource facilitator som gjør det mulig for oss å få tilbakemelding fra brukerne om hva de vil ha i produktet fremover. 99designs er et crowdsourcing community hvor du kan legge opp en konkurranse for grafiske designere, hvor folk konkurrerer om å komme opp med et design som du er villig til å betale for.

Er du interessert i flere slike crowds kan du ta en titt på denne listen fra Open Innovators over plattformer og tjenester. Crowdsourcing i ulike former er fremtiden. Det betyr mindre og mindre hvor man befinner seg i verden, og de som klarer å tappe kunnskap og talent over internett vil komme seirende ut av de komende årene. Dette er et utrolig spennende felt, og jeg gleder meg til å se mange, nye måter å utnytte dette på fremover.


Torbjørn: La oss anta to ulike definisjoner av Template Method pattern - de to ytterpunkte...

Lars-Petter: Hei igjen. Siden du inviterer til å ta diskusjonen i bloggen, og har tatt deg t...

Torbjørn: Lars-Petter: Det er én måte å se det på. Det er absolutt fortsatt Template M...

Lars-Petter: Hei. Har du ikke i prinsippet her gått over fra Template Method (arv) til Strat...

Christian Abildsø: I alle fall i C#, så føles dette som kode som blir mer fleksibel men vanskelig...

Torbjørn: Hei Henrik, og takk for tilbudet. Ble oppmerksom på Rasberry Pi for under en uk...

Henrik Sandaker Palm: Ang. større hobby prosjekt. Du er som er en slik rakker på programmering har j...

Øivind Nilsen: Slutt å bruke mobilnummeret mitt som eksempel !...

Bjørn Einar Bjartnes: Jeg har også latt meg fascinere av Clojure, uten at jeg har kommet så veldig l...

Bjørn Einar Bjartnes: Sweet :) Jeg tror egentlig jeg liker det som det er, med musikk. Litt av utford...

 Hold deg oppdatert

Søk i bloggen

Ferske innlegg

  • Template Method del 4: Multippel arv
  • Template Method Intermesso
  • Template Method del 3: Bare funksjoner
  • Template Method del 2: På vei mot funksjonell programmering
  • Kategorier

  • .net ninja (37)
  • Bøker (17)
  • Diverse prosjekter (35)
  • DSL (10)
  • Erlang (10)
  • F# (5)
  • Hardware (1)
  • Jobb (77)
  • Julekalender (51)
  • kjempekjekt.com (23)
  • LISP/Clojure (33)
  • NNUG / community (60)
  • O/RM & databaser (10)
  • Off topic (116)
  • OO-design/clean code (30)
  • Podcasts (14)
  • Polyglot (77)
  • Ruby (27)
  • Silverlight / RIA (3)
  • Software/verktøy (20)
  • Softwareutvikling (20)
  • Testing / TDD (30)
  • the contiki strip (13)
  • User experience (3)
  • WCF (3)
  • Webutvikling (32)
  • WPF (9)
  • WTF (12)
  • Last ned Wallpaper

    Programmeringsbloggens tøffe skrivebordsbakgrunn med snippets fra ulike språk laster du ned her!

    Abonner via epost

    Om du vil kan du få alle nye blogposter tilsendt til din epost. Abonner nå, det er kjempeenkelt!

    Meta