<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Joep Schuurkes (Posts about programming &amp; test automation)</title><link>https://smallsheds.garden/</link><description></description><atom:link href="https://smallsheds.garden/categories/cat_programming-test-automation.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:site@joep.slmail.me"&gt;Joep Schuurkes&lt;/a&gt; 
&lt;a href="https://creativecommons.org/licenses/by-nc/4.0/" rel="nofollow" target="_blank"&gt;
&lt;img alt="Creative Commons BY-NC License" style="border-width:0;margin: 0px 0px 0px 0px" src="https://licensebuttons.net/l/by-nc/4.0/80x15.png" /&gt;
&lt;/a&gt;
</copyright><lastBuildDate>Wed, 22 Apr 2026 17:46:51 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Benchmarking counterstring implementations in TypeScript</title><link>https://smallsheds.garden/blog/2025/benchmarking-counterstring-implementations-in-typescript/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;Earlier this year I posted about how I &lt;a href="https://smallsheds.garden/blog/2025/using-fake-it-till-you-make-it-to-implement-counterstring/"&gt;implemented a counterstring function&lt;/a&gt; using "fake it till you make it". I also posted about &lt;a href="https://smallsheds.garden/blog/2025/comparing-counterstring-implementations-in-typescript/"&gt;different ways&lt;/a&gt; to implement counterstrings. In this post, I want to share how those different implementations compare performance-wise.&lt;/p&gt;
&lt;p&gt;To do this, I used both &lt;a href="https://github.com/tinylibs/tinybench"&gt;Tinybench&lt;/a&gt; and &lt;a href="https://vitest.dev/guide/features.html#benchmarking"&gt;vitest bench&lt;/a&gt; (which uses Tinybench). The results are basically the same, but their default output is slightly different.&lt;/p&gt;
&lt;h2&gt;The nine implementations&lt;/h2&gt;
&lt;p&gt;Before I present the results, I should describe the different implementations and how they differ from each other. The &lt;a href="https://codeberg.org/joeposaurus/counterstring/src/commit/04883b7bb2f3e99f7be81ffa58e4ac5f934d276b/src/alt-counterstrings.ts"&gt;actual code of each implementation&lt;/a&gt; is available on Codeberg. Here I'll only mention what makes each implementation interesting compared to the others:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2025/benchmarking-counterstring-implementations-in-typescript/"&gt;Read more…&lt;/a&gt; (8 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>counterstring</category><category>programming</category><guid>https://smallsheds.garden/blog/2025/benchmarking-counterstring-implementations-in-typescript/</guid><pubDate>Sat, 22 Feb 2025 23:00:00 GMT</pubDate></item><item><title>Comparing counterstring implementations in TypeScript</title><link>https://smallsheds.garden/blog/2025/comparing-counterstring-implementations-in-typescript/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;In my previous post &lt;a href="https://smallsheds.garden/blog/2025/using-fake-it-till-you-make-it-to-implement-counterstring/"&gt;"Using 'fake it till you make it' to implement counterstring"&lt;/a&gt; I mentioned the implementation I included there, wasn't my initial implementation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I did something less performant with reversing an array, because I had looked at PerlClips's source code. How that came about and what I learned from it, is for another blog post.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is that blog post.&lt;/p&gt;
&lt;p&gt;As a matter of fact, I currently have &lt;a href="https://codeberg.org/joeposaurus/counterstring/src/commit/04883b7bb2f3e99f7be81ffa58e4ac5f934d276b/src/alt-counterstrings.ts"&gt;9 different implementations&lt;/a&gt; of counterstring in TypeScript. Including two that are not mine: one is from &lt;a href="https://www.satisfice.com/download/perlclip"&gt;PerClip&lt;/a&gt; but translated to TypeScript by me, the other is &lt;a href="https://www.eviltester.com/blog/eviltester/chrome-extensions/2019-02-19-counterstring-snippets/#counterstring-generation-function"&gt;EvilTester's implementation&lt;/a&gt;. There are some interesting lessons to take, both from comparing the code of the different implementations, as from comparing the differences in performance. The &lt;a href="https://smallsheds.garden/blog/2025/benchmarking-counterstring-implementations-in-typescript/"&gt;performance-part of the comparison&lt;/a&gt; will have to wait for my next post, though.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2025/comparing-counterstring-implementations-in-typescript/"&gt;Read more…&lt;/a&gt; (10 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>counterstring</category><category>programming</category><guid>https://smallsheds.garden/blog/2025/comparing-counterstring-implementations-in-typescript/</guid><pubDate>Sat, 18 Jan 2025 23:00:00 GMT</pubDate></item><item><title>Using "fake it till you make it" to implement counterstring</title><link>https://smallsheds.garden/blog/2025/using-fake-it-till-you-make-it-to-implement-counterstring/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;Last week I implemented &lt;a href="https://www.satisfice.com/download/perlclip"&gt;PerlClip&lt;/a&gt;'s &lt;a href="https://www.satisfice.com/blog/archives/22"&gt;counterstring&lt;/a&gt; in TypeScript. A counterstring is a string that tells you how long it is. For example a counterstring with length 9 looks like this: &lt;code&gt;*3*5*7*9*&lt;/code&gt;. Each number tells you the position of the asterisk following the number. My main goal with this project is to learn more about front-end development.&lt;/p&gt;
&lt;p&gt;Before I could start doing any front-end stuff, however, I needed to write a function that correctly generates counterstrings. Since I approached it in a way that I really enjoyed, inspired by Llewellyn Falco &lt;a href="https://youtu.be/O1h9ho2G85Q?t=155"&gt;"Fake it till you make it"&lt;/a&gt;, I figured it would make a good first post about this project.&lt;/p&gt;
&lt;p&gt;The idea behind "fake it till you make it" is simple. Start with an implementation covering a single case ("fake it") and then pull it apart little-by-little until it becomes an actual program ("make it"). As Llewellyn explains in the video, the value of this technique is that it's a lot easier to start from a working example and proceed from there than it is to get complete requirements.&lt;/p&gt;
&lt;p&gt;I did approach counterstring from the opposite direction, though, as Llewellyn did with Fizzbuzz in the video. Llewellyn starts with FizzBuzz length 20, so a case covering all the logic. Then he refactors it using different techniques, such as separation and encapsulation. While I started with counterstring length 0, the most simple case, and then worked my way up to larger lengths.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2025/using-fake-it-till-you-make-it-to-implement-counterstring/"&gt;Read more…&lt;/a&gt; (4 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>counterstring</category><category>programming</category><category>small steps</category><guid>https://smallsheds.garden/blog/2025/using-fake-it-till-you-make-it-to-implement-counterstring/</guid><pubDate>Sat, 04 Jan 2025 23:00:00 GMT</pubDate></item><item><title>What do you fix when you fix a test?</title><link>https://smallsheds.garden/blog/2024/what-do-you-fix-when-you-fix-a-test/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;You ran the tests&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="https://smallsheds.garden/blog/2024/what-do-you-fix-when-you-fix-a-test/#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; - or a pipeline did it for you - and some of them failed. Time to fix the tests! But what is it exactly that needs fixing?&lt;/p&gt;
&lt;p&gt;There are quite a few things that might make a test fail:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;an issue with the build&lt;/li&gt;
&lt;li&gt;an issue with the pipeline (if that's where the test runs)&lt;/li&gt;
&lt;li&gt;an issue in the environment the code under test is running on&lt;/li&gt;
&lt;li&gt;an issue in the environment the test code is running on&lt;/li&gt;
&lt;li&gt;a bug in the code under test&lt;/li&gt;
&lt;li&gt;a mistake in the test code&lt;/li&gt;
&lt;li&gt;a mistake in what the test should test&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Arguably, on the last three describe a test that fails. The test did its job detecting a problem. In the first four we didn't even get that far. The issues prevented the test from doing its job. So in those cases, it's not the test(s) as such that need fixing.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2024/what-do-you-fix-when-you-fix-a-test/"&gt;Read more…&lt;/a&gt; (5 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>coverage</category><category>quality engineering</category><category>software testing</category><category>test automation</category><category>test strategy</category><guid>https://smallsheds.garden/blog/2024/what-do-you-fix-when-you-fix-a-test/</guid><pubDate>Sat, 24 Aug 2024 22:00:00 GMT</pubDate></item><item><title>Tackling test automation in a new language</title><link>https://smallsheds.garden/blog/2024/tackling-test-automation-in-a-new-language/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;While there's value in learning all the ins-and-outs of one particular language, its ecosystem and its testing libraries, I think there's also a lot of value in having experience in several. Or at least, in two. If you only know one, you don't really know what's essential and what's incidental to the one set of tools you know. You don't know from experience in what ways things could be different.&lt;/p&gt;
&lt;p&gt;Picking up a new language is not trivial though, especially if it's your second one. There will be a lot to learn. You will notice similarities between the new language and the one(s) you already know. Sometimes those similarities will help you, sometimes they will mislead you.&lt;/p&gt;
&lt;p&gt;Also, it's more than picking up a new language. There are also the testing libraries you will use
and the language's ecosystem (e.g. how to install those libraries&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="https://smallsheds.garden/blog/2024/tackling-test-automation-in-a-new-language/#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; or how to set up a pre-commit hook with a linter). That's quite a package.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2024/tackling-test-automation-in-a-new-language/"&gt;Read more…&lt;/a&gt; (3 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>agile</category><category>communication</category><category>programming</category><category>test automation</category><guid>https://smallsheds.garden/blog/2024/tackling-test-automation-in-a-new-language/</guid><pubDate>Sat, 10 Feb 2024 23:00:00 GMT</pubDate></item><item><title>A lesson from every language I've used</title><link>https://smallsheds.garden/blog/2023/a-lesson-from-every-language-ive-used/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;Throughout the years I've used quite a few different languages - if you allow me to be somewhat generous with the word "use". One language I actually feel proficient in. Some languages I've only done coding exercises in. And one language I've only used for a total of maybe 10 minutes, but that did really help out a whole team.&lt;/p&gt;
&lt;p&gt;I do believe we should be that generous, both towards ourselves and to others. For an industry that likes to talk about imposter syndrome, we seem to enjoy saying &lt;em&gt;"You're not a real ... unless..."&lt;/em&gt; a bit too much.&lt;/p&gt;
&lt;p&gt;Listing these languages for myself made me wonder what I had learned from them. Did I just learn how to write some code in each of them? Or did I also pick up some more general lessons? Turns out I did.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2023/a-lesson-from-every-language-ive-used/"&gt;Read more…&lt;/a&gt; (5 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>clojure</category><category>programming</category><category>python</category><guid>https://smallsheds.garden/blog/2023/a-lesson-from-every-language-ive-used/</guid><pubDate>Thu, 28 Dec 2023 23:00:00 GMT</pubDate></item><item><title>Getting [name] from "Name: [name]" in Python - an engineering problem</title><link>https://smallsheds.garden/blog/2019/getting-name-from-name-name-in-python-an-engineering-problem/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;Today I was presented with an interesting engineering problem. (Important later: context was the code of an auto-test.) Given a string of the format "Name: [name]", what's the best way to get the [name] in Python?&lt;/p&gt;
&lt;p&gt;There are several options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lstrip()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;split()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;replace()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;string slicing&lt;/li&gt;
&lt;li&gt;regex&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So let's look at each of them and then I'll explain which one I prefer and why. All examples are in Python 3.6, using the &lt;a href="https://docs.python.org/3.6/tutorial/interpreter.html"&gt;Python Interpreter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2019/getting-name-from-name-name-in-python-an-engineering-problem/"&gt;Read more…&lt;/a&gt; (5 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>programming</category><category>python</category><category>semantics</category><guid>https://smallsheds.garden/blog/2019/getting-name-from-name-name-in-python-an-engineering-problem/</guid><pubDate>Mon, 26 Aug 2019 19:27:38 GMT</pubDate></item><item><title>How this tester writes code</title><link>https://smallsheds.garden/blog/2019/how-this-tester-writes-code/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;A long time ago (March 2015) I wrote a post titled "&lt;a href="https://smallsheds.garden/blog/2015/test-automation-five-questions-leading-to-five-heuristics/"&gt;Test automation - five questions leading to five heuristics&lt;/a&gt;". Later that year &lt;a href="https://twitter.com/richrtesting"&gt;Rich Rogers&lt;/a&gt; asked for a follow-up. To which I replied I should do a follow-up post (ahum) "soon".
Then last Wednesday &lt;a href="https://twitter.com/noahsussman"&gt;Noah Sussman&lt;/a&gt; said on &lt;a href="https://twitter.com/noahsussman/status/1136288062651142149"&gt;twitter&lt;/a&gt;: &lt;em&gt;'I don't know that I've *ever* seen "this is how testers write code"'&lt;/em&gt;. To which I replied "challenge accepted", so now here we are, me writing a blog post about how I as a tester write code.&lt;/p&gt;
&lt;p&gt;The format of this post turned out to be advice based on my experiences, so the usual disclaimers apply. And feel free to leave a comment if you have any feedback!&lt;/p&gt;
&lt;h3&gt;The basics&lt;/h3&gt;
&lt;h4&gt;use an IDE&lt;/h4&gt;
&lt;p&gt;An IDE is not just an advanced text editor. It understands your code - to a degree, since it's not interpreting, compiling or executing the code. So not only allows an IDE you to manipulate your code as text, it also allows you to manipulate your code as code.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2019/how-this-tester-writes-code/"&gt;Read more…&lt;/a&gt; (14 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>heuristics</category><category>IDEs</category><category>programming</category><category>python</category><category>test automation</category><guid>https://smallsheds.garden/blog/2019/how-this-tester-writes-code/</guid><pubDate>Sat, 08 Jun 2019 16:21:38 GMT</pubDate></item><item><title>Test automation - five questions leading to five heuristics</title><link>https://smallsheds.garden/blog/2015/test-automation-five-questions-leading-to-five-heuristics/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;&lt;em&gt;I wrote a &lt;a href="https://smallsheds.garden/blog/2019/how-this-tester-writes-code/"&gt;follow-up&lt;/a&gt; to this post in June 2019 in which I &lt;a href="https://smallsheds.garden/blog/2019/how-this-tester-writes-code/#revisiting-my-blogpost-from-2105"&gt;revisit the heuristics&lt;/a&gt; from this post.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In 1984 Abelson and Sussman said in the Preface to '&lt;a href="https://mitpress.mit.edu/sicp/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;':&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our design of this introductory computer-science subject reflects two major concerns. First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. &lt;strong&gt;Thus, programs must be written for people to read, and only incidentally for machines to execute.&lt;/strong&gt; Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems. [emphasis mine]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This oft-quoted sentence I emphasized, is even more true if the purpose of our programs is test automation&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="https://smallsheds.garden/blog/2015/test-automation-five-questions-leading-to-five-heuristics/#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. So let's say you run your test automation program and the result is a list of passes and fails.  The purpose of testing is to produce information. You could say that this list of results qualifies as information and I would disagree. I would say it is data, data in need of interpretation. When we attempt this interpretation, we should consider the following five questions.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2015/test-automation-five-questions-leading-to-five-heuristics/"&gt;Read more…&lt;/a&gt; (6 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>heuristics</category><category>programming</category><category>test automation</category><category>testing and checking</category><guid>https://smallsheds.garden/blog/2015/test-automation-five-questions-leading-to-five-heuristics/</guid><pubDate>Tue, 24 Mar 2015 19:53:24 GMT</pubDate></item><item><title>Lessons learned in some test automation</title><link>https://smallsheds.garden/blog/2013/lessons-learned-in-some-test-automation/</link><dc:creator>Joep Schuurkes</dc:creator><description>&lt;div&gt;&lt;p&gt;In the past two weeks I built a test tool in VBA (Visual Basic for Applications). I did this, because two weeks ago my fellow tester showed me an important test we have to do at least once for each major release. The test consists of having the application generate three reports in Excel format. On two of these reports you apply a set of filters and take the sum of a few columns, rinse and repeat. Then you add several of those sums together and the results of those calculations should match the numbers in the third report. So basically, the point of the test is to check if the numbers in the three reports add up. And it's a lot of work, i.e. about two days.&lt;/p&gt;
&lt;p&gt;After being shown how to perform the test, the first thought that popped into my head, was: "Boring!" The second thought was: "It's automatable!" And since there was little else to do - delivery of the new test environments was delayed - I changed it from automatable to automated.&lt;/p&gt;
&lt;p&gt;So now, after two weeks, I have this tool in VBA. For each of the three reports it contains a sheet in which you define the sets of filters and sums. If you click a big button, the report is opened and the filters and sums are applied. There's also a fourth sheet to do the second set of calculations and to do the check if the numbers match. This last part is not done in VBA; it's all formulas in Excel.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://smallsheds.garden/blog/2013/lessons-learned-in-some-test-automation/"&gt;Read more…&lt;/a&gt; (8 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>programming</category><category>test automation</category><category>VBA</category><guid>https://smallsheds.garden/blog/2013/lessons-learned-in-some-test-automation/</guid><pubDate>Mon, 18 Feb 2013 20:46:02 GMT</pubDate></item></channel></rss>