I got into the habit of doing about 30 minutes of Code Kata every morning. I practice these Kata following the test-driven development (TDD) approach.
Guile distribution includes the SRFI-64 module: a unit testing framework. In this article, I explain how to use it and how to configure it in order to practice code kata.
The SRFI-64 module has a default configuration. Let me show you what it looks like here.
Below is a Guile program that creates a test suite with only one test (doomed to fail) :
(use-modules (srfi srfi-64))
(test-begin "demo")
(test "Hookup" #f #t)
(test-end "demo")
Explanation of the program :
It is relatively simple, there are few frills.
This is the result of the execution of this suite if you save it in a
/tmp/tests.scm
file and execute the :$ guile --no-auto-compile test.scm
%%%% Starting test demo (Writing full log to "demo.log")
/tmp/test.scm:3: FAIL Hookup
# of unexpected failures 1
The console displays only a summary of the result: line 3 shows an unexpected failure from the “Hookup” test. It's very brief but it gives a quick idea of the state of the program.
The complete detail is in the /tmp/demo.log file:
cat demo.log
%%%% Starting test demo
Group begin: demo
Test begin:
test-name: "Hookup"
source-file: "/tmp/test.scm".
source-line: 3
source-form: (test-equal "Hookup" #f #t)
Test end:
result-kind: fail
actual-value: #t
expected-value: #f
Group end: demo
# of unexpected failures 1
This report gives me two pieces of information that I use a lot :
actual-value
and expected-value
.This default configuration, although ready to use, has the disadvantage of providing information in two places: in the console (list of tests and their states) and in a file (test results). Not very practical...
Fortunately, the test framework is easily configurable. In the following article, I present you with my configuration dedicated to code kata.
The idea here is to configure the SRFI-64 module to display all the information I need directly in the console (and I don't need to report in a file). I want to see at a glance :
According to the SRFI-64 reference, the objects that maintain the statistics on the test suite (total number of tests, number of successful, failed, passed, ...) are the test-runners.
Thanks to the section Writing a new test-runner and some examples gleaned from the web, you should be able to create the test-runner that suits you!
Here is the one I made for myself (based on the work of Mathieu Lirzin and Alex Sassmannshausen) :
;;;; kata-driver.scm - Guile test driver for code kata practice
(define script-version "2020-10-04") ;UTC
;;; Copyright © 2015, 2016 Mathieu Lirzin <[email protected]>
;;; Copyright © 2019 Alex Sassmannshausen <[email protected]>
;;; Copyright © 2019 Jérémy Korwin-Zmijowski <[email protected]>
;;;
;;; This program is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;;; Commentary:
;;;
;;; This script provides a Guile test driver using the SRFI-64 Scheme API for
;;; test suites. SRFI-64 is distributed with Guile since version 2.0.9.
;;;
;;; This script is a very cleaned up version of the Alex Sassmannshausen 's
;;; version. The changes make it suitable for use in a code kata practice.
;;;
;;;; Code:
(define-module (runner-kata)
#:export (test-runner-kata))
(use-modules (srfi srfi-64)
(ice-9 pretty-print)
(srfi srfi-26))
(define* (test-display field value #:optional (port (current-output-port))
#:key pretty?)
"Display 'FIELD: VALUE\n' on PORT."
(if pretty?
(begin
(format port "~A:~%" field)
(pretty-print value port #:per-line-prefix "+ "))
(format port "~A: ~S~%" field value)))
(define* (result->string symbol)
"Return SYMBOL as an upper case string. Use colors when COLORIZE is #t."
(let ((result (string-upcase (symbol->string symbol))))
(string-append (case symbol
((pass) "") ;green
((xfail) "") ;light green
((skip) "") ;blue
((fail xpass) "") ;red
((error) "")) ;magenta
result
"")))
(define* (test-runner-kata)
(define (test-on-test-end-kata runner)
(let* ((results (test-result-alist runner))
(result? (cut assq <> results))
(result (cut assq-ref results <>)))
(if (equal? 'fail (result 'result-kind))
(begin
(newline)
(format #t "~a ~A~%"
(result->string (result 'result-kind))
(result 'test-name))
(when (result? 'expected-value)
(test-display "expected-value" (result 'expected-value)))
(when (result? 'expected-error)
(test-display "expected-error" (result 'expected-error) #:pretty? #t))
(when (result? 'actual-value)
(test-display "actual-value" (result 'actual-value)))
(newline))
(begin
(format #t "~a ~A~%"
(result->string (result 'result-kind))
(result 'test-name))))))
(let ((runner (test-runner-null)))
(test-runner-on-test-end! runner test-on-test-end-kata)
runner))
I created a git repository which contains a project template for a code kata. When you run the `watch.sh' script, the terminal will reload your tests at every changes. So you are ready to code and see the feedback instantaneously. Handy, right?
No more need to look at the content of the report (which is no longer generated) to find out what the problem is. So I can execute this script in a dedicated emacs buffer, every time I save, and act according to the test results.
Choose a code kata exercise, work on it for about 30 minutes, share the link to your code and your tests in comments below!
Then, I give you my 2 cents for your next session!
Thank you so much for reading this article!
Don't hesitate to give me your opinion or ask a question! To do so, please leave a comment below or contact me.
And most importantly, share the blog and tell your friends it's the best blog in the history of Free Software! No shit!
Previously published at https://rednosehacker.com/code-kata-with-srfi-64