When is the right time to break something?

Please excuse this sensational headline. I am referring to classes in your software and to their design. But also to tests, but see below…

Work

The past week I mainly tried to pair with my fellow developers to impart some knowledge onto them. We worked together on integration tests with Nightwatch.js which is something like Capybara from the Ruby world. A question that came up was “when do we stop testing?”

I have to share some details about our setup: We created a React application for the frontend and use the APIs provided by the backend developers. Those APIs are sometimes flaky. And generally it would be a bad idea to access them during the tests. This is because they would introduce a dependency in your tests that is outside of your control. Do you want to have your tests fail, because somebody changed something inside the APIs? And would you like your tests to succeed, regardless of whether the API was accessible or not?

The answer for both question is “yes”. The first type of test is a system test, where you do a complete blackbox-style test of your system for (mostly) functional requirements. If the API changes, you would want to know. And you would like to have your tests fail and notify you of that change. Well, you would want the backend dev to notify you beforehand, but still…

The second type of test I was describing is an integration test. You want to find out whether the code you wrote tries to access the API in the required way and whether your software behaves as specified for the API’s responses. But you don’t need the actual API for that. You should use a MOCK API that replaces the real API and behaves just the same. And this mocked API should be under your control.

So much for the details. Because we wrote integration tests against the mocked API. We sent a request to get data, let’s call it a widget and we specified it by its ID.

GET /widgets/123-567-890 => widget.json

We received JSON and displayed the widget in a form, so the user is able to edit it.

In this test, we edit a widget’s category only. We send a PUT request with the whole object, even though we only update the category (A PATCH would be enough, but this is what the API specified…). We send the request to our mocked API. Since this was the “happy path” testing, we received a response that indicated a success. 🎉

A bit more of background:

  • Back in our UI, where we display the widget, we do not display the category.
  • When we get a successful response for the request, we update the internal state of the app (we don’t use Redux). So we “save” the category.
  • When we open the form the edit the widget, we fetch data from the API first and display that to edit.

Now the question was: “Where do we stop testing?” Since we mock the successful response anyway, do we test that we update the internal state with the widget? But we don’t use or display that state (the updated category) anyway?!

I want to say, I had to think about this for a while. I wasn’t sure what the best way would be. One answer could’ve been to display the edited category somewhere accessible for the test (perhaps as a data-attribute). But where’s the business value in that?

A better answer turned out to be:

  • For the happy path test for a successful response and be done
  • Add tests for the failure case of unsuccessful responses

And the test and it’s questions revealed another thing: We do not need to store the updated category right now. The person who wrote that code did it with a possible future requirement in mind. But it wasn’t and isn’t necessary right now. But since they didn’t use TDD to create the code and its design, they didn’t notice.

So that’s one more history for “tests help increase the quality of code and design”.

This is already long and I wanted to share something on the size of classes and when to refactor them. I guess this has to wait for the next issue.

Talks/webinars

This topic from last week resonated with you. Thanks for the many responses. I will take you up on your offers and put you in a virtual crowd using Zoom, next time I am doing something like this.

Personal

Fixed gear bikes seem to be a favorite for many readers. I hadn’t anticipated that you would have experience riding these. I was glad I shared it.

On a completely unrelated note: In the future I will factor into my selection of clients whether they have a shower in their office or not. Having access to one helps me tremendously to combine my training plans into my working plans. Just yesterday I was able to do an intense interval running training on my way to my client because I knew I could shower afterwards. The alternative would have been to do it in the evening. But I’d rather spent the evening with my family instead. So this really increases my happiness.

Another personal endeavor of mine is to decrease my reliance on external/3rd party solutions for syncing data and storing it. This means stuff like iCloud and Dropbox but also other proprietary solutions inside apps that I use, e.g. DayOne.app

If I write my thoughts for years and years, I do not want to rely on some business to be able to access it. Same with my own business content. I mostly write code and articles, but also thoughts on strategy and lots of other things. I plan my business for the long run, which means I want to be able to access these things forever.

That’s why I begin to turn away from iCloud and friends. I don’t use Ulysses anymore for writing, but Joplin. I run my own cloud service (Nextcloud) and sync all my encrypted plain text files to the cloud and between my devices. That way I can tripple-back-up everything. Joplin is FOSS. I can save the source code in its current state (you bet I already did!) and will be able to access my notes for as long as I have a computer.

So I started migrating my data from the different apps I used to Joplin. This is an ongoing task and I also began to write an Importer to do this automatically. I have thousands of entries and notes in DayOne and other apps. It’s quite a challenge. But this makes sense to me.

Speaking into a microphone

Work

On Tuesday I did something new for the first time. And I feel like I failed miserably. I hosted a webinar. Back in the beginning of the year, I sent out proposals to a bunch of conferences with the goal of giving a talk. A conference by NAGW (National Association of Government Web professionals) accepted my submission. I was supposed to give a talk in Utah in September. Due to calendar issues I had to cancel that appearance. So they asked me whether I was up for giving the talk as a webinar to their audience, which I happily agreed to.

Turns out I need people with faces in front of me! Once the time came to start the webinar I was so excited/anxious that I was barely able to keep my breath down. It almost felt like a small panic attack. I don’t know how it came across to the listeners (it was audio-only) but I felt like I could hardly talk or speak. Which made me speak so unbelievably fast that I went through the whole material in half the time it usually takes me. And I bet I forgot a whole lot of things that I should have said. I do know that I am excited and nervous every time I start a talk in front of a crowd of people. But usually this nervousness fades after 3-5 minutes, once I scanned the room and felt the (positive) reactions of the crowd. After all, your listeners want you to “succeed” and give a great talk. But I had nothing of that during the webinar. I had no reassurance that people actually understood what I was talking about. In any case that felt bad. I learned something from that experience. The first reaction was to never give a webinar again. The second experience was that I need to have a different setup next time. I need to interact with people and for that I will try to use the chat-tool that every webinar software offers. I don’t know how well that works, but I will do what works for me almost always: Be frank and open and tell the audience about my anxiousness and let me help them through their interaction in the chat. It think that’s at least worth a try before abandoning webinars altogether.

August has started and it’s the last month at my current client. This means that I will begin to do a lot more pairing with the permanent developers, and less writing features/code myself. This way knowledge transfer is increased and the company and the people get more out of it. This will be more demanding than the months before, but it’s worth it.

If you’ve been part of this newsletter community for some time, you might remember that I told you about an online course on testing, that I was about to create and release. I still am doing this, but I got stuck. It is the first course that I am creating and will no experience I hit some road blocks that I couldn’t solve on my own. Thus, I entered an online community/course on course building, how meta 😉. With this help I am absolutely sure that I can solve the issues and create an interesting pilot course. I will reach out to you again, once I am looking for participants for that.

Personal

I bought yet another bike. 😝 I do love my bikes, and I found a great bargain on eBay with a steel frame, only one year old for half the original price. So I bought it. It’s a fixed-gear bike, which means you cannot coast and have to move the legs at all times. Riding home on it yesterday evening I noticed how incredibly a meditating experience this is. As a beginner with fixed-gear bikes like me, you have to be so 100% aware of what you’re doing at all times. There was no space left in my head to think about anything but moving my legs and riding this bike (“don’t stop pedaling”). Because if you, for one second, stop pedaling, the pedal will still move upwards (rotate) and your leg will move and might catapult you out of the saddle. It’s demanding.

In other news, our older daughter will start with school in about one week. We are incredibly excited and a tiny bit afraid 😬.

Thinking

This is getting long already, so I’ll end this quickly soon. Last time I thought about doing scales in my professional development and how that correlates to doing interval training in sports. But that was wrong. Doing scales is not at all like intervals, but more like easy runs/long runs. You don’t do anything technically demanding but you are doing ground-work, fundamentals, basics — whatever you call that. I had a lengthy discussion about this with my mastermind group. They were the ones pointing out this difference to me.

See you next week.

Jouraling

I am writing again. Mostly for myself. As a journal. In the future I’ll try things a bit differently around here: I want to share what I am thinking about, how I work and what I am working on (as far as it makes sense in regard to my clients and NDAs).

Working

I secured a new client for autumn and the first months of 2020. I’ll be joining them as interim tech lead. I am excited. This will let me work a lot with Rails again. The last months were JS/TS only…

Something that I was proud of during the last week was a caching solution I created. Let me describe it briefly:

  • We are in a TypeScript project
  • There are external APIs we are calling to populate our app with data.
  • We display the same value in multiple places on a page or after navigating somewhere else.
  • We do not have a global state management like Redux etc. (Why is a discussion for another time 😉)
  • Every display of the value resulted in a fetch to the same API resource.

What I built was a cache-aside solution, where I cache the (pending) Promise for the first request. All subsequent requests receive this Promise as return value, without fetching again. Once the Promise is resolved, the value appears where it’s supposed to appear and every requests happens just once. This is possible and makes sense, because the values change very infrequently and using the “old” value until the site is reloaded works just fine. We don’t yet need things like etags and ModifiedSince. But perhaps this will be added in a future situation. Anyway, this was cool and also challenging to find a proper solution. Caching the Promise itself was an idea that was developed together with my co-worker, Franz.

I am redesigning my website these last months. It always takes longer, because nobody pays me for that 😂. It’s progressing nicely, thanks to the help of my designer. She’s great. I am really looking forward to sharing this with you. Also, I need to get back into the rhythm of writing articles. I have a lot of topics planned and see my traffic increase steadily.

I did not renew my subscription to the email marketing service Drip that I used during this last year. They were too expensive anyway. You will receive this mail through Drip, still. But future mails might be sent by something else. I’ll keep you posted and hope to be able to complete the migration without any hassle for you.

Personal

I am in the middle of a training program for my next 10 kilometers race. It’s quite intense, I am running 4-5 times a week. To make the time for that I started to do run-commutes. This means I run to my client in the morning, take a shower there and run home in the evening/afternoon. This is demanding but works out quite nicely. The shortest distance to my current client is about 6km, so it’s fine to run it twice.

I have a height-adjustable desk at my home office now and it is awesome. I love the flexibility. I actually stand most of the time. But after lunch, for example, I tend to sit down more. Ha, just wanted to share. If you are on the fence about getting one, you should!

Thinking / Reading

A quote that still makes me think:

Recently, one of my favorite questions to bug people with has been “What is it you do to train that is comparable to a pianist practicing scales?” If you don’t know the answer to that one, maybe you are doing something wrong or not doing enough. Or maybe you are (optimally?) not very ambitious?

It’s from this article: https://marginalrevolution.com/marginalrevolution/2019/07/how-i-practice-at-what-i-do.html

My current answer is “my side project” I am working on (nothing to share publicly here, yet). But I do know that I am not stretching doing that project. Compared to my run training, this is like a relaxed long run. Important for basic fitness and healthy, but nothing that increases my ability by much. The caching solution I wrote about certainly stretched me and I learned new things there. But this was work and not practice. And not deliberate but a happy “accident”. I should be able to plan for these training sessions.

So this is something I am thinking about.

Holger

Well this is confusing. I am a web developer and still have trouble getting this sorted. I want to:

  • Publish and create microposts on my wordpress site
  • I want these posts to appear in my micro.blog timeline
  • I want to crosspost my entries to Twitter
  • I do not need a custom domain name for my Micro.blog updates
    I read the help section. I created a category on my wordpress and could post from the IOS app to wordpress. The posts do not appear in my Micro.blog timeline.
    What do I need to do differently @manton?

I just read Paul Jarvis‘ latest email mailchi.mp/pjrvs/own… Now I am (again) motivated to turn away from platforms, switch to Linux and own everything I use. He’s very motivating in how he writes. So where to start?

On my way to Leipzig by train. Once I get there I will head back to Berlin. On my bike. I heard someone call this nonsense 🤣

Using css modules the right way, I got it to work. 🎉 In the end I had some naming clashes where I already tried to prefix my css class names with the module name—which is handled by css modules already. Because of this duplication it didn’t work. Now it does. Yay!

I am working on my first React component library for my current client. Doing lots of things for the first time. Running into lots of roadblocks and things don’t really work like I expect them to. This might be simple, but it’s not easy.

This morning I took some detours on my way to my client by bike. I rode through some parks, chose small streets and enjoyed myself on my @8barbikes adventure bike. I‘m very much in love.

From my friend Ian, I learned the value of putting a clear; in front of your test runs in the terminal. Wasn’t aware of the difference it makes for running your tests many times.