Playback speed
×
Share post
Share post at current time
0:00
/
0:00
Transcript

Nik Sumeiko: React with Test-driven Development

Over 400 people watched us live as Nik presented a clear and simple approach to designing frontend business architecture to make it easily testable and pluggable. No fluff, no hidden magic.

Our BIGGEST live stream to date!

400 engineers, technologists, testers, managers joined us live from the following countries: 🇧🇷🇧🇪🇹🇷🇩🇪🇦🇹🇸🇮🇨🇭🇭🇷🇮🇳🇮🇷🇹🇳🇭🇺🇲🇽🇪🇸🇵🇱🇫🇷🇲🇦🇳🇬🇬🇳🇵🇹🇺🇬🇱🇺🇺🇦🇻🇳🇩🇿🇬🇧🇺🇸🇮🇹🇫🇮🇱🇰🇲🇩🇵🇰🇨🇦🇻🇪🇧🇦🇷🇸🇸🇦🇦🇪🇲🇬

Overview of the 3 hour episode

Hey this is Denis—There’s quite a bit to unpack here so I highlighted the interesting bits with a star to guide you to the more impactful topics. The episode has 3 rounds of long stretches of coding by Nik, about 45min each.


[TL;DR]


  • Rundown of the sample fintech project starts at 0h 10min

  • Project setup & tools used 💫

  • Testing theory

  • First test

  • Making it work

  • What is business logic? 💫

  • Brittleness exposed, refactoring

  • Black-box testing in React

  • Inside-out testing, adding abstractions for adapters

  • Separating business logic from React

  • Outside-in TDD

  • Separating coupling to network requests without mocks 💫

  • Solving the prob drilling and coupling issue

  • Q&A starts at 2h 10min

Project links

Github repo: https://github.com/niksumeiko/virtual-credit-card
Task: https://github.com/niksumeiko/virtual-credit-card/issues/1
Presentation: https://excalidraw.com/#json=D2GvygMVZgcHbXTKSmIu8,SIidepI-cI03ALzbmFNePQ

Here’s a non-editable copy | Credit: Nik Sumeiko

Highlights & key concepts

Measure the value each software increment brings

Nik:

“The only measure that I found: Does this increment have tests? Explicitly— if this is a feature, does this feature have a critical user journey test covered? […]

If you have a coverage for that then you can check for it in addition to existing features. If both are passing then you can measure that [at least] you won’t destroy existing business value. [The increment] might not be [immediately] useful to your customers, but business value is not always useful. Business value is also knowing that what you shipped works.

If you don’t ship with tests or your tests are breaking then you are in the risk zone. You don’t know whether your increment brings value plus you may even decrease business value because you might break some features which worked before and are critical.

Start separating concerns into functional layers very early

Nik:

What is business logic, and what is not business logic?

Business logic is not that code that you see normally in these hooks where you use useState and so forth. Business logic are if statements, some logical control structures, loops, data transformations, data extraction, data retrieval, or side effects, usage of side effects. In our case, we are using some SDK. It's just one line here.

And that line is business logic. […]

And what is not business logic is usage of React hooks, useState, and state management usage, JSX code. It's not business logic, it's an orchestration logic.

It's code that integrates things together. It's glue. Yeah, it's glue right there, but in a good overview, and this is very important. So what I see so often or saw in the past is that you have those huge React big ball of muds where you have everything in every place munched together somehow. And this is what we really should avoid, especially when using React, because it becomes not only hard to read.

Adrian:

In my opinion, that kind of architecture should already be implemented as soon as you leave the prototyping phase of your application. Because your application will grow. And no matter if you have five people or five hundred people working on an application, you will have the same problems very early on.

As soon as you want to change things, add things, you will come into this problem state.

Loose coupling and inversion. Get away from React (glue)

Nik:

So the dependency inversion, that's the last principle from SOLID, actually. I assume that there are no coupling between the outside world in our case, between Visa SDK and the React code. In that case, our use case functional layer.

Okay. But rather both relying on some intermediate interface—this one and this one—plus implementation details within the adapter, shall also rely on the interface. This is like how I nailed down the dependency inversion.

So somehow we need to, in React terminology, somehow we need to remove the import that this layer has.

Denis:

We need to move it from a compile time coupling to something that we can control at render time.

Nik:

"Yes! I have context provider in place. So this thing requires some providers. This is exactly where we'll put a a fake implementation inside.

But in production code, if we go to our routes where the page is used, we will plug in a production implementation. So I'm wrapping this in two places.”

Your questions that we covered as best as we could 🙏

—Nik. Do you give group presentations / not company ones in your website. But more of a register-to-attend?

—We are implying in the test that we know the SDK's format. Why not format the adapter's SDK Card outcome to our Card model before it comes out of the Adapter function?

—Nik, what about when you have multiple HTTP calls in the user journey, do you create a schema file to store your fake data? What do you do?

—What is the reason to create a factory?

—Does it have to be an E2E test with Cypress being built? If I understand it correctly, then you are testing on the level of the component that displays the button and the credit card. Could I also build this with React-TestingLibrary? I'm concerned about the level of the test. Do I comply with these?

—How would you implement the providers in an architecture that loads pages dynamically (e.g. Next.js), where the bundle would include all providers, regardless of whether they are used in the current page?

—What do you think about replacing assertions that check whether certain text or visual elements appear on the page in Cypress tests with a single screenshot test?

—Can you say a few more words about why you built a model-function? what is the difference to the view? My first thought would be that e.g. would the spaces between the card number, be the job of the view?

—If we supply the adapter with mock data, it is okay if we e.g. Use vitest.mock? or is it a cleaner solution to implement the “fake” manually?

—Hey Nik, for companies that ship fast, how can they adapt TDD?

—Do we need to test the date conversion separately? As the VirtualCardPageService test is only testing 1 input and output

—Is it wrong to put the creation of the model in the adapter?

—Nik: why are the arguments of your functions optional?

—How to implement or glue the view and the "business logic"/"orchestration code" together with react router? Can you explain more your strategy how to seperate the role of a designer of graphics and the role to actually develop the logic/frontend logic and how to glue it in your style? The goal is to give this two people and work in parallel.

—Can we move the coupling from the visa-client CreditCard model, to something we create, our internal model?

—What if my team has only juniors? 😕

—Even in an very early stage product?

—Aren't side effects accidental complexity rather than essential complexity (hence, business logic)?

—What is the approach to test App that need MFA auth ? ( E2E tests )

—Does it make sense to test first, what no card was shown. and in a second step (after clicking on the button) that the virtual card was shown? Or ist it too much?

—Are test ids considered as last resort in querying elements? Why not use accessibility selectors?

—I was assuming that you would start from the button "Virtual Card" in the home page. Is there a specific reason by which you started directly from the page?

—So if I understand correctly, TTD doesn't work if I'm not working on a product? Doesn't bring much in the project business or ?

—Can you please touch advanced topics please? As the internet is full of beginner topics and intros.♥️

—TDD is focus on the quality but the quality is difficult to measurement than the quantity, so it hard to manage. Could you give some tips to measure the quality?


Hey, this is Denis once more. We got nearly 200 comments and questions. I managed to sift through the main ones for you. Hope you enjoy, let me know what your favorite bit was.

If you’d like more content like this coming straight to your inbox please consider subscribing.

Sharing to more than a handful of friends will also give you a quick paid subscription comp if you want the good stuff for a little effort.

Share

🔮 Crafting Tech Teams
🏔 Our Tech Journey
Stream updates, recaps, announcements go here. Turn off notifications if you only want the actual videos.