23rd week of 2021

Published on

Smoke testing, conditional props in React + TypeScript, 5 rules of ARIA, zero-runtime CSS-in-TypeScript (vanilla-extract).

Table of contents

👨‍💼 Work

No highlights this week.

👨‍🚀 Personal

Removed the Cookbook section like I had planned to do. Wrote a blog post about it: Goodbye Cookbook, hello more blog posts.

Next I'll have to think whether I want to continue writing this weekly log. 😅 It's quite much work in the end and individual topics are hard to discover from the weekly log entries (compare with a blog post focusing only on one topic). Plus is anyone even reading my ramblings? 🤣

👨‍🎓 Learnings

Smoke testing is quick and dirty testing

I recently heard the term "smoke testing" when we were talking about production deployments at work. Let's see what Wikipedia tells us about Smoke testing (software):

In computer programming and software testing, smoke testing (also confidence testing, sanity testing, build verification test (BVT) and build acceptance test) is preliminary testing to reveal simple failures severe enough to, for example, reject a prospective software release. Smoke tests are a subset of test cases that cover the most important functionality of a component or system, used to aid assessment of whether main functions of the software appear to work correctly.

So: smoke testing is cursory or "quick and dirty" testing to see that the software works correctly. Or appears to work correctly – there's no extensive testing.

For example, if you do extensive testing in your integration or staging environment (or whatever your non-production test environment is called), there might be no need to repeat the extensive tests in production. So, during production deployments it's enough to verify that everything looks good at a cursory glance. That's smoke testing.

I was curious why smoke testing was called like that. Wikipedia's page about Smoke testing (electrical) explains it clearly:

The expression probably was first used in plumbing in referring to tests for the detection of cracks, leaks or breaks in closed systems of pipes. By metaphorical extension the term is used in electronics. In Lessons Learned in Software Testing, Cem Kaner, James Bach, and Brett Pettichord provided the origin of the term: "The phrase smoke test comes from electronic hardware testing. You plug in a new board and turn on the power. If you see smoke coming from the board, turn off the power. You don't have to do any more testing."

So: plumbing → electronic hardware testing → software testing.

The first Wikipedia quote above says that smoke testing is also called sanity testing. This may or may not be true – check out What is the difference between smoke testing and sanity testing? on Stack Overflow for different opinions.

React + TypeScript: Props that depend on other props

Let's say we want to create a Shape React component with the following requirements:

  • It takes a color prop.
  • It takes a type prop with the value of 'circle', 'rectangle' or 'square'.
  • Depending on the type prop's value, it takes the following props as well:
    • radius when the type is 'circle'.
    • width when the type is 'square'.
    • width and height when the type is 'rectangle'.

A naive type for the props object would look like this:

type ShapeProps = {
  color: string
  type: 'circle' | 'square' | 'rectangle'
  radius: number
  width: number
  height: number

function Shape(props: ShapeProps) {
  return /* ... */

It's naive because then we could specify all of those props:

<Shape color="red" type="circle" radius={10} width={20} height={30} />

That makes no sense because a circle shape doesn't have a width or a height; it only has a radius. The other shapes have similar problems.

We instead want to create a union type:

type ShapeProps =
  | { color: string; type: 'circle'; radius: number }
  | { color: string; type: 'square'; width: number }
  | { color: string; type: 'rectangle'; width: number; height: number }

Now TypeScript won't let us specify invalid props. For example, when the type is 'circle', we can (and must) specify only the color and radius props, and we can't specify the width or height props.

Notice how we are repeating the color prop in all three types. We can reduce duplication by using an intersection type:

type ShapeProps = { color: string } & (
  | { type: 'circle'; radius: number }
  | { type: 'square'; width: number }
  | { type: 'rectangle'; width: number; height: number }

I learned this and some other tricks from Bruno Antunes's YouTube video React.js TypeScript Conditional Props – Props that depend on other Props. Check it out, it has more advanced examples as well.

🕵️‍♂️ Cool stuff

The 5 rules of ARIA

W3C's Using ARIA spec has a Notes on ARIA Use in HTML section with five rules of ARIA use. Bramus has summarized the rules in his blog post The 5 Rules of ARIA:

  1. If you can use a native HTML element or attribute with the semantics and behavior you require already built in […] then do so.
  2. Do not change native semantics, unless you really have to.
  3. All interactive ARIA controls must be usable with the keyboard.
  4. Do not use role="presentation" or aria-hidden="true" on a focusable element.
  5. All interactive elements must have an accessible name.

vanilla-extract: zero-runtime CSS-in-TypeScript

vanilla-extract, a "zero-runtime CSS-in-TypeScript" library, is pitched like this on its home page:

Use TypeScript as your preprocessor. Write type‑safe, locally scoped classes, variables and themes, then generate static CSS files at build time.

Cool! Like linaria, a zero-runtime CSS-in-JS library, but with type safety and possibly other advantages as well.

I would probably want to try out vanilla-extract in some project (or linaria if working with vanilla JS) if I didn't want to try out Twind, a Tailwind-in-JS library even more!

💁‍♂️ More Weekly log entries

Next week: 24th week of 2021

Previous week: 22nd week of 2021