Visar inlägg med etikett programming. Visa alla inlägg
Visar inlägg med etikett programming. Visa alla inlägg

onsdag 9 augusti 2023

Do you know the difference between a Fake, a Spy, a Stub, a Dummy and a Mock when writing unit tests?

Published at last

Below is a post draft that I wrote in the summer of 2017 but for reasons I don't remember it has stayed as a draft since then. 

Now, in the summer of 2023 I'll just add Martin Fowler's summary of the test doubles in the book "xUnit Test Patterns" copied from https://martinfowler.com/bliki/TestDouble.html (which I think is a great summary) and publish it.

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
  • Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
  • Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.

The old draft

Do you know the differences between Fake, Stub and Mock when writing unit tests? I thought I did, and was about to write some kind of guide to use at work, but thought I'd do a little bit of research first to be sure to get the details correct. After reading on different pages I became more and more confused, until I found this page http://xunitpatterns.com/Test%20Double.html, that I think describes the types and their differences in a clear way that probably can be useful for us.

The page is on a webified version of the book xUnit Test Patterns: Refactoring Test Code that seem to be a great book that I have missed out on up until now.


When you know the differences between the types, then you might want to read more about how to choose between them according to Mark Seeman here: Mocks for Commands, Stubs for Queries

In his post Mocks Aren't Stubs, Martin Fowler also explains the difference between stubs and mocks and investigates pros and cons of the classicist and mockist way of writing your tests.


So, something that I thought I already knew and I could write about in an hour or so, ended in hours of research and a post with links... keeping it DRY :)

lördag 5 augusti 2023

Skapa en AI-modell som styr en bil i AWS DeepRacer

AWS DeepRacer

AWS DeepRacer är tjänst i Amazons moln. Med hjälp av den tjänsten kan du träna upp en maskininlärningsmodell med förstärkningsinlärning så den kan köra en bil i skala 1:18 på en virtuell eller riktig bana. Modellen kan du sedan anmäla till olika tävlingar.


Som IT-konsult på Knowit hakade jag på möjligheten att prova på DeepRacer när Knowit skapade sin egen interna tävling där deltagarna fick generöst med fria modellträningstimmar. I det här inlägget tänkte jag visa lite hur tjänsten ser ut när man skapar sin modell. I ett eventuellt framtida inlägg är min plan att visa hur det ser ut när modellen tränas.

Skapa en modell

När man loggat in i Amazons molntjänst så listas de senaste tjänsterna man använt. För att komma in på AWS DeepRacer så klickar man på den länken.



Väl inne i tjänsten så får man upp menyn i bilden nedan. För att skapa en modell så går man till "Your models".


Här listas de modeller man skapat tidigare. Eftersom jag provat mig fram en hel del så har jag en del modeller liggande redan. På mitt konto finns dock en begränsning på max sex stycken samtidiga modeller, så jag tar bort en först för att visa hur man skapar en ny med knappen "Create model".



Modellen skapas med en wizard i fem steg. Före alla steg får man lite info om träningen.


Steg 1: Val av modellnamn och bana

I första steget får du namnge modellen och om du vill även ange en beskrivning av den.


Det finns 61 banor att välja mellan att träna modellen på.



Våra tävlingar skulle till att börja med köras på tävlingsbanan från 2018, det vill säga "re:Invent 2018".



Steg 2: Val av tävlingstyp och träningsalgoritm

Det finns tre olika tävlingstyper att välja mellan, just nu var det "Time trial" som gällde.


Vid val av träningsalgoritm blir det helt plötsligt rätt hög nivå... PPO eller SAC, det sa mig ingenting. Nån av guiderna jag tittade på har jag för mig föreslog att börja med PPO, ser att alla mina modeller använder den.


Vågar man sig på att fälla ut "Hyperparameters" så blir det riktigt läskigt, men som tur var så var rådet att låta dessa vara tills man blivit varm i kläderna.


Steg 3: Definiera vad bilen kan göra, d v s dess Action space

Först får man lite info igen.


Sen ska man välja mellan "Continuous" eller "Discrete" action space.


Väljer man "Continuous" så kan man i nästa steg ange max styrvinklar och min/max hastighet.




De val man gjort visas också visuellt. Man kan även klicka direkt på en av pilarna och dra den hur man vill ha det.


Eftersom tävlingen handlar om att ta sig fortast runt banan så har jag tänkt att det är bra att utöka action space med högre hastigheter, så när jag använt "continuous" så har jag ökat max hastighet från ett till fyra.


Om man istället väljer "Discrete" så ska man i nästa steg explicit ange ALLA möjliga utfall som modellen kan ha som utdata. Nedan är förinställda värden.



Jag har testat att använda båda sorterna, men det var ett tag sen jag skapade mina modeller och minns inte om någon av dem fungerade bättre. Jag fick aldrig till läsningen av loggfilerna som skapas vid utvärderingen av modellen, men om man får det så verkar logganalysverktygen mer anpassade till  (eller kanske t o m kräva) "discrete"-varianten.


Steg 4: Välja fordon

Jag har två likvärdiga virtuella bilar, den färgglada har jag för mig att jag fick som pris för att jag ställt upp med en modell i en tävling. Det finns varianter av bilarna, iallafall av de fysiska, som har dubbla framåtriktade kameror och LIDAR.


Steg 5: Belöningsfunktionen

Det är nu man får börja koda! Här ska du, i Python, ange den belöningsfunktion som modellen ska tränas med. Modellen får in bilens tillstånd, den tar ett beslut om vad bilen ska göra härnäst och din belöningsfunktion berättar för träningsalgoritmen hur bra beslutet var utifrån bilens nya tillstånd.

Nedanstående funktion är förifylld, den kan returnera fyra olika värden beroende på hur långt från mitten bilen är placerad, ju längre bort från mitten desto lägre värde. Det vill säga, den belönar modellen när den lyckas följa mittlinjen.


Men eftersom tävlingen handlar om att köra fortast så behöver man även belöna hastigheten på nåt sätt och då behöver man mer data att titta på. Data om bilens tillstånd och även lite info om banan kommer in till belöningsmodellen som en dictionary i parametern "params". Den innehåller nedanstående värden (illustrationer och förtydliganden finns här):
  • "all_wheels_on_track"
    Boolean
    flag to indicate if the agent is on the track

  • "x"
    float
    agent's x-coordinate in meters

  • "y"
    float
    agent's y-coordinate in meters

  • "closest_objects"
    [int, int]
    zero-based indices of the two closest objects to the agent's current position of (x, y).

  • "closest_waypoints"
    [int, int]
    indices of the two nearest waypoints.

  • "distance_from_center"
    float
    distance in meters from the track center

  • "is_crashed"
    Boolean
    Boolean flag to indicate whether the agent has crashed.

  • "is_left_of_center"
    Boolean
    Flag to indicate if the agent is on the left side to the track center or not.

  • "is_offtrack"
    Boolean
    Boolean flag to indicate whether the agent has gone off track.

  • "is_reversed"
    Boolean
    flag to indicate if the agent is driving clockwise (True) or counter clockwise (False).

  • "heading"
    float
    agent's yaw in degrees

  • "objects_distance"
    [float, ]
    list of the objects' distances in meters between 0 and track_length in relation to the starting line.

  • "objects_heading"
    [float, ]
    list of the objects' headings in degrees between -180 and 180.

  • "objects_left_of_center"
    [Boolean, ]
    list of Boolean flags indicating whether elements' objects are left of the center (True) or not (False).

  • "objects_location"
    [(float, float),]
    list of object locations [(x,y), ...].

  • "objects_speed"
    [float, ]
    list of the objects' speeds in meters per second.

  • "progress"
    float
    percentage of track completed

  • "speed"
    float
    agent's speed in meters per second (m/s)

  • "steering_angle"
    float
    agent's steering angle in degrees

  • "steps"
    int
    number steps completed

  • "track_length"
    float
    track length in meters.

  • "track_width"
    float
    width of the track

  • "waypoints"
    [(float, float), ]
    list of (x,y) as milestones along the track center

Här har jag sparat de belöningsmodeller jag har försökt med. I slutet försökte jag kombinera att bilen skulle ha en bra riktning mot nästa "waypoint" i banan, att den skulle ligga centrerad på banan samt ha en hög hastighet.

När man är klar med belöningsmodellen så ska man välja hur länge modellen ska tränas. Jag tyckte det verkade som att en timme var absolut minimum för att få fram en modell som klarade sig hyfsat bra.



De vill gärna att man anmäler sin modell till en tävling när den är klar. Det körs ständigt kvalificeringstävlingar där resultatet avgörs i slutet av månaden.


Sen är det bara att klicka på "Create model" så sätts träningen av modellen igång och man får rulla tummarna eller hitta på något annat under den tid man ställt in i steget innan att träningen får ta.



Avslutning

Sådär, nu har du fått en bild av hur man skapar en modell i AWS DeepRacer. Som jag skrev i början av inlägget så ska jag försöka knåpa ihop ett till inlägg där det syns hur träningen och utvärderingen av modellen ser ut.

söndag 6 februari 2022

Gherkin - det gemensamma "språket" från produktägare till utvecklare

Gherkin

Jag har nu haft möjligheten att använda Gherkin på jobbet, ett språk, eller kanske mer en mall, som används för att skriva systemtest så att de ska bli läsbara och förståeliga hela vägen från produktägare till utvecklare. Vi är bara i början av resan, men det verkar mycket lovande och intressant! Rekommenderar!

Om du är som jag och undrar varför saker heter som de heter så kan jag avslöja att gherkin betyder "liten picklad gurka". Och språket Gherkin används i testramverket Cucumber, vilket frun till skaparen fick namnge:

My wife suggested I call it Cucumber (for no particular reason), so that's how it got its name. I also decided to give the Given-When-Then syntax a name, to separate it from the tool. That's why it's called Gherkin (a small, pickled Cucumber).


Cucumber är ett Ruby-ramverk, sitter du med .net så är det SpecFlow som gäller om du vill skriva test med Gherkin.

För att du ska få en känsla för hur språket ser ut så kommer här ett exempel, där de fetkursiva orden, samt möjligheten till den korta beskrivningen på raden under scenario, tillhör Gherkin:

Scenario: Duplicate email

Where someone tries to create an account for an email address that already exists.

Given I have chosen to sign up

But I enter an email address that has already registered

Then I should be told that the email is already registered

And I should be offered the option to recover my password


plant, fruit, food, green, produce, vegetable, fresh, kitchen, gourd, eating, vegetables, cucumber, cucurbita, cucumbers, gherkin, preparations, flowering plant, pickled cucumber, ensiling cucumbers, mizeria, land plant, cucumber gourd and melon family, summer squash, Free Images In PxHere


Godbitar jag hittat

För att komma in i testskrivandet lite snabbare så läste jag The Cucumber Book - Behaviour-Driven Development for Testers and Developers. Här nedan kommer de partier jag markerat som "kom ihåg" under läsning.




Readability

When you're writing Cucumber features, make readability your main goal. Otherwise, a reader can easily feel more like they're reading a computer program than a specification document, which is something we want you to try to avoid at all costs. After all, if your features aren't easy for nonprogrammers to read, you might as well just be writing your tests in plain old Ruby code. The real key to expressive scenarios is having a healthy vocabulary of domain language to use to express your requirements. That said, using only the basic set of Gherkin keywords can often make your features repetitive, making them cluttered and awkward to read. By the end of this chapter you'll know everything there is to know about Gherkin's syntax, giving you all the tools you need to write clear, readable Cubumber acceptance tests.

System tests Vs unit tests

It's also worth thinking about whether some of the behavior you've specified in Cucumber scenarios could be pushed down and expressed in fast unit tests instead. Teams that enthusiastically embrace Cucumber sometimes forget to write unit tests as well and rely too much on slow integration tests for feedback. Try to think of your Cucumber scenarios as broad brush strokes that communicate the general behavior of the code to the business, but still try to get as good a coverage as you can from fast unit tests. Help make this happen by having testers and programmers work in pairs when implementing Cucumber scenarios. This pair can make good decisions about whether a piece of behavior necessarily needs to be implemented in a slow end-to-end Cucumber scenario and drive out the behavior using a fast unit test instead.

Överflödiga detaljer

Nedanstående test tas upp som ett exempel på ett test som innehåller alldeles för mycket detaljer på fel nivå.

Ett scenario för en e-postklient på webben:

Scenario: Check inbox
Given a User "Dave" with password "password"
And a User "Sue" with password "secret"
And an email to "Dave" from "Sue"
When I sign in as "Dave" with password "password"
Then I should see 1 email from "Sue" in my inbox

Användarnamnen är användbara, eftersom de är viktiga beståndsdelar i scenariot, men lösenorden är bara brus, de har inget att göra med det som testas och gör testet svårare att läsa. Till exempel så har Sue ett annat lösenord än Dave, vilket kan leda till att du som läsare av testet börjar fundera över om den delen är relevant och tappar då fokus från scenariots huvudsakliga mening, dvs: att testa att Dave kan se Sues email.

Lösenorden är alltså överflödiga detaljer (incidental details), detaljer som nämns i scenariot, men som saknar relevans för scenariots uppgift. 

Här är testet utan lösenord:

Scenario: Check inbox
Given a User "Dave"
And a User "Sue"
And an email to "Dave" from "Sue"
When I sign in as "Dave"
Then I should see 1 email from "Sue" in my inbox

En klar förbättring, mer lättläst och testets betydelse framträder tydligare. Ännu mer brus kan tas bort:

Scenario: Check inbox
Given I have received an email from "Sue"
When I sign in
Then I should see 1 email from "Sue" in my inbox

Nu är det ett koncist trestegs-scenario, som också är lättare att underhålla. Om användarautentiseringen måste ändras, så påverkar det inte själva testet utan bara koden bakom. 

When Cucumbers Go Bad: Imperative Steps

In computer programming, there are two contrasting styles for expressing the instructions you give to a computer to make it do something for you. These styles are called imperative programming and declarative programming.

Imperative programming means using a sequence of commands for the computer to perform in a particular order. Ruby is an example of an imperative language: you write a program as a series of statements that Ruby runs one at a time. 
A declarative program tells the computer what it should do without prescribing precisely how to do it. CSS is an example of a declarative language: you tell the computer what the various elements on a web page should look like, and you leave it to take care of the rest.

Exempel i imperativ stil:

Scenario: Redirect user to originally requested page after logging in
Given a User "dave" exists with password "secret"
And I am not logged in
When I navigate to the home page
Then I am redirected to the login form
When I fill in "Username" with "dave"
And I fill in "Password" with "secret"
And I press "Login"
Then I should be on the home page

Enligt författaren så kan man argumentera att ovanstående testexempel har en del fördelar. Men han menar på att man snart kommer drabbas av problem med test som lätt går sönder och uttråkade intressenter, t ex produktägaren. Test som skrivs på den stilen blir brusiga, långa, tråkiga att läsa och går lätt sönder. Till exempel en så liten ändring som en omdöpning av knappen från "Login" till "Log in" får testet att gå sönder.

Men det värsta är att språket inte tillhör den egentliga problemdomänen, utan blir mer lågnivå-språk med ord som "fill in" och "press", vilka tillhör gui-domänen.

Exemplet i deklarativ stil:

Scenario: Redirect user to originally requested page after logging in
Given I am an unauthenticated User
When I attempt to view som restriced content
Then I am shown a login form
When I authenticate with valid credentials
Then I should be shown the restricted content

Författaren skriver att det snygga med detta är att testet inte kopplas till en specifik implementation av användargränssnittet. Samma scenario kan användas för en desktop-app som en mobil-app.
Orden som används (unauthenticated, restricted, credentials) är förståeliga för en intressent som håller på med säkerhet.

It's true that using declarative style will mean you have to write more step definitions, but you can keep the code in those step definitions short and easy to maintain by pushing the actual work off into helper methods in your support code.

lördag 30 oktober 2021

Blazor gotcha: Use the @key attribute when visibility of list items can be toggled

Finding the "bug"

We're building a Blazor web from scratch for the first time in a project at work. I like it and we've been able to go pretty fast although it's a new framework for all the devs in the team. But we ran into a strange behavior that looked like a bug.

In the web app a user can add locomotives and wagons to a list to create a train. Each of the vehicles in the list is represented of a header and a body, where the body can be collapsed or expanded.

User input for each vehicle is validated after entry. When a field is invalid a red frame is shown around the field and a validation error message is shown beneath it.

The strange behavior appeared when the body for one vehicle was expanded at the same time as the body for another vehicle was collapsed. When the use entered an invalid value in a field for one of the vehicles, the field for the other vehicle was marked as erroneous!

Reporting the "bug"

I recreated the strange behavior in a minimal project and reported it as a bug in Blazor: Input validation status gets mixed up when toggling content

After a few days I got the reponse:

Thanks for contacting us. It looks like you're missing the @key attribute for the elements which are rendered in a loop. You can learn more about this from https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-6.0#use-key-to-control-the-preservation-of-elements-and-components

The linked page says: 

The mapping process of elements or components to a collection can be controlled with the @key directive attribute. Use of @key guarantees the preservation of elements or components based on the key's value. 

It can be used like this:

<ol>
    @foreach (var person in people)
    {
        <li>
            <Details @key="person" Data="@person.Data" />
        </li>
    }
</ol>

Not seen in any material

I dont't remember seeing this in any Blazor material I've studied so far (pluralsight.com and the book "Blazor in Action"), so if you're going to use Blazor and create something with similar behavior, keep this post in mind! :)

fredag 18 juni 2021

Write a ray tracer guided by Jamis Buck's test suite

Background

Having seen people write their own ray tracers, I've been curious about writing my own. And for a while I also believed I just could sit down and write one, without any help, until I tried. At least I failed fast :)

Fast forward a few years to the moment when I listened to the podcast Developer On Fire, where the interviewer asks the interviewee for book recommendations and the book The Ray Tracer Challenge - A Test-Driven Guide to Your First 3D renderer by Jamis Buck is mentioned. I bought it and started coding.


About the book
The book explains the theory you need and contains unit tests in Gherkin, which means that you can translate them to whichever programming language you want to use. 
Here's an example of a test that subtracts a point from another, which should result in a vector:


I used C# and NUnit, which made my test implementation look like this:


The algorithms that make the tests pass are written in pseudocode, so you have to translate them as well.

What I learned
Test first
I really liked the test first way of coding. It catched errors early which made it easier to spot and correct the bugs. It was good to build up a safety net of tests, because the code got pretty math intense and would be pretty hard to debug without them.

Funny / not funny
The fun part was the coding and to see the resulting images. But creating sceneries and trying out different settings was not that fun, which makes it pretty useless to have my own ray tracer to play around with...

Recreational coding
Jamis Buck has also written a book about how to generate mazes, something he did when recovering from a burn out. He's sharing that story in the pod Corecursive.

Examples of created images

Here's two examples of images I created. 

Snowflakes
This is supposed to look like falling snowflakes. I made it after learning how to create cylinders and cones and how to group simple shapes together.



The making of a kitchen table

Here's after learning to do cubes and planes and manipulate them, like scaling in different directions, move them and give them color and patterns. Also tried to do a kitchen lamp, but found out that the shadow logic was too simple so that a transparent object shadows as much as an opaque object.

Yes, I had at hard time positioning the table legs :)


The code

It took me quite a while to finish the book. The commit history shows that I began in June 2019 and finished in June 2021. I worked with it in bursts and often had long periods of inactivity.

I skipped the code for matrix manipulation, I used the MathNet.Numerics nuget package instead to faster advance to the chapters that resulted in images.

My github repo for this project.

When searching for The ray tracer challenge at github, I get 254 repo hits in 10 languages, where the most are in Rust (51), C++ (48), C# (32) and Go (17).

After finishing the book I also noticed that people have posted their learning journey on youtube, like this playlist.

fredag 30 oktober 2020

The guest quotes about Clean Code in the book Clean Code

Clean code and code quality

The introduction of the book Clean Code by Robert C Martin begins with the image below, which I find funny beacuse its true. Even when the code is good, you can get wtf moments, but maybe more of surprise of becoming aware of odd things the program has to handle or usable stuff in the framework you didn't know existed than of strange or overcomplicated solutions.





What is clean code?

The focus of this post is on the content of the first chapter, which contains answers from other well-known and deeply experienced programmers on what they think defines Clean Code. Just to have all the quotes in a single place and easily retrievable.

Bjarne Stroustrup, inventor of C++ and author of The C++ Programming Language
I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well.

 

Grady Booch, author of Object Oriented Analysis and Design with Applications 

Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control.

 

"Big" Dave Thomas, founder of OTI, godfather of the Eclipse strategy

Clean code can be read, and enhanced by a developer other than its original author. It has unit and acceptance tests. It has meaningful names. It provides one way rather than many ways for doing one thing. It has minimal dependencies, which are explicitly defined, and provides a clear and minimal API. Code should be literate since depending on the language, not all necessary information can be expressed clearly in code alone.

 

Michael Feathers, author of Working Effectively with Legacy Code

I could list all of the qualities that I notice in clean code, but there is one overarching quality that leads to all of them. Clean code always looks like it was written by someone who cares. There is nothing obvious that you can do to make it better. All of those things were thought about by the code's author, and if you try to imagine improvements, you're led back to where you are, sitting in appreciation of the code someone left for you - code left by someone who cares deeply about the craft.

 

Ward Cunningham, inventor of Wiki, inventor of Fit, coinventor of eXtreme Programming. Motive force behind design patterns. Smalltalk and OO thought leader. The godfather of all those who care about code.

You know you are working on clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem.


And the longest last...

Ron Jeffries, author of Extreme Programming Installed and Extreme Programming Adventures in C#

In recent years I begin, and nearly end, with Beck's rules of simple code. In priority order, simple code:
  • Runs all the tests;
  • Contains no duplication;
  • Expresses all the design ideas that are in the system;
  • Minimizes the number of entities such as classes, methods, functions and the like.

Of these, I focus mostly on duplication. When the same thing is done over and over, it's a sign that there is an idea in out mind that is not well represented in the code. I try to figure out what it is. Then I try to express that idea more clearly.

Expressiveness to me includes meaningful names, and I am likely to change the names of things several times before I settle in. With modern coding tools such as Eclipse, renaming is quire inexpensive, so it doesn't trouble me to change. 

Expressiveness goes beyond names, however. I also look at whether an object or method is doing more than one thing. If it's an object, it probably needs to be broken into two or more objects. If it's a method, I will always use the Extract Method refactoring on it, resulting in one method that says more clearly what it does, and some submethods saying how it is done.

 Duplication and expressiveness take me a very long way into what I consider clean code, and improving dirty code with just these two things in mind can make a huge difference. There is, however, one other thing that I'm aware of doing, which is a bit harder to explain.

After years of doing this work, it seems to me that all programs are made up of very similar elements. One example is "find things in a collection". Whether we have a database of employee records, or a hash map of keys and values, or an array of items of some kind, we often find ourselves wanting a particular item from that collection. When I find that happening, I will often wrap the particular implementation in a more abstract method or class. That gives me a couple of interesting advantages.

I can implement the functionality now with something simple, say a hash map, but since now all the references to that search are covered by my little abstraction, I can change the implementation any time I want. I can go forward quickly while preserving my ability to change later. In addition, the collection abstraction often calls my attention to what's "really" going on, and keeps me from running down the path of implementing arbitrary collection behavior when all I really need is a few fairly simple ways of finding what I want.

Reduced duplication, high expressiveness, and early building of simple abstractions. That's what makes clean code for me. 

Rather watch the movie instead of reading the book?

Here you have hour after hour with uncle Bob (Robert C Martin), speaking about that same things that's in the book.

söndag 19 maj 2019

One way to handle DateTime.Now when unit testing C# code

Hide DateTime.Now behind ITimeProvider?

To make code unit testable there is often a need to break dependencies between classes. This is normally done by hiding concrete implementations behind interfaces and injecting those interfaces  into the class that you want to test.

What if your code is dependent on the static DateTime.Now? Should you hide that behind an interface called ITimeProvider and suddenly have to pass that interface around?

In his book "The Art of Unit Testing", Roy Osherove suggests that you don't and that you use a solution like this class instead:

 public class SystemTime  
 {  
   private static DateTime? _date;  
   
   public static void Set(DateTime custom)  
     => _date = custom; 
   
   public static void Reset()  
     => _date = null;  
   
   public static DateTime Now  
     => _date ?? DateTime.Now;  
 }  

If you create such a class, then you can replace all the calls to DateTime.Now in your code to SystemTime.Now.

And in your unit tests you can use SystemTime.Set() to set what date should be returned from SystemTime.Now. After each test run, make sure to call SystemTime.Reset(). That call is preferably put in a teardown method, like [TestCleanup] if you're using MSTest or [TearDown] in NUnit.



måndag 10 december 2018

Overuse Example of the Null Coalescing Operator (??) and Null-Conditional Operator (?.)

The sweet taste of syntactic sugar

From Wikipedia
In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.

Sometimes though, too much of the sweetness can become a mouthful.

Suppose you need this to guard against collections that are null or empty



but in the rush you head directly for the sweet style. Its shorter and doesn't repeat the variable name, but is it really more readable?


Last week I saw code like that. Since my own code was dependant on that method I really would like it to be correct. At a first glance it appeared to be buggy. So I tried it out in LinqPad and saw that it behaved totally correct and therefore felt a bit perplexed. Do you?

There's three cases
  1. collectionOfInts has at least one value
  2. collectionOfInts is empty
  3. collectionOfInts is null
I find the first and second case pretty straightforward, but I couldn't evaluate the null scenario in my head. For instance, I became unsure about the operator precedence between "!" and "??".

Unfolding

It was when I started to dissect the code it became apparent what it was that confused me.

I expanded
collectionOfInts?.Any() 

to
collectionOfInts == null ? null : collectionOfInts.Any()

and saw that I had a type conversion error. I had to cast null to a type.
collectionOfInts == null ? (bool?)null : collectionOfInts.Any()

Up until now I hadn't realized that the result from the "?."-operator was a nullable bool. Reading up on operator precedence I learned that the "!"-operator has much higher precedence than the "??". Those are two clues to what goes on here.

What type and value do you think the variable "result" will get in the code below?


As shown below, "result" is a nullable bool that is null! Not null is null!



This means that when collectionOfInts is null the code can be rewritten like this:
!collectionOfInts?.Any() ?? true 
!(bool?)null ?? true
(bool?)null ?? true
true


So, no sugar in this case?

After having discussed the code with the author and realizing that he also had trouble understanding what happens in the null case, I say "no"! The sugar is there to make the code more readable, but apparantly it doesn't in this case.

Make your own sugar

There is a solution though, that I find easiest to read, but was a bit surprising when I first saw it, and that is:
if (collectionOfInts.IsNullOrEmpty())

The thing that surprised me was that the author believed that you could call a method on an object that is null. But you kind of can. If the method is an extension method.

If you make an extension method like the one below it also works for strings, since a string implements IEnumerable<char>


Is it worth using the extension method and risking surprising a reader of the code?
People seem to disagree about that :)

https://stackoverflow.com/questions/790810/is-extending-string-class-with-isnullorempty-confusing
https://stackoverflow.com/questions/14196593/why-is-mystring-isnullorempty-not-built-into-net
https://stackoverflow.com/questions/8582344/does-c-sharp-have-isnullorempty-for-list-ienumerable

onsdag 28 november 2018

My first project in Python: a sudoku solver

Background

It was a weekend a few weeks ago when my youngest child saw a sudoku in the paper and wanted to solve it. It was a hard one. And when they are hard I can't keep it all in the head and need to write remaning possible numbers down, but most often I don't find room for that. And for hard sudokus you sometimes have to guess for a number and try that out. When that guess turns out to be wrong, it is no fun at all to backtrack to how the sudoku board looked like before the guess. Both problems can be solved by a computer though! :)

Last time I wrote a sudoku solver was back in 2006 when learning Ruby. I've looked in all my stashes for that code, but it seems to be lost forever. This time the language that I've been looking at besides C# was Python, but so far I hadn't written anything else than short exercises, so it seemed like a good fit to try using it for a small project like this.

I don't even dare to google for sudoku solvers, there probably exist thousands of them, but I want to do this small project in my own little bubble.

Used techniques


Knockout

This is what the board looks like. The nine squares on the board will be called "big squares", and the dots represents the squares that will be called just "squares" or "small squares".
In this example the user has entered two known values, a 9 and a 5. 



When running the solver in knockout mode it will knock out the known values from the list of possible values for all other squares. In the example below the value 9 has been knocked out from all squares inside the yellow marking which contains:
1. the big square that the 9 is in,
2. the row the 9 is in
3. and the column the 9 is in

The same goes for the 5, which affect all squares inside the red marking.

When there is a list of numbers in a small square, it is a list of values that still is valid to try out for that small square for solving the sudoku. Therefore, the lists of possible values inside the yellow marking all lacks the number nine, and all the lists inside the red marking lacks the number 5. Small squares that are inside both the yellow and red marking lacks both 9 and 5.


When the knockout runs and a value is knocked out from a square which value list suddenly only contains a single value, that square has become solved by the algorithm. Another round of knockout will be run for that square so its new value will be knocked out from all the squares the solved square affects.

Find unique value

When no more squares can be solved using the knockout technique, the next thing to look for is a list which contains a value that is unique in its big square. In the example in the image below, the square inside the red marking is the only square inside its big square (yellow) that still has the value 7 as a possible value. Therefore the square can be solved with that value and might kick off a new round of knockouts. This example won't though



Brute force

When no more can be done by the other two techniques, it's guessing time. For this, the solver goes looking for the first square with the lowest count of remaining possible numbers. In the board below it is the square marked with red that contains possible numbers 3 and 7.



The solver will begin to try with the number 3. So it sets the square to that value and then runs the "knockout" and "find unique value" routines. 
For this guess the board ends up looking like the board in the top of the image below. This board state is a fail because of the solved numbers the big square in the middle of the bottom row, there are two occurences of the number 8.

That erroneus state makes the solver understand that it has to backtrack to the last guess and try out the other value, in this case number 7.


Some sudokus requires multiple squares to be solved using the brute force routine. In the example above the printout says "Brute forcing 4 squares", which means that three other squares has gotten their value by guessing before the processing of the current square.

The code


The solution is a bit unfocused because I never decided if I wanted to build a complete solver or just a helper that could help us a little bit when trying to solve hard sudokus during the weekends. 

Another reason the code might seem strange is that I wanted to investigate the functional side of Python, but didn't get any relevation. Which isn't too strange I just found out, reading the answers in the link below. 

Over all I would say that Python isn’t very functional at all, and if you try to force a functional style into python it doesn’t feel very natural, and you will have to break out of it each time you want to use a third party library.

So writing a solver in F# or Haskell might be material for another project, but currently I'm a bit fed up with sudokus :)





söndag 4 november 2018

Are the line numbers missing in the call stack of your logged exceptions?

Sometimes when being on a bug hunt it can be a great help to read the call stack of a logged exception and to be able to see which line the exception was thrown from.

So, if your logs lacks line numbers like this one below, you don't get that extra help...

System.NullReferenceException: Object reference not set to an instance of an object.
   at LineNumberDemo.Program.ThirdMethod(Int32 value)
   at LineNumberDemo.Program.SecondMethod(Int32 value)
   at LineNumberDemo.Program.FirstMethod(Int32 value)
   at LineNumberDemo.Program.Main(String[] args)


To fix that you have to change the Debugging information setting in the project's build settings. 
- Open the Properties for your project. 
- Click Build > Advanced and change "Debugging information" from "None" to "Pdb-only".




The pdb (Program database) files contains the infomation needed to map an instruction in your program to the original line in the source file. After changing that setting the log now looks like this:

System.NullReferenceException: Object reference not set to an instance of an object.
   at LineNumberDemo.Program.ThirdMethod(Int32 value) in C:\Code\LineNumberDemo\LineNumberDemo\Program.cs:line 42
   at LineNumberDemo.Program.SecondMethod(Int32 value) in C:\Code\LineNumberDemo\LineNumberDemo\Program.cs:line 35
   at LineNumberDemo.Program.FirstMethod(Int32 value) in C:\Code\LineNumberDemo\LineNumberDemo\Program.cs:line 29
   at LineNumberDemo.Program.Main(String[] args) in C:\Code\LineNumberDemo\LineNumberDemo\Program.cs:line 16


In Visual Studio 2017, "Pdb-only" is the default setting for the Release configuration, but I'm not sure it always has been, because I've seen lots of projects that did not include the pdb-files. They make the release bigger, but as long as that isn't a problem, I don't see any reason to not include them.



Good bug hunting!