Zombie Elm - Part 3 - Testing
The goal for this spike. [ ] Have a test running
Tests
I don’t feel a need to test every single thing in Elm, cause the compiler does tell if I’m about to make a stupid mistake, but some tests would be nice. Shuffling the tiles seems to be a candidate for a good test, so I’ll try to verify that it always creates the same tile list when initialised with the same seed.
Going to be using [elmtest][Elm-test] from [dfg][deadfoxygrandpa] following his ‘Getting started’ guide.
My first test in elm
npm install -g elm-test && elm-test-init
Created C:\src\zombie-elm\tests
Created C:\src\zombie-elm\tests\elm-package.json
Created C:\src\zombie-elm\tests\TestRunner.elm
Created C:\src\zombie-elm\tests\Tests.elm
Created C:\src\zombie-elm\tests\.gitignoreI then added a “test” target in package.json, allowing me to do “npm test” to run my tests. (It even worked on windows, as is visible from the console output)
Testing the shuffleTiles method
My assumptions
- I will have a shuffle method accepting a seed and the list to be shuffled.
- This will return a new shuffled list and a new seed.
Elm-test to my delight had already added ../src as a source directory, so Main.elm and Zombie.elm was available for import. My test then becomes
all : Test
all =
let
tiles =
List.map newTile [ "h1", "h2", "h3", "h4" ]
seed =
initialSeed 1
model =
Model seed tiles
shuffledModel =
shuffleTiles model
shuffledModel2 =
shuffleTiles model
nextModel =
shuffleTiles shuffledModel
in
suite
"Shuffles"
[ test "Always gives same result when initialised with same seed" (assertEqual shuffledModel.tiles shuffledModel2.tiles)
, test "When called again with new seed gives different result" (assertNotEqual shuffledModel.tiles nextModel.tiles)
]And this runs, and fails, since I hadn’t implemented the method.
Making the tests green
I couldn’t find a good way to shuffle a list in the language.
Eventually I found NoRedInk’s [ere][elm-random-extra] with a Random.Array.shuffle method which seemed to do the trick.
It’s type signature was shuffle : Array a -> Generator (Array a) which forced me to learn Elm’s Random library has a generate method which I can call with a generator and a Seed.
But it only takes an array, and my Model contains a list of tiles….
Fortunately Array has fromList and toList which simplified things.
The generate method returns a tuple of the generated object and a new seed, so you don’t regenerate the exact same result on each call.
In the end I was rather satisfied with my solution. I can understand each step now, and I think I will understand it if I come back to it in a month or two.
shuffleTiles : Model -> Model
shuffleTiles model =
let
tilesArray =
fromList model.tiles
generator =
shuffle tilesArray
shuffles =
generate generator model.seed
shuffledTiles =
toList (fst shuffles)
newSeed =
snd shuffles
in
{ model | tiles = shuffledTiles, seed = newSeed }Adding that method to my Components.Zombie makes the tests run green.