19 October 2023

Unit Testing Scheme

For more than four years this article has been waiting to be written. Now a rainy summer day can do wonders. Back in 2018, when I fell into Scheme, I needed a unit testing framework. I was digging into Scheme with coding exercises and wanted the quick feedback of my TDD cycle so see if I was on the right track. I did not know anything about modules, dependency management or how to get custom code in Scheme and searched the web for a small test framework. As minimalism is in the spirit of Scheme, I initially went with the Scheme Unit outlined on Cunningham's Wiki,
;
; Unit test framework for scheme
; see http://c2.com/cgi/wiki?SchemeUnit
;
(define (report-error msg)
    (display "ERROR: ")
    (display msg)
    (newline))
    
(define (assert msg b)
    (if (not b)
        (report-error msg)))
Evolution
Now that was minimalist indeed. But as good as it was, it lacked important features: I wanted more assertions, at least for all basic data types, and needed to see some colours. What is the point of a green bar, if it is not shown in green. I had created my own xUnit libraries before, one for good old Turbo Pascal and one for assembly (written in assembly - usually you would use C). While both were useful, I did not get famous for them, it seems that am focusing on "niche products" in the testing framework world. Creating my own xUnit was a kata in itself and always helped me while learning a new programming language.

I started adding more assertions already in 2015 and test cases in 2017. I kept extending it whenever I needed something new, always copying the latest file to the next code kata. In 2018 I decided to put my "SchemeUnit" up on GitHub under the name of assert-scm. Now my tests, for example the tests for the Parrot kata, look like
(include "assert.scm")
(include "parrot.scm")

(test-case "it gets the speed of an european parrot"
    (assert= 12.0
             (parrot-speed 'european-parrot 0 0.0 #f)))

(test-case "it gets the speed of an african parrot with one coconut"
    (assert= 3.0
             (parrot-speed 'african-parrot 1 0.0 #f)))
Features of xUnit
Which features are expected from a true xUnit framework? From my knowledge of JUnit, I derive the core elements of xUnit:
  • Assertions: First we need assertions. These are typically called assertSomething. Assertions are necessary to verify the actual result versus the expected one. If these values are not equal, the assertion should fail in some way. There should be assertions for equality of basic data types. In my Scheme xUnit there are (assert-true actual) and assert-false, assert= for integer numbers and symbols (and everything you can compare with = in Scheme), assert-char= and assert-string= for these primitives and assert-inexact= for floating point numbers which allows a delta for rounding errors. There are assert-null, assert-not-null, and more. As lists are the basic, all encompassing data structure in Lisp, and therefore Scheme, any testing framework for these languages needs support for comparing lists for equality: assert-list= and assert-list-deep= for flat and deep list comparison.

  • Failure Messages: Assertions need to fail with descriptive messages. For example, if two values expected and actual are not equal, I would like to see "expected: <expected value> but was: <actual value>". I hate testing frameworks which just stop with "Assertion failed." Creating good messages gets more interesting when comparing lists as they can be of different length and nested. After assertions, this is the second important thing to have.

  • Test Cases: In xUnit, test cases are often a bit weird, as they are classes containing multiple methods. Each of these methods is an individual test case because during test execution the class is instantiated for each method. In some frameworks test methods are named testSomething(), or annotations or other markers are used. In frameworks without classes, e.g. Jest or Pytest, each test function is a test case. A test case has a name, often the name of the method, some arrange code, some logic and one or more assertions. Test cases should be run independently of each other and report success or failure individually.
    (test-case "(test-case) allows several assertions"
        (assert-true #t)
        (assert-true #t))
    will print (test-case) allows several assertions .. OK.

  • Ignoring Test Cases: Sometimes I want to ignore a certain test case. Most frameworks offer ways to do that, e.g. @Ignore, @Disabled, @mark.skip or using other markers. I like the Mocha way of replacing it('') with xit('') and went for a different function ignored-test-case:
    (ignored-test-case "(ignored-test-case) is ignored, else it would fail"
        (assert-true #f))
  • Test Suites: Test suites are used to group test cases. Naturally these are Java classes, Python modules or Jest/Mocha describe blocks containing test methods. In Scheme 5 that would be files. Files can include other files which allows me to build arbitrary test suites. I rarely use test suites in any language, as I am running all tests most of the time.

  • Fixtures: Fixtures contain the necessary creation and release of resources needed for the test and make sure these are released even if the test failed. Older test frameworks allow setup and teardown methods or @Before/@After markers. Other approaches include injecting necessary dependencies, as for example JUnit 5 and Pytest do. Till now I did not need fixtures in my exercises. In small test sets, I am fine when tests stop at the first failing test.

  • Asserting on Exceptions: Few testing frameworks offer assertions for exceptions. For example in Java, before JUnit 5's assertThrows, there were 5+ ways to test that a method threw an exception. Maybe this is a special case, something that is rarely used. As I was building my assert-scm Scheme xUnit from scratch, I wanted to be sure the assertions work. How would I test for a failing assertion? I had to dig deeper into Scheme. Standard R5RS Scheme has no function to catch exceptions and different implementations handle this differently. Gambit Scheme, the Scheme I started, offers some proprietary extension for exceptions, whereas Chicken Scheme, another common Scheme, has some support for handling exceptions - called conditions. At least Chicken version 4 does, but it is outdated now. Portability is an issue between different Scheme implementations. It seems Scheme R6RS has standard support for exceptions, but its structure is way more complicated. I would like to avoid this for fun exercises.
If you are interested in features of xUnit and how to use them I recommend you work through my Unit Testing-Koans exercises.

Prime Factors
Exploring a new language is incomplete for me, until there is a nice TDD, step by step implementation of the Prime Factors kata. It is my goto exercise and I am collecting my Prime Factors solutions - which usually look the same. Here are the tests:
(include "prime-factors.scm")
(include "../assert-r5rs.scm")

(test-case "one"
    (assert-null (prime-factors 1)))

(test-case "two"
    (assert-number-list= (list 2) (prime-factors 2)))

; ...

(test-case "nine"
    (assert-number-list= (list 3 3) (prime-factors 9)))

(test-case "max"
    (assert-number-list= (list 2147483647) (prime-factors 2147483647)))
which execute in assert-scm's GitHub build,

assert-scm Prime Factors Test
and verify the code
(define (prime-factors n)
    (test-candidate n 2))

(define (test-candidate n candidate)
    (cond ((= n 1) (list))
          ((too-large? n candidate) (prime n))
          ((divides? n candidate) (keep-candidate n candidate))
          (else (next-candidate n candidate))))

(define (too-large? n candidate)
    (> candidate (sqrt n)))

(define (prime n)
    (list n))

(define (divides? n candidate)
    (= (modulo n candidate) 0))

(define (keep-candidate n candidate)
    (append (prime candidate)
            (test-candidate (/ n candidate) candidate)))

(define (next-candidate n candidate)
    (test-candidate n (+ candidate 1)))
This is neat, isn't it? If you fancy playing with Scheme and do not want to miss unit tests, check out assert-scm, a minimalist unit test framework for Scheme R5RS.

3 October 2023

I find your lack of tests disturbing

I Find Your Lack Of Tests DisturbingClassics never get old. Like with Shut up and Write a Test, I am reposting an old meme about lack of tests, see its preview on the right. Lack of tests is a direct result of not following the prior advice when to write tests. ;-) In many coaching discussions I need to fall back to the fundamental basics and I cannot allow such a gem to vanish. Usually I find the lack of tests in my client's code base disturbing.

Origin
The image was posted on rubystammtisch.at, a site which ceased to exist long time ago. I downloaded it at the 25th of March 2009 for a presentation held at the local user group. The meme is a variation of Darth Vader's "I find your lack of faith disturbing", used as a phrasal template where "faith" is swapped with other words. Now that I have researched the origin of the image, I could re-create it using Meme generators. I will not, a classic is a classic. (And again, during writing a blog post, the process of writing is valuable and I learn on the way by organising and structuring the material. That is why I recommend writing as a learning and teaching activity at the same time.) Unfortunately the original image is only 400 pixel width, printed versions will be fuzzy. It might use it on my upcoming Code Cop Veto Cards, similar to my Achievement Appreciation Cards, as cards require smaller images with less detail.

I find a lack of tests disturbing.

19 August 2023

Unusual Personal Branding

Brennstempel ALK T4I like personal branding and use a lot of branded items. Besides my obvious Code Cop business cards, I use "Code Cop approved" buttons and stickers as giveaways. I wear my Code Cop shorts and hoodies when meeting new clients and when speaking at conferences. I enjoy keeping track of my reading progress using my Code Cop hand crafted book marks. What else could there be? After the embroidery prototype I was looking for something new to add to my branding toolbox.

Branding Iron
I have no memory of how I ended up with the idea, but I got a Code Cop branding iron. No I do not own any cattle or sheep which I need to mark, but at least "branding iron", gives a new meaning to "developer branding". My branding iron, see its picture on the right, needs to be plugged into electricity to warm up and after ten minutes it is ready. I have no idea how I will use it professionally - I am not selling anything in wood crates that could be marked - but I have a lot of fun marking everything in the house: For example, all my Escrima sticks and tool handles are clearly Code Cop's now.

Code Cop Logo Branded Sticks
Medallion
Later, after watching Netflix' The Witcher, I toyed with the idea of a Code Cop medallion, like Geralt is wearing. The Witcher's medallion is pretty large and has a raised and relief design, which means part of the silver wolf's head has a 3D effect. I searched online shops for some month for custom pendants. Most places offer two dimensional ones, using vector graphics to drive the cutting or engraving machine. I tested one such design with a simple pattern. The pendant was fine but it was too thin and flat for me. That was not what I had envisioned.

Eventually I found Lucas from Valeria Custom Jewellery who offered similar custom pendants. He 3D printed a mold and casted silver to create the three dimensional form on top of a large medallion. He sent me several work in progress images to check. During the whole process the cost went over the top, as I wanted a certain (too) large size, then shipping and tax for goods from overseas added on top. The total cost makes me wary to wear it. Further my wife keeps reminding me that I am not a rapper with their oversized and lavish jewellery ;-) While I am not wearing it, my Code Cop medallion is my most favourite branded item, sitting on my work desk right in front of me.

Code Cop Logo Medallion
To make my medallion more "magic" like Geralt's one, I fancy some engraving at its flat, smooth back. Maybe some piece of source code that is of general significance? Which code would that be? Surely code like the Apollo-11 guidance system or the first Linux kernel are relevant. There are some collections like Computer History Museum's source code. Usually these are many pages of assembly. As the medallion is small compared to that, the code would have to be really short, a few statements at most. Maybe I will go with Greg Walsh's famous Fast Inverse Square Root calculation from Quake III source code: 0x5f3759df.

1 August 2023

Shut up and write a test!

Due to the hype around ChatGPT I wanted to create this text with it. I failed. I tried several versions of different prompts, and also asked the Bing variant, but it failed to create any text I liked. It could not simulate my personal style. I should have to train a model with all my blog posts ... It seemed easier to use with the good old method of writing my texts myself.

Should I Write a Test?
Around ten years ago I stumbled upon a diagram if and when to write a test. This was a repeating question in trainings, when should you write tests? Before or after writing the code? Only when you have time? Only when you feel like it? I loved the diagram because there was only one end state. Whatever the reason or excuse would be, just shut up and write a test! It does not matter if you are tired, or if it is a little change, it should be tested. Such a rule is helpful when you want to adopt Test Driven Development, as there are plenty of excuses why to skip it.

Shut Up and Write a Test!
The original diagram was created by Gemma R Cameron, a software engineer and event organiser from Manchester. She was inspired by a similar diagram about skating. Recently, when I was asked again when to test, I wanted to share the diagram and could not find its page. I thought it lost and planned to repost the diagram here. Eventually I discovered Gemma's page again, it had moved from a .me to a WordPress domain. I am glad that the original source is still available. You can find it here.

Java Version
The original version of the diagram was for Ruby, indicated by the use of Automock. What was bad with Automock? It provided some support for automated mocking of Rails application and is dead since 2016. Here I present a slightly modified version for Java, replacing Automock with PowerMock. And I do know what is wrong with PowerMock. It is a powerful mocking tool which uses a custom class loader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods and more. It is useful to bring legacy code under test, before seams can be introduced. The bytecode manipulation makes it slow compared to regular mocking. If used often, the whole test suite will run much longer than needed. Further, if code is hard to test, I change its design to make it testable by applying SOLID principles or by creating seams as outlined by Michael Feathers in his WELC book. Using PowerMock for tests does not improve the design. (I am not inherently against PowerMock, it is extremely powerful and as such dangerous. I needed something to replace Automock.)

Download and print the Java version of the Shut up and Write a Test Diagram. The fact that there are versions of this diagram for both Ruby and Java is a testament to the universality of its principle: Shut up and Write a Test! The Code Cop approves, and I am sure your future self will too.

15 March 2023

I want you to exceed me

During my time at IBM I started coaching other teams. It was fun and I liked it. Later I went into full time training and coaching, and my motto was "Developing Quality Software Developers". I knew it was the thing I wanted to do, but I did not know why.

Gamification
I use Gamification as a strategy to improve user engagement. To increase participation in my workshops and to express my feelings about that, I created achievement cards, the Code Cop Achievement Cards. Achievements or trophies are concepts from video games, and describe meta-goals defined outside the game's parameters. Meeting the fulfilment conditions, and receiving recognition of fulfilment by the game, is referred to as unlocking the achievement. There are several cards for first time participants in my deck, for example Shortcut Fu when someone uses a rare keyboard short-cut, Regexer for comprehending a crazy regular expression or Finisher for finishing the coding exercise started during the workshop at home - which I always offer but rarely happens. I award these cards to a participant, if I feel that the person has worked hard or struggled to make it.

Appreciation
I wanted my cards to convey my honest appreciation and used NVC (Non-violent Communication) appreciation statements. For a NVC-style appreciation we share the specific actions that contributed to our well-being, the needs that have been fulfilled, and the feelings engendered by the fulfilment of those needs. The focus is to create a clear understanding of how our life was enriched.. This made me think more about my feelings and which of my needs had been satisfied at the moments when I wanted to appreciate some action. I had thought about needs before in more general, less personal way. My friend and NVC coach Aki Salmi helped me to formulate these statements using different phrases to avoid having the same text on each card again and again: For example: "I value the usage of short-cuts as effective and as sign of ongoing mastery in our craft." "I am touched to see courage in situations of uncertainty, risk and emotional exposure." "I am amazed by critical questions based on creativity and independent thought." "I am inspired by the integrity and consistency of sticking to principles in difficult situations." The process of finding the right words alone strengthened my ability to express my feelings dramatically.

Very Personal Appreciation Badge (copyright Peter Kofler) Scrutiny
Some of my appreciation cards celebrate learning, including stepping out of one's comfort zone, which is required for learning. One card I of these is titled "Scrutiny", subtitled Correct me when I am wrong. It shows a Whistle icon (by Delapouite CC BY 3.0) and the appreciation is "I am proud when you correct me, showing independence and competence." It does not happen often - still sometimes in a pairing or ensemble session, my focus may slip and I make a mistake or do not call out a mistake on time. And then, sometimes, someone else does.

Growth
There is a common theme in most of my cards: growth. Now that I have seen it, it is obvious to me. Growth is one of my major needs. I want to grow - e.g. learning new languages and other stuff regularly. And I want the people I coach and work with to grow, too. My second motto - surfacing around 2013 - "Developing Quality Software Developers" expresses that clearly. I want them to grow, to learn, to improve - and I am inspired and amazed the most, when they exceed me.

Snatch the Pebble From My Hand
There is nothing more satisfying than when a pupil exceeds his or her master. This is often depicted in movies, where a student must learn a lot, for example in Kung Fu movies: In the television series Kung Fu, Caine is an orphan and is accepted into a Shaolin Monastery. Part of the Shaolin way of life is strengthening the body and the mind. For example, one of Caine's teachers asks him to "snatch the pebble from my hand":


Then, after many years of training, Caine is finally able to beat his master:


What a satisfying moment, and Caine's master smiles. This is one of my favourite TV moments ;-) Like being corrected (see Scrutiny card above), "snatch the pebble from my hand" situations make me proud of my students.

Make Me Look Like a Baby
I want to leave you with a quote from a different and maybe more controversial source of motivation than Caine, ex Navy SEAL member Jocko Willink: Don't try and be like me. Be better than me. Crush me. Make me look like a baby. That's what you do. (Even better when he says it himself.) - OK, maybe there is too much testosterone here ;-)