I was reading about domain specific languages and one of the interesting applications is framework for behaviour driven development (there are lots more of course). With Python it should be relatively easy to construct language like that, but I chose a little bit different approach on a test that I wrote as an exercise:
Pete = strong(Adventurer()) Uglak = weak(Goblin()) place(Uglak, middle_of(Level())) place(Pete, right_of(Uglak)) make(Uglak, hit(Pete)) assert_that(Pete, has_less_hit_points())
This hides all the nasty details about factories, parameter classes and random number generator stubbing, leaving only the most important parts of the test visible. There isn’t a setup method to set up the testcase, because in this case it probably would make test harder to understand (and granted, there isn’t exactly that many lines of code).
Pete and Uglak are both instances of Character class. One of them is modified to be strong, while other is weak. Both are located on an empty level, Uglak standing in the middle and Pete right next to him (on right side).
When Pete gets hit by Uglak, his hit points should go down (not much, he’s not going to die from a single weak hit).
The visible code in the test case is considerably shorter than what it would have been if I had written it a year ago. At that time all the details of the test would have been visible in the test case (or in the setup) and reading through it later would have confused me.
I could refine the code behind the scenes a lot more. One idea would sprinkle it generously with various asserts that would check if operation was successful. When the test is accidentally run on a level consisting of solid rock, trying to place Uglak in the middle of it could detect this by assert and announce that “Tried placing Uglak in the middle of the level, but there was solid rock there”.
By defining more verbs (place, make, hit), nouns (Adventurer, Goblin) and those others which names escape me (right_of, middle_of) I could build a dictionary that can be used in high level testing. Tests with high level of abstraction would define how system is supposed to work (outer quality) and lower level tests would guide the design and ensure that the code works (internal quality).