Problem Steps Recorder

psr

 

 

Ik hoorde er voor het eerst over op runas radio (http://www.runasradio.com/default.aspx?showNum=410), en ik dacht: zou het zo simpel kunnen zijn?
Een programma dat (vanaf Windows 7) in Windows zelf zit, waarmee je op een simpele manier acties die je uitvoert kan ‘opnemen’?

Nou, het bleek dus inderdaad zo simpel te zijn.
Ok, verwacht geen vervanger van een uitgebreide screencapture solution, maar als je op een simpele manier de acties die je uitvoert (of die iemand anders moet uitvoeren) wilt opnemen, dan is dit een handige tool.
En in mijn vakgebied, software development, komt het best vaak voor dat je even wilt delen wat een klant moet doen, of dat een tester wil laten zien hoe een issue tot stand is gekomen.

Hoe te starten?

In Windows 7 WIN-R en type ‘psr

of in Windows 8: ga naar de tile modus en type ‘psr

Er komt dan een klein window waarin je kiest voor ‘start record’.
Vanaf dat moment worden je acties opgeslagen. Na elke actie wordt een schermafdruk gemaakt die wordt bewaard.
Je kunt ook met de ‘Add comment’ knop een sectie in het scherm markeren en daar een tekst bij typen om iets te verduidelijken.
psr-highlightproblem

 

 

 

 

 

 

 

Als je klaar bent klik je op ‘stop record’ en wordt alles in 1 gebundelde (.mht) file opgeslagen.

What to do when the testsuite is broken

So you have a suite of unit testskeep-calm-and-unit-test.

Ok, to be honest, they are not all unit tests, some are integration tests.

But hey, you can’t have it all, after all, you’ve almost got a 1000 tests in place, great!

The only downside: when time went by, only two thirds of the test nowadays pass, the rest doesn’t.

The consequence is that nobody runs the tests, and on the build server they don’t run either.

Developers are discouraged to create new tests because they will never be run again.

What to do now?

Basically there are three options:

  1. fix the failing tests;
  2. ignore the failing tests;
  3. delete the failing tests;

The first option is not a real option: who can and wants to fix 300 failing tests?

The second option is tempting: all the code is kept so the remaining unit tests still run and no code is thrown away. And maybe, later, when we have spare time, they all get fixed.

As tempting as the second option is, I choose for the third option: delete all the failing tests. I think all the ignored tests just creates noise in your code, and the spare time to fix them… that will be the day!

And the longer you work on your production code, the more out of sync the testcode will be. So you maybe have to comment out some code in your ignored tests (yikes) in the future to prevent from compile errors.

Yes I understand, removing so much code from your project feels like throwing away money, but I think it will save you money in the future, and you can start right now with a clean base of unit tests.

 

 

Omzetten van de Affinno.nl website van ASP.Net webforms naar ASP.Net MVC 4

asp-net-mvc-hosting-logo

Vorige week had ik wat tijd over, dus heb ik wat tijd gestoken in het ombouwen van de eigen Affinno website van ASP.Net webforms naar ASP.Net MVC.

Aangezien ik best tevreden was over de look and feel, heb ik besloten om deze ongemoeid te laten en alleen wat admin functionaleit in te bouwen, zodat het wat gemakkelijker wordt om content aan te passen.

De laatste projecten die ik heb uitgevoerd waren ook MVC projecten, dus daar waren geen problemen te verwachten. Wel maakte ik de stap van MVC 3 naar MVC 4. Daar verwachtte ik weinig problemen mee; overstappen naar een hogere versie is meestal niet veel meer dan de releasenotes tot je nemen (Release notes MVC 4) en kijken wat er voor goodies in zitten. Voor mijn site was alleen de bundling en minification een meerwaarde, dus die heb ik gebruikt.

Na het aanmaken van het nieuwe project met de internet template viel me gelijk op dat deze meer dan voorheen al onderdelen include; zo zit bv Modernizer er al standaard in. Je hebt dus wel al vanaf scratch een groot aantal referenties en Javascripts in je project. Aan te raden is om deze even te doorlopen en te kijken welke je hier echt van nodig hebt.

Een meevaller was dat ook het inloggen via external services erg gemakkelijk is gemaakt: de voorbeeld code zit er al uitgecommentarieerd in. Zo was het een fluitje van een cent om het inloggen via Google mogelijk te maken.

Toen kwam de eerste kennismaking met Visual Studio 2012; ook hier verwachtte ik geen issues mee omdat overgangen van de ene versie van Visual Studio naar de volgende tot nu toe ook geen verrassingen hebben opgeleverd.

Deze keer heb ik de Express versie eens geprobeerd, om te kijken wat de stand daar van is ten opzichte van de professional versie. Ik moet zeggen: ik ben onder de indruk, ik heb geen moment het idee gehad met een of andere uitgeklede versie te maken te hebben. Wel is er een belangrijk nadeel aan de Express versie: het ondersteunt geen plugins dus ik moest het doen zonder mijn hulpje Resharper, en dat was wel een groot gemis!

Met een vers project heb ik als eerste de masterpage van de oude site overgezet naar de nieuwe _layout pagina. Daarna een actionmethod op de controller, een statische .aspx pagina gekopieerd naar een view, de css’s en js’s gekopieerd van het ‘oude’ project en voila: de eerste pagina was al te zien.

En dan stap je toch al snel in de valkuil die je op projecten ook vaak ziet als je zo snel iets zichtbaar hebt: je denkt bij jezelf “bijna klaar”. En dat is nou net wat te snel gedacht, want ik had natuurlijk nog geen errorhandling, 404 redirects, omleidingen van de oude url’s, content editing, caching, contact edit pagina’s etc. etc.

Uiteindelijk heeft het omzetten iets meer dan 2 dagen gekost. Grote meevaller was dat in de ‘oude’ site de logica al in een aparte laag zat waardoor ik veel code 1 op 1 kon kopiëren. De views moeten natuurlijk wel opnieuw worden aangemaakt (geen ASP.Net panel, ASP:Textbox etc. meer) en omdat de abstractielaag van webforms er niet meer is moet je toch wel voor elke pagina wat code aanpassen; weliswaar meestal niet al te veel, maar wel voor bijna elke pagina. Gebruik je echter veel server componenten zoals de grid, bereid je dan maar voor op redelijk wat ombouwtijd.

Wat ik nog niet eerder had gedaan was het automatisch deployen vanuit Visual Studio naar de server. Ik heb dat nu via een FTP deploy gedaan, wat goed werkte. Hierbij heb ik ook kennis gemaakt met de automatische web.config transformatie waarbij direct de juiste server web.config settings worden gemaakt vanuit je development omgeving.

Op aanraden van oud collega André heb ik ook T4MVC gebruikt. Deze vernuftige T4 template maakt voor elke controller en controlleraction strongtyped strings aan zodat je altijd strongtyped naar controllers en actions kunt verwijzen. Erg handig.

Al met al een leuk project waar je goed kan zien dat als je een goed uitzicht hebt op het eindresultaat je snel meters kunt maken.

In Dutch: “Delen door nul is flauwekul”, which means “dividing a number by zero is nonsense“.

When you start programming you have probably experienced this: the .Net DivideByZeroException. You get this when, for instance, you want to calculate the average of a values list, and you divide it by the number of items, but then the list is empty, so you divide by zero. The .Net framework then throws a nice DivideByZeroException, which points you to the place in the code were you did not check for the denominator to be zero.

So, then all is well. Until you start calculating with doubles in stead of integers. Then you do not get an exception when you divide by zero. Instead, the double gets one of the following three values:

  • PositiveInfinity
  • NegativeInfinity
  • NaN

The first you get by dividing a positive value by zero, the second by deviding a negative value by zero and the last one by deviding zero by zero. Following the docs, when you want to check whether a double has one of these three values, you cannot check it this way:

d == Double.PositiveInfinity, d == Double.NagativeInfinity,  d == Double.NaN

But you have to use these methods instead:

  • Double.IsPositiveInfinity(d)
  • Double.IsNagativeInfinity(d)
  • Double.IsNaN(d)

calculator

Dividebyzeroexception

Affinno compenseert CO2 uitstoot

Vandaag geen development onderwerp, maar een milieu onderwerp.
Om een klein beetje te helpen tegen de uitstoot van CO2 in de wereld heb ik besloten om de CO2  die ik zelf uit stoot in mijn werkzame leven te compenseren.
Dit gebeurt door het financieren van Goldstandard projecten waarmee niet alleen de CO2 uitstoot wordt gecompenseerd maar die ook nog een bijdrage aan duurzame ontwikkeling leveren.
Meer informatie lees je hier.

Automatisch invullen van website formulieren: Roboform

Ken je dat, als developer, dat je gevraagd wordt om een issue te bekijken als ‘het aanvraagformulier’ wordt gesubmit. Dus je start de applicatie, vult het formulier in, en drukt op ‘submit’.  Je controleert even wat, klikt ‘back’, en je moet weer het formulier invullen. Dan moet je daarna wat code aanpassen, runnen, formulier invullen, styling bekijken, aanpassen, formulier invullen…. je begrijpt wat ik wil zeggen: elke keer een heel formulier invullen is niet leuk. Helemaal niet omdat als je later wat moet testen je het formulier zo beu bent dat je overal waar het kan de letter ‘a’ of het cijfer ‘0’ invult, en dat er nooit meer een representatieve input uit het formulier komt je applicatie. Aangezien ik ook in dat schuitje zit ging ik op zoek naar een tooltje dat dat invullen voor mij kan doen, en ik kwam uit bij Roboform.

Als je op de site van Roboform komt dan lijkt het in eerste instantie voornamelijk een passwordmanager. Daar gebruik ik het niet voor, ik gebruik het voor het automatisch invullen van formulieren tijdens testen.

Het werkt als volgt:

  • Je vult 1 keer een heel formulier in met representatieve data
  • Je klikt in de Roboform toolbar op ‘opslaan’
  • De volgende keer dat je het formulier moet invullen klik je in de Roboform toolbar op het ‘invul’ icoon en voila; de data staat ingevuld.

Je kunt ook meerdere keren verschillende input opslaan; je kunt dan later kiezen welke opgeslagen data je wilt invullen op dat moment. Het is voor zover ik weet niet mogelijk om (zoals je bij geautomatiseerd testen wellicht wilt) data random laten te genereren (bv elke keer een ander telefoonnummer) maar voor (debug) developer testen is het erg handig.

Het werkt in Internet Explorer, FireFox, Opera en Chrome.

In de gratis versie wordt een beperkt aantal url’s ondersteund (dus je kunt dan voor maximaal 10 url’s een formulier opslaan) maar als je vindt dat het prettig werkt dan kost het maar $9,99 (nee, ik heb geen provisie regeling) en dat was het mij persoonlijk zeker waard.

Ervaringen met Scrum

Enige tijd geleden ben ik begonnen op een project waar Scrum wordt gebruikt.
Hier mijn eerste ervaringen met Scrum:

Wie let er op het tempo?
Aangezien het hele team de baas is, is er dus niemand echt de baas. Wie houdt er dan in de gaten of de velocity van 60 storypoints wel ambitieus is, of dat er eigenlijk wel 80 storypoints door het team gehaald kunnen worden?
De product owner kan het niet inschatten, en een langzaam team ziet wellicht niet hoe langzaam ze zijn.

Daily standup is nuttig.
Het is niet altijd even leuk voor elk teamlid om met de billen bloot te moeten elke dag, maar met deze meeting is het wel erg duidelijk of er voortgang wordt geboekt of dat mensen blijven hangen in bepaalde stories.

Retrospective rules.
Onze sprints duren 2 weken. Dat wil zeggen dat we elke 2 weken terugkijken over hoe het is gegaan; wat er goed is gegaan en wat er beter had gekund. En dat is gewoonweg awesome. Elke 2 weken een kans om bij te sturen, om echt na te denken of we op de goede weg zitten, en ook dus bij te kunnen sturen.
Dat vind ik echt veel beter dan aan het einde concluderen dat het allemaal anders had gemoeten.

Twee-wekelijks opleveren; directe feedback
Meer dan eens wordt er maanden achtereen code geschreven zonder dat een stakeholder er iets van ziet. Dikke kans dat het na al die maanden niet exact overeenkomt met wat die stakeholders in gedachten hadden. Dus het 2-wekelijks opleveren van software geeft niet alleen regelmatig aan hoe de voortgang is, maar geeft ook al snel inzage in wat er ontwikkeld wordt.

Schatten van de userstories
Het schatten van userstores, hier gedaan in storypoints maar het kan ook prima in uren, met meerdere mensen is een prima middel gebleken om al vroeg te discussieren over complexiteit van userstories en wat ze eigenlijk precies inhouden.
Ook geldt in dit geval: twee weten meer dan een dus de schatting is accurater dan wanneer één iemand zich hier mee bezighoudt.

Echte betrokkenheid met degene voor wie je het doet door de directe communicatie
Een productowner die in dezelfde ruimte zit als waar het development team zit en altijd aanspreekbaar is: wat een luxe!
Geen ‘het zal wel dit zijn’ meer maar direct vragen wat gewenst is. Een absolute kwaliteitverbeteraar.

Goede scrummaster onontbeerlijk
De titel zegt genoeg; een scrummaster kan met een neutrale blik (want niet in het team) bekijken of het proces goed loopt.

Userstories beter dan MS-Word proza.
We werken hier met userstories in een vast formaat: AS A — I WANT — SO THAT.
Bijvoorbeeld AS A user I WANT to be able to see the unread email indicated SO THAT i can easily see which email i have to process.
En dat is wellicht wat meer werk voor de product owner dan een standaard MS-Word document, maar als developer werkt het wel een stuk prettiger als de specificaties op deze manier zijn geschreven.
Vooral het laatste, SO THAT, ofwel het waarom, is vaak erg verduidelijkend.

Sterke productowner
Je moet wel een sterke product owner hebben. Hij of zijn bepaalt namens alle gebruikers en belanghebbenden. Voordeel is wel dat dat uitzoekwerk buiten de scope van de developer plaatsvindt maar je hoort alleen de conclusie, en niet de discussie vooraf. Degegen bij wie je later je info haalt moet dan ook wel goed op de hoogte zijn.

Data is lost from my asp.net cache

A strange experience it was; losing data from the Asp.net cache.
I was refactoring some code which was used frequently in my Asp.net code, and all it did was getting a non-volatile list of items from the database. A good candidate for some caching I thought.

So I created the caching code, hit F5 and started the program.
And guess what? All new errors occurred.

While debugging I found out that the first moment I put in ten items for the cachekey, and later on I only got five out when I asked for the same data.
So what is this? A bug in the cache in .Net?
Most likely not, so I investigated the rest of the code.

And what turned out to be the case?
One function getting the data from the cache actually removed items from the list.
That is perfectly ok if the next code gets a fresh result from the database, but not if the items are removed from a list which is actually in cache.

Conditionally enable fieldvalidators (ie RequiredFieldValidator) in Asp.Net

Today i used the old and familiar asp.net validators again.
The code was straight forward: controls where dynamicly created and their validators, dynamicly, also.
But in this case i wanted to use the validators conditionally, which is not an uncommon thing todo:

Say you order a book. You have to enter your delivery address, so that field is mandatory so you attach a RequiredFieldValidator to it. Then there is a checkbox ‘use another address for invoicing’. When you check it, the invoice address is mandatory, but when you uncheck it, the address must be optional (and probably disabled, but that’s another thing). The solution: conditionally (based on the condition ‘is checkbox checked?’) the invoce address textbox validator must do it’s work; it must be enabled or disabled.

The Asp.Net validators are split into two parts:
a client side validation and a server side validation.
For the client side there is a simple javascript function (which is generated by the .Net framework when you use .NEt validators) for enabling the validator:

 ValidatorEnable(CONTROL, enableValidator);

I’ve called it with Jquery with a change event on the checkbox: if the control is checked, call ValidatorEnable(txtInvoiceAddress, true); when the control is un-checked, call ValidatorEnable(txtInvoiceAddress, false).

On the server side, it’s almost as simple: you have to override the ‘Validate’ event:

public override void Validate()
{
  if (chkUseOtherAddress.Checked)
  {
  ReqValidatortxtInvoiceAddress.Enabled = true;
  }
  else
  {
  ReqValidatortxtInvoiceAddress.Enabled = false;
  }
  base.Validate();
}

And then you’re good to go. The client side part makes sure the average user get’s client side validation; the server side validation validates the user who bypass the normal page or have Javascript disabled.

Deja Vu: browserfunctionaliteiten

Een van de zaken die ik me herinner uit de begintijd van webdevelopment, we spreken de tijd van Netscape 4 en IE4, was het rekening houden met de grote lijst van verschillen tussen die browsers.
Als Netscape 4 dan dit, als IE4 dan zus, als IE5 dan zo.
De laatste jaren waren in dat opzicht iets eenvoudiger: er kwamen wel meer browsers bij waar je rekening mee moest houden, maar met de komst van JQuery was werden veel verschillen netjes gladgestreken.
Maar nu: HTML5.
Eigenlijk een specificatie van de nieuwe HTML standaard en nog volop in ontwikkeling, maar langzaam verworden tot een losstaand begrip net als ‘web 2.0‘.
Omdat HTML5 een buzzword aan het worden is en de meeste browsers al een deel van de (lopende) specificaties aan het implementeren zijn, willen veel developers toch al iets leuks doen met de nieuwe mogelijkheden.
Maar hoe weet je nu of de browser waarin jouw site wordt getoond wel jouw mooie Canvas ondersteunt? Of het nieuwe Video element, of de Rounded Corner?
Dat kun je natuurlijk zelf gaan afvragen maar je kunt ook gebruik maken van modernizr.
Als je gebruik maakt van modernizr dan vult modernizr de html tag met classnames die weergeven welke functionaliteiten de browser ondersteunt. Je kunt deze classes vervolgens gebruiken om styling in je CSS toe te passen afhankelijk van de ondersteuning van Canvas, Rounded Corners of niet.

Bijvoorbeeld: 
.canvas #myCanvas{
background-color:green;
}
.no-canvas #myCanvas{
background-color:blue;
}

Als de browser geen HTML5 Canvas ondersteunt dan zal het in de html tag de classname ‘no-canvas‘ toevoegen; als de browser de Canvas wel ondersteunt dan zal het de classname ‘canvas‘ toevoegen.
Dit kun je dan gebruiken in je CSS om een element te stylen.

Ook voor deze kennis in je Javascript is gezorgd: modernizr geeft ook een Javascript object met properties welke functionaliteiten door de browser worden ondersteund:

if (Modernizr.canvas) {
//create nice canvas
}
else{
//hide the canvas element
}

Een goede (korte) getting started staat hier: http://webdesignernotebook.com/css/how-to-use-modernizr/