Tj_vantoll:
Hey everybody and welcome to another episode of React Roundup. I am your host today, TJ Vantol, and with me today on our panel, I have Jack Harrington
Jack_Herrington:
Hello.
Tj_vantoll:
and Paige Niedringhaus.
Paige_Niedringhaus:
Hey everyone.
Tj_vantoll:
And our special guest today is Chris Frewen. Chris, how's it going? Welcome to React Roundup.
Chris_Frewin:
Hi, thanks for having me.
Tj_vantoll:
Yeah, so Chris, why don't you start by telling us a little bit about who you are, what you do, why you're famous, all that good sort of stuff.
Chris_Frewin:
Okay, yeah, Famous might be questionable. Yeah, so I'm currently a full stack software engineer at a startup called InClub. And it's based around Zurich, Switzerland. And we're, I guess, we're trying to be, if you could imagine, kind of an Airbnb but for experiences. I'm going hiking this weekend, who wants to come with me? Or, I mean, going on a pub crawl, who wants to come with me? And so, yeah, I've been there now just over a year. Yeah, from everything from backend, mobile app, CMS, everything in between.
Paige_Niedringhaus:
Thank
Chris_Frewin:
So
Paige_Niedringhaus:
you.
Chris_Frewin:
I've seen
Paige_Niedringhaus:
Bye.
Chris_Frewin:
a little bit of everything.
Tj_vantoll:
Awesome.
Jack_Herrington:
Nice.
Tj_vantoll:
So I know we reached out because you've written a couple of really interesting articles about your thoughts and like all sorts of things from like code structure to testing, to how BDD behavior driven
Jack_Herrington:
Hehehehe
Tj_vantoll:
development. So maybe do you wanna start by just giving like an overview of some of like, maybe we could start with like BDD and like how you came to like how you structure code and how you approach problems at the startup. Cause I... Not a whole lot of us get the chance to really like Greenfield build something like that at scale So I'm curious like some of your thoughts and opinions you have to share around that sort of thing
Chris_Frewin:
Sure, yeah, so the challenge for us was that we were a very small team. So up until a few weeks ago, I was kind of the only developer. So it was me and the two co-founders. So as you said, yeah, super Greenfield. And we actually, we were guided. One of our technical advisors told us about this kind of behavior-driven development. thing. So we're like, okay, what is this? And so he pointed us, I guess, at the very top of this whole behavior-driven development and test-driven development stuff is this language called Gurken. And so Gurken is simply, you could consider it like a programming language, but it's also kind of behavior and kind of product design language. So basically the only, the three important keywords are given, when, and then. And for us developers, that kind of corresponds one to one to the whole, the act, arrange, assert trio. So the reason he pointed us in this direction is that the two co-founders, they're kind of the minds behind the product and driving. a lot of the ideas behind the product. They can describe in plain English or with these three sentences, right? Given, you know, let's say, given I open the app, when I press the login button, then I see the login screen, right? Something like that. They can explain
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
steps in very plain English. And then we, or I, I guess it's we now, there's two of us now, that's awesome. We
Tj_vantoll:
Hehehe.
Chris_Frewin:
can write the tests against these. kind of, yeah, these, we call them Gerken specifications.
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
So.
Tj_vantoll:
Very cool. And it's spelled, just for anybody else curious, G-H-E-R-K-I-N, just for anybody
Paige_Niedringhaus:
I'm
Tj_vantoll:
just casually
Paige_Niedringhaus:
sorry.
Tj_vantoll:
Googling this as
Jack_Herrington:
Ha ha
Tj_vantoll:
we
Jack_Herrington:
ha
Tj_vantoll:
go
Jack_Herrington:
ha
Tj_vantoll:
across,
Jack_Herrington:
ha!
Tj_vantoll:
because I would not have guessed that it's spelling at all.
Chris_Frewin:
Yeah,
Paige_Niedringhaus:
Yeah.
Jack_Herrington:
So does
Chris_Frewin:
I
Jack_Herrington:
this
Chris_Frewin:
believe.
Jack_Herrington:
integrate with Jest or how do I, if I just want to start with this, where do I start with this?
Chris_Frewin:
Yeah, so there's two ways. The one way is you can use a library called Cucumber,
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
which they have actually drivers for a lot of languages, I think also plain Java, JavaScript, Kotlin, other languages. So you can use that. And you basically directly import a function called given. And then you pass the string of whatever the given line of that. description file is. But yeah, we have since integrated with Jest. There's also an integration. When you write these specification files, we're using the dot feature file extension that seems to be kind of a standard. And this Jest integration works that you import to have a load feature function. and then Jest knows, okay I'm reading from this feature file and then you have defined feature with more in I guess a standard Jest way, but still with these you get these little given when then functions that you can call from Jest in the order of the steps.
Jack_Herrington:
Oh nice cool
Tj_vantoll:
Yeah, I found the it's just ask dash cucumber on GitHub. And you're right. It like, it looks to me like any other just all these, these nouns, it's kind of, sometimes you take a step back and go like
Paige_Niedringhaus:
Hehehe
Tj_vantoll:
these sentences I'm saying are a little crazy, but it looks like any other just test that I've seen before, but you're right. It clearly has the, the given when then type of structure was just sort of embedded within it.
Paige_Niedringhaus:
And that's really interesting that you've been able to incorporate that into a testing framework because at the last company that I worked with, our product managers were responsible for writing a lot of our feature stories. And they would use that sort of syntax to write out the story. So exactly like you would say, you know, given a user clicks on a button, when they are given a user is on our application, when they click on the input button, then I should open up the input or the login screen. But we would. then translate that into our own tests where it would be like tests or it should xyz. So that's really cool that you can just take it directly from the user's story or the user input and make that part of the test because it's like if you don't meet that criteria exactly you know there's something wrong with the code not the or or how it was defined maybe but that's really cool that you could have that one-to-one comparison.
Chris_Frewin:
Yeah, I mean, I think there's huge advantages. I mean, what you just described is amazing, right? Like basically the product development team or the product management team can kind of have a one-to-one bridge right to the engineers.
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
And what we also found, now that we have this new developer on, you basically have your whole infrastructure more or less. You can say, hey, like, or if, you know, if they, they're asking about what does this feature do or how does it work? You say, Hey, don't, don't read the test, read
Jack_Herrington:
Yeah.
Chris_Frewin:
the test second, but first read these, read these feature files. It's, and then you can understand, okay, I see exactly these user stories in plain English. Um,
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
so that's,
Tj_vantoll:
Oh,
Chris_Frewin:
that's super valuable.
Tj_vantoll:
so you keep around the like plain English versions of these requirements then, so it's not just the tests that live on?
Chris_Frewin:
Yeah, yeah, these are checked right into the code base.
Tj_vantoll:
Ah, okay.
Chris_Frewin:
So with that said, like what Paige was mentioning, sometimes we can write the test directly as they're written. But sometimes, I mean, it's been a constant learning process for both of us. I mean, for example, we had features where it was like, you know, you have a form, and it's like, if the email's wrong, I see an email error. If the first name's wrong, I see a first name error. But I've learned like, okay, that should probably just be like in a unit test for like the form validation function, right? That doesn't probably need to be always like, you, you probably don't need to write every test in this, in this given one then syntax it's, it's, it's kind of like a pick and choose and it's a constant, like, yeah, it's, it's a discussion between, between us and the, the product team.
Jack_Herrington:
So would this be more of a replacement for like EDE tests then? I mean, I wouldn't imagine necessarily writing unit tests this way. I guess you could. Like more logic tests.
Chris_Frewin:
Yeah, you're right. That's where we found it's the easiest, right? Because end-to-end tests are much higher level anyway, which
Jack_Herrington:
Yeah,
Chris_Frewin:
works
Jack_Herrington:
yeah.
Chris_Frewin:
much better with like, I press this
Jack_Herrington:
When
Chris_Frewin:
button.
Jack_Herrington:
I go to the homepage, I find that my name says blah blah blah. Yeah.
Tj_vantoll:
Yeah, I've never used this structure for actually implementing tests before, but I have used this when working with like product people before. And the other kind of nice thing I think about this format is, is it forces product people to give more specific requirements
Jack_Herrington:
Ha ha ha
Tj_vantoll:
for
Paige_Niedringhaus:
Yes.
Tj_vantoll:
things as well. Um, because I'm sure a lot of you can resonate with sometimes you'll get these requirements that are like vague or they
Jack_Herrington:
No
Tj_vantoll:
have
Paige_Niedringhaus:
They
Tj_vantoll:
Or
Paige_Niedringhaus:
never consider
Tj_vantoll:
they're complicated,
Paige_Niedringhaus:
the unhappy path.
Tj_vantoll:
like,
Jack_Herrington:
What?
Tj_vantoll:
yeah, or they don't, yeah, exactly, they don't consider things beyond and like this sort of forces you to say like, okay, well, when this happens, or this scenario when this happens, what should happen, right? What happens with these account types? What happens if they try to log in and they already have an account or it's an invalid
Paige_Niedringhaus:
Mm-hmm.
Tj_vantoll:
email or the server is down or whatever, right? So it gives you like a clear. just means of specifying requirements.
Chris_Frewin:
Yeah, and then even better, when you do get that feedback, then you still have these descriptions and these scenarios for the unhappy path or when the server's down. Given the server's down, what happens?
Jack_Herrington:
Yeah, I think I used this at a previous job and I remember there being like part of it was on us to actually go and build out like the regular expressions like enable the terminology like when I do X, I see blah and like you kind of like we're writing, you know, regular expressions to match some of the English terminology of the test. Yeah, is that you find yourself doing that a lot or is that not so much?
Chris_Frewin:
Um... What do you mean exactly? Or...
Jack_Herrington:
Well, like there were expression matchers for the terminology in the test, like because the terminology is written in kind of an plain English speaking style, right? When I go to the page, I ended up actually having to write like pattern matchers for some of that stuff.
Chris_Frewin:
Yeah, it depends. I guess I'm not sure what you mean exactly. So
Jack_Herrington:
That's okay.
Chris_Frewin:
do you mean like the, because the given, you mean the body of the test itself, like what?
Jack_Herrington:
Yeah, yeah, yeah.
Chris_Frewin:
Yeah, so yeah, that's, we typically have done what we've been using a lot, especially in these end-to-end tests, is just like a test ID,
Jack_Herrington:
Oh.
Chris_Frewin:
if you're aware of those. So Yeah, the whole thing behind test IDs is a bit, it's considered sometimes anti-pattern, I guess. But what we realized is because, it's also because the whole kind of startup environment features could change like two weeks from now with
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
different even, you know, different UI elements, different texts and everything like that. So some of the other matchers like, you know, get. get by text or yeah, get by element.
Jack_Herrington:
Hmm
Chris_Frewin:
They don't make so much sense, at least from our opinion. So when you have this test ID, yeah, it's difficult. I mean, sometimes the test ID itself kind of gives way to what it is, like a button
Jack_Herrington:
Yeah.
Chris_Frewin:
or at
Jack_Herrington:
Right.
Chris_Frewin:
least like a touchable, we're working in React Native, so a touchable
Jack_Herrington:
No, no.
Chris_Frewin:
opacity.
Tj_vantoll:
So one question I have, you said you store a lot of these requirements in, actually in the code base. So how do you handle like the location of those, especially for things, because occasionally you'll have requirements that aren't specific to say like a page, right? Like they'll have to be like, I do something on one page and then I go back to another and something should happen sort of thing. So do you have like app level requirements or like how? Like how sort of pedantic do you get about that and how do you sort of handle that sort of thing?
Chris_Frewin:
Yeah, that's something we're still working on. So far, we've had a set. Usually, you have five or six of these feature files per feature. But then we've also, the engineering team, we've designed our own feature files. Still to this, which I could hear a lot of people out there would be like, what? That's a waste of time. But it's still going back to this idea that you have a catalog of everything, that you're testing in a catalog of these features. So typically, for example, like these end-to-end tests, we've written ourselves in the Gherkin syntax, which has these kind of cross, multi-page stories and things like that. Yeah, it's difficult to... It's difficult to balance that. Like some... How should I explain? Because you can't ask like the product team, they can't write a feature file probably for a specific function in your code base, right? They don't know about it. So it's really, it just comes down to reading the features and saying, okay, where is this gonna go? More than... So more often than not, it's probably going to go into an integration test or end-to-end test. But even then, you may even want to break down or talk with them, say, yeah, okay, let's take these scenarios and put them in a different test, or that actually belongs with a different feature, or grouped with other features. So yeah, it's quite challenging, actually. I'm not sure. That's probably a horrible, no good answer there, but...
Paige_Niedringhaus:
It's
Tj_vantoll:
No,
Paige_Niedringhaus:
the
Tj_vantoll:
because
Paige_Niedringhaus:
it depends
Tj_vantoll:
I think
Paige_Niedringhaus:
answer.
Tj_vantoll:
everybody struggles with this, right? I think this is just a common thread of software development. No matter what system you use, where you put tests and how you organize requirements and how you maintain them over time is a constant struggle. So if anybody had the magic bullet answer, we'd all be just doing that.
Chris_Frewin:
Yeah,
Paige_Niedringhaus:
So Chris.
Chris_Frewin:
one thing I can say to that at least is that we, so we have like for our end to end tests, which are supposed to be like the least, you know, the top of the pyramid, least used and whatnot. What we do have there is like only the, we call them like business critical stories, right? So like, can a user check out, can they do this other like, typically like, so we have At InClub, you can create your own experience, of course. You can put in the title, description. These things we have as end-to-end tests, because they're the most important. But in terms of unit tests and integration tests, well, currently we're a bit more lax with those. Of course, you should have all your tests passing before you go to production. But just in terms of the way they're designed, a lot more of them are just written by us, the software team, and there's maybe not a feature file yet for those.
Paige_Niedringhaus:
and
Chris_Frewin:
So.
Paige_Niedringhaus:
So that actually leads into my next question. And you touched on this a little bit with the testing pyramid, but how much, how many integration and unit tests would you say you have compared to your end-to-end tests? What's your percentage?
Chris_Frewin:
Yeah, so we have, we're kind of weird. The middle of our pyramid is very fat. So the integration level. And I think that comes a lot from like React itself.
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
You can argue maybe a small component is like a unit test, but probably in reality, you're gonna need something, some component from somewhere else to test
Jack_Herrington:
I'm going to make a
Chris_Frewin:
your components. And that's the biggest part of our code base. I mean,
Jack_Herrington:
cat tower.
Chris_Frewin:
We have the unit tests we do have
Jack_Herrington:
I'm going to make a cat tower.
Chris_Frewin:
are only for, we
Jack_Herrington:
I'm going to make a cat tower.
Chris_Frewin:
have only, I don't know, a dozen or so. And those are for our big, like our most critical functions. Ideally, I mean, yeah, everybody wants the ideal world where you have a hundred percent test coverage, every function, every component. Well, okay,
Jack_Herrington:
Not me.
Chris_Frewin:
maybe we don't as software developers, maybe we don't cause we'll go crazy. But yeah, so we have, I would say, how would I, maybe like 15% unit and end to end, so on the two ends, and then the rest is all integration. Yeah, that's just what we have currently.
Tj_vantoll:
No, I think that
Jack_Herrington:
And
Tj_vantoll:
makes
Jack_Herrington:
it
Tj_vantoll:
sense. I'm also like, we've had conversations before. We're not on team 100% unit
Jack_Herrington:
Hahaha!
Tj_vantoll:
testing coverage here
Paige_Niedringhaus:
No.
Tj_vantoll:
on this show.
Paige_Niedringhaus:
That's nuts.
Tj_vantoll:
We're
Jack_Herrington:
No,
Tj_vantoll:
very
Jack_Herrington:
nevermind
Tj_vantoll:
much
Jack_Herrington:
that.
Tj_vantoll:
pragmatic. I think it's even beyond
Paige_Niedringhaus:
Thanks for watching!
Tj_vantoll:
pragmatic because if you have a goal of 100% test coverage, that puts in sort of like weird incentives as well. Like you end up just writing tests just to do it versus whether
Paige_Niedringhaus:
Mm-hmm.
Tj_vantoll:
it's actually providing value to you as well.
Paige_Niedringhaus:
Yep.
Jack_Herrington:
Yeah, and then you get these meaningless tests and if they break, you're not quite sure why. And what are you testing? What was the intent here and all that?
Paige_Niedringhaus:
Hehehehe
Tj_vantoll:
Yeah,
Jack_Herrington:
So,
Tj_vantoll:
I mean, you're...
Jack_Herrington:
yeah.
Tj_vantoll:
Go ahead, Jack.
Jack_Herrington:
Well, no, no, I'm happy to refund this. I was going to ask the CID CD question, but we'll get there.
Tj_vantoll:
No,
Jack_Herrington:
So.
Tj_vantoll:
I was just going to add one final thought that, I mean, your unit tests are code too. You have to maintain it.
Jack_Herrington:
Oh
Tj_vantoll:
Your
Jack_Herrington:
yeah.
Tj_vantoll:
requirements are
Paige_Niedringhaus:
Mm-hmm.
Tj_vantoll:
going to change. They're going to break. So your test should be doing something versus just being there. So you hit the, hit the lines of code to make your, your whatever code coverage tool happy.
Jack_Herrington:
I think you should always have some rules like, if we do a certain type of change, we don't want a unit test to break. Like if we make a text change to a button, we don't
Tj_vantoll:
Yeah.
Jack_Herrington:
want
Paige_Niedringhaus:
Oh.
Jack_Herrington:
a unit test or any kind of test
Paige_Niedringhaus:
That
Jack_Herrington:
to break.
Paige_Niedringhaus:
sounds like chaos
Jack_Herrington:
I
Paige_Niedringhaus:
testing,
Jack_Herrington:
mean, the,
Paige_Niedringhaus:
Jack.
Jack_Herrington:
Well, you know, but like if you like make a spelling fix, like that's, you know, come on. Like,
Tj_vantoll:
Yep.
Jack_Herrington:
you know, the little I'm talking about the like the little blurby texts, like, you know. Whatever.
Paige_Niedringhaus:
the things that snapshot testing
Jack_Herrington:
Please enter
Paige_Niedringhaus:
pick
Jack_Herrington:
your credit
Paige_Niedringhaus:
up.
Jack_Herrington:
card
Paige_Niedringhaus:
Ha
Jack_Herrington:
here.
Paige_Niedringhaus:
ha.
Jack_Herrington:
Yes, exactly. Yeah. Basically, just trying to ward people off of Snapshot testing. Please don't
Paige_Niedringhaus:
Yeah.
Jack_Herrington:
do that. Well,
Chris_Frewin:
Give
Jack_Herrington:
OK,
Chris_Frewin:
it.
Jack_Herrington:
so Chris, CICD. So when do you just to kind of dig into the whole DevOps thing here? So when do you run these tests and how do you like it? Is it a headless thing? Do you run it in CICD? All that.
Chris_Frewin:
Very soon we will run them in CI, CD. I'll just say
Jack_Herrington:
Ahahaha,
Chris_Frewin:
that.
Jack_Herrington:
okay.
Paige_Niedringhaus:
Hahaha
Chris_Frewin:
But that has a lot more to do with me being the solo guy. The whole trouble with Apple building has to be built on a Mac.
Jack_Herrington:
Oh,
Chris_Frewin:
The only
Jack_Herrington:
right.
Chris_Frewin:
other option,
Jack_Herrington:
You're going
Chris_Frewin:
although...
Jack_Herrington:
to react native. Oh, yeah.
Chris_Frewin:
Yeah, yeah, and the tooling is tough. Although Apple is releasing a cloud, but yeah, I run the test locally before release or when we're getting quite close. But that's very soon to be added, now that I have some help from our new developer who
Jack_Herrington:
Mm-hmm.
Chris_Frewin:
doubled the engineering team size for us. But yeah, I think the typical path is simply I like to throw in the type check, that type check's empty, that's actually my first test even before unit, and then the unit test, then integration, and then end to end.
Jack_Herrington:
When you say type check, you mean like TypeScript checking?
Chris_Frewin:
Yes, the
Jack_Herrington:
Oh, OK,
Chris_Frewin:
TSE.
Jack_Herrington:
yeah. Yeah, OK. No warnings.
Chris_Frewin:
Actually, we can, it might be overkill. That might've been a bit of overkill from me, but we wrote, we converted ours into a unit. Check. Like we get the output from TSE and if it's zero lines, the unit test passes. So, although I,
Tj_vantoll:
That's actually...
Chris_Frewin:
I, I
Jack_Herrington:
Okay.
Chris_Frewin:
did that. And then I realized later, I was like, yeah, I could just run the, the bash command as part of the pipeline. Like that.
Jack_Herrington:
Yeah, I think you could turn that into a husky step too.
Chris_Frewin:
Yeah.
Jack_Herrington:
You know. Yeah.
Chris_Frewin:
Yeah.
Tj_vantoll:
So Chris, another article you have that I think is kind of interesting, you make the case for one function per file, which could be potentially controversial. I don't know how the other hosts feel, but why don't you start by making the case for this. Why one function per file?
Chris_Frewin:
Yeah, so yeah, I've worked with a lot of code bases. Typically, I think it's a React pattern or it might be almost like a legacy React pattern is that you'd have a bunch of exports in one giant file called like, I think in my blog posts I use like a math as an example, right, so you could
Tj_vantoll:
Yep.
Chris_Frewin:
imagine add, subtract, divide. Okay, great. But then if you use them, First you import them and then you get this big import from one file. But the hardest or the most confusing thing for me from that pattern is that when you're in this function file, you're looking all over the place and jumping around. I don't know, I like if I open a file, it's just I can see hopefully if the function is well organized, it should all fit right on the screen, right? And then I have it. And the idea there and how it relates to testing is that when you do a unit test, you import this file, and that's basically other than all your test tooling, that should be the only file from your code base that you're importing. And then you're sure that, at least in a unit sense, this is like what's under test, like this single thing in my code base.
Tj_vantoll:
Yeah, I'm trying to decide if I like it or not
Jack_Herrington:
I
Chris_Frewin:
Hehehehe.
Jack_Herrington:
think
Tj_vantoll:
in my head.
Jack_Herrington:
I'm I'm gonna go with
Paige_Niedringhaus:
like
Jack_Herrington:
this like
Paige_Niedringhaus:
it.
Jack_Herrington:
I mean I can imagine like at least Maybe as a compromise like one expose Function like cuz I definitely do things where I hide like internal
Paige_Niedringhaus:
sure.
Jack_Herrington:
Stuff as like if somehow add in the math context where a complex thing to do or something
Tj_vantoll:
Well, but you could argue you could make a
Jack_Herrington:
Yeah
Tj_vantoll:
function within a function. This is JavaScript. You can
Chris_Frewin:
Hehehehe
Tj_vantoll:
throw functions anywhere.
Paige_Niedringhaus:
Nothing is off limits.
Jack_Herrington:
Okay, sure, but don't do that in a React component. I've seen that before, people making
Tj_vantoll:
Yeah.
Jack_Herrington:
subcomponents inside of the declaration of a function
Paige_Niedringhaus:
Mm-hmm.
Jack_Herrington:
component. That is bad. Don't do that. It'll
Tj_vantoll:
Sure.
Jack_Herrington:
actually mess up React if you do that.
Tj_vantoll:
But in math, if your math, if your function needed
Jack_Herrington:
Yeah.
Tj_vantoll:
to do some like repetitive thing over and over again, you could do that.
Chris_Frewin:
My argument was if you had this sort of math function, you can organize them by the file name and the subfolder. So.
Tj_vantoll:
So like math slash add, math slash subtract. Okay.
Chris_Frewin:
Yep. But I may
Paige_Niedringhaus:
I
Chris_Frewin:
be,
Paige_Niedringhaus:
just feel like that's,
Chris_Frewin:
I suspect I'm in a small minority.
Paige_Niedringhaus:
yeah, it just feels like a lot of files to keep track of
Jack_Herrington:
Yeah.
Paige_Niedringhaus:
instead of just one that has all of your
Jack_Herrington:
When.
Paige_Niedringhaus:
related functions together. But
Tj_vantoll:
Yeah,
Paige_Niedringhaus:
to
Tj_vantoll:
I
Paige_Niedringhaus:
each
Tj_vantoll:
feel like
Paige_Niedringhaus:
his
Tj_vantoll:
now
Paige_Niedringhaus:
own.
Tj_vantoll:
I'm just bringing up like a, bringing up like a code base and looking around, because
Jack_Herrington:
This is this
Tj_vantoll:
I don't know,
Jack_Herrington:
shred
Tj_vantoll:
like,
Jack_Herrington:
my code bases. Oh
Tj_vantoll:
at
Jack_Herrington:
my
Tj_vantoll:
the
Paige_Niedringhaus:
Ha
Tj_vantoll:
same
Jack_Herrington:
god
Paige_Niedringhaus:
ha
Tj_vantoll:
time,
Paige_Niedringhaus:
ha!
Tj_vantoll:
like, I can see though, like, I do,
Jack_Herrington:
Oh my god.
Tj_vantoll:
even if I don't totally agree with one function per file, like, definitely like, it's definitely an anti-pattern to be building like these monstrosity files that I think
Jack_Herrington:
Yes.
Tj_vantoll:
most of us have worked on, right? Like, even if like we maybe can't get on board fully with slimming things down to one function. Like once your file, like I've had, I've worked at places where we had rules that like, once you reached a file, reached a certain number of lines, it would spit out some sort of warning, right? Like
Jack_Herrington:
Hmm.
Tj_vantoll:
you're, you're over like 300 lines in this file. Like, are you, are you sure you want to
Chris_Frewin:
I'm
Tj_vantoll:
keep,
Paige_Niedringhaus:
Do
Chris_Frewin:
sorry.
Paige_Niedringhaus:
you want it?
Tj_vantoll:
are you sure you want to keep going?
Jack_Herrington:
The RB dragons I just refactored a graph QL server file that I had. It was 2400 line.
Paige_Niedringhaus:
Yep,
Chris_Frewin:
Oh.
Tj_vantoll:
Oh
Paige_Niedringhaus:
that
Tj_vantoll:
my God.
Paige_Niedringhaus:
sounds right.
Tj_vantoll:
I
Paige_Niedringhaus:
I remember
Jack_Herrington:
And that
Paige_Niedringhaus:
working
Jack_Herrington:
was all
Paige_Niedringhaus:
on
Jack_Herrington:
on
Paige_Niedringhaus:
some...
Jack_Herrington:
me
Tj_vantoll:
don't, I
Jack_Herrington:
100%
Tj_vantoll:
was,
Jack_Herrington:
on me. I yeah
Tj_vantoll:
Jake, you might want to consider this
Chris_Frewin:
it's
Tj_vantoll:
one
Chris_Frewin:
one
Tj_vantoll:
function
Chris_Frewin:
function.
Tj_vantoll:
per file. You
Jack_Herrington:
right.
Tj_vantoll:
might.
Jack_Herrington:
But now I understand like why he says his his unit his integration tests are so large because if an integration test is defined by a test because integration tests are weird. definition anyway. But if it's defined by a test that includes more than one file, then yeah, no, man, like if you have one function per file, like 90% of your tests are going to span across multiple files somehow. Yeah.
Paige_Niedringhaus:
True.
Jack_Herrington:
Very controversial, I would say.
Paige_Niedringhaus:
I'm sorry.
Jack_Herrington:
Yeah.
Chris_Frewin:
Yeah, it may have been just my reaction to seeing I've also worked with some of these giant files and I just said nope, nope, just
Jack_Herrington:
Hehehe
Chris_Frewin:
keep it simple. One for file. That's my rule. Yeah, we'll see. Maybe we also have to refactor some of our functions.
Jack_Herrington:
I will give
Paige_Niedringhaus:
So
Jack_Herrington:
you
Paige_Niedringhaus:
Chris.
Jack_Herrington:
that if you hit command P and say you're now searching around on files in VS code. Now different IDs have different ones, but if you're doing command P then you type in add, right? You'd get if you have one one phone for file, you'd get it.
Paige_Niedringhaus:
Mm-hmm.
Jack_Herrington:
So that's kind of cool. As long as you don't. OK, don't do the thing where you have like an ad directory like slash math slash ad slash index. Where
Chris_Frewin:
Oh no no no
Jack_Herrington:
index is the implementation and then index.spec or test. Oh God, you kill me. Cause then you have a billion indexes.
Paige_Niedringhaus:
So Chris,
Tj_vantoll:
So
Paige_Niedringhaus:
when
Tj_vantoll:
Chris,
Paige_Niedringhaus:
you joined.
Tj_vantoll:
I'm curious, do you... Pidge, you go.
Paige_Niedringhaus:
All right. Chris, when you joined the company that you're working for now, was it completely greenfield where you just got to build this app from scratch and make all the design decisions, the architecture decisions, what libraries were using, what stack, or was there something that you inherited that you kind of had to take and build off of?
Chris_Frewin:
It was definitely inherited, and it actually was a lot of what Jack just mentioned, infinite
Jack_Herrington:
Ух!
Chris_Frewin:
index.js files. That's also part of why I went to this one file, one function per file pattern. But in the other struggle, at least from a JavaScript or now TypeScript perspective, is that they had... It was a weird mix of... with JS file extensions and everything in between. And actually that's something nice we've achieved very recently is there's no more TypeScript errors in the entire code base. It took a long time, but we finally got in there and now it's great because you can, for example, we just upgraded a package, then you just run TSE and you say, ah, okay, they changed. Of course you read the documentation, but you find immediately where in the code base
Jack_Herrington:
Yeah.
Chris_Frewin:
that the changes are and so these types don't work here. Before when we had 500 TypeScript errors anyway, they were just lost in a sea of confusion and you don't know where there's errors hiding. So yeah, it was a big takeover and there were also no tests written. And I still think tests in general are kind of, I might be biased from my own experience, it was one of the last things that I kind of learned and I'm still learning as a software engineer, but I think it's a lot of, because we all like to, when we test, we'd like to run, just run the app or click around and use it ourselves, right? That's like, it's kind of the natural, your natural way to go, but I really see now the value of having automated tests and it gives you security and, or not security, but a better feeling about what you're shipping to just
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
another layer of... Yeah, of,
Paige_Niedringhaus:
of confidence.
Tj_vantoll:
Like,
Chris_Frewin:
I guess,
Tj_vantoll:
peace of mind, yeah.
Chris_Frewin:
yeah, yeah, definitely. Yeah.
Jack_Herrington:
You should always get down to zero warnings and zero. Well, zero error is for sure, but zero warnings
Paige_Niedringhaus:
I'm sorry.
Jack_Herrington:
because otherwise, yeah, it's just it's white noise and people are taking over after a while. Well, you know, you know, and then yeah, and you're in hell.
Chris_Frewin:
Yeah, nobody's touched that function because if we touch
Jack_Herrington:
Uh
Chris_Frewin:
it or change
Jack_Herrington:
oh.
Chris_Frewin:
it,
Paige_Niedringhaus:
We'll break
Tj_vantoll:
Thanks for
Paige_Niedringhaus:
it.
Tj_vantoll:
watching!
Chris_Frewin:
nobody knows what happens. Yeah, it
Jack_Herrington:
That's what TypeScript's
Chris_Frewin:
has
Jack_Herrington:
supposed
Chris_Frewin:
to be
Jack_Herrington:
to
Chris_Frewin:
cleaned
Jack_Herrington:
avoid.
Chris_Frewin:
up.
Paige_Niedringhaus:
I'm sorry.
Tj_vantoll:
So Chris, do you have any other tips or from being like a solo developer starting on like a big project like this? Do you have like any other thoughts or things people might find interesting from going through that experience?
Chris_Frewin:
I think the best thing you can do is just to, I wanna say write one function per file, but no, really,
Jack_Herrington:
Ha ha ha!
Chris_Frewin:
the best thing you can do is try and be organized, or write code that's, you know, thinking about this file length limit, that's almost true, especially when you work alone, you can't really afford to have these big complex. functions and components and you even on a bigger team you probably shouldn't so I think my number one advice would be to try and write Code that's like small and manage in small manageable parts that that work together Yeah
Tj_vantoll:
I think I can definitely see that because if I'm left to myself, if I'm coding by myself, I definitely have a different mode, right? Where I'm far more willing to just go, just the wild west, right? I have my giant function, I know what it does.
Jack_Herrington:
Hahaha
Tj_vantoll:
It does what it needs to do, right? And I don't think about it too much. Whereas if I'm working on a team, I'll approach it like, well, okay, Paige is gonna see this and have to figure out what it's gonna do and how that's gonna work. So I might. think about it a little bit more. So I think I would struggle in that role just because I, I don't know, my apps would fall apart at scale because I would just be lazy about it.
Chris_Frewin:
Yeah, I mean, I had to fight the same thing too, right? But the hope I kept in mind, I was like, yeah, soon there will be someone on the team.
Tj_vantoll:
Yeah
Chris_Frewin:
You know, with the vision that we're growing, I mean, we are growing slowly too, but the vision that more people, more engineers will be writing on this code base soon.
Jack_Herrington:
Yeah, every time I'm asked to evaluate a code base and it's a single coder on it. And it's been there for a year or so over a year. I I'm like, Oh, no,
Paige_Niedringhaus:
Watch
Jack_Herrington:
that's
Paige_Niedringhaus:
out.
Jack_Herrington:
not going to be, that's going to be some weird stuff going on there for sure.
Tj_vantoll:
Yeah, single engineer or also like contractor written. That's been the other red flag for me
Jack_Herrington:
Oh!
Tj_vantoll:
too.
Jack_Herrington:
Oh
Paige_Niedringhaus:
Mm-hmm.
Jack_Herrington:
no. Oh yeah.
Tj_vantoll:
Just because when someone's not accountable to the team, somebody just has to see something working to sign off on it,
Chris_Frewin:
Thank you.
Tj_vantoll:
then things can often get hairy.
Jack_Herrington:
Yeah, I would be a strong fan of the single function profile if I was a contractor and getting paid per file.
Chris_Frewin:
There you go. Yeah. I'll do it.
Jack_Herrington:
Yeah,
Paige_Niedringhaus:
per line
Jack_Herrington:
exactly.
Paige_Niedringhaus:
of code.
Jack_Herrington:
At one constant per vial.
Tj_vantoll:
Awesome. Well, Chris, have we, we've covered a lot of ground. Is there anything we've missed? Like any articles you've covered, any topics that we haven't got into that you, you wanted to discuss at all.
Chris_Frewin:
I think one thing I was going to mention before we got into the whole CI, CD and the function profile discussion, a huge thing that we've learned, or it's quite simple really, is like, because we're talking about all these tests, you have all your tests, they pass great, but most often of course, bugs are either like super weird or user reported that nobody expect or saw. And one of the best kind of patterns that we've done is like, okay. we get a critical bug or either a very weird bug or something, then you write a test specifically against that bug. It maybe it wasn't in your feature files, wasn't in your specifications, but write a test against that bug or fix the bug, of course, and then write a test against it to kind of, you know, make sure that it doesn't come back, right? That it doesn't,
Jack_Herrington:
Yeah,
Chris_Frewin:
there's no
Jack_Herrington:
100%
Chris_Frewin:
regression.
Paige_Niedringhaus:
Mm-hmm.
Jack_Herrington:
agree on that one for sure.
Chris_Frewin:
So
Paige_Niedringhaus:
Mm-hmm.
Tj_vantoll:
Yep.
Chris_Frewin:
that's one thing I forgot to mention, but That might even be if you work somewhere and maybe your organization has no tests yet, that may be one of the first places to go, or the easiest way to start writing tests.
Paige_Niedringhaus:
Yeah,
Tj_vantoll:
It's
Paige_Niedringhaus:
that's
Tj_vantoll:
also
Paige_Niedringhaus:
a
Tj_vantoll:
very
Paige_Niedringhaus:
good one.
Tj_vantoll:
satisfying if you can get it to show up as red and then you implement a fix and then feel confident that like get to see it switch over. It's a very satisfying feeling too.
Chris_Frewin:
Exactly, yeah.
Tj_vantoll:
Cool.
Jack_Herrington:
Thanks for watching!
Tj_vantoll:
Well, it's been awesome chatting with you. I think we can move on to our picks. So this is where we just pick something, movies, TV show, music. We're still waiting for somebody to have a strong musical take. We do a lot of TV shows. But Jack, do you wanna kick us off today?
Jack_Herrington:
Yeah, sure. Why not? My daughter and I just finished up the UCS Millennium Falcon build, which is a Lego build that's just ginormously huge. You know, it's like I think 7000 parts and 1500 pages
Paige_Niedringhaus:
Nice.
Jack_Herrington:
and it's epic. Yeah.
Tj_vantoll:
longer that take.
Jack_Herrington:
We're kind of old hands at the Lego thing, so it took us three and a half, four days. But it was, you know, woo! We basically traded off on it and it was fun, you know? So if you're into that sort of thing, it's a fun build. I will say that if you are into movie speak, it has a lot of what's called greebles. Which are just basically little things that you put on something to make it visually interesting. So there's just a lot of stuff on there. Just like it doesn't. There's not actually not functional. It's just kind of stuck on. And it's just a lot of that. Like you build up a structural piece and then it's like a bunch of like just add a lot of little bits. But
Tj_vantoll:
Yeah.
Jack_Herrington:
it's fun.
Paige_Niedringhaus:
Awesome.
Tj_vantoll:
Cool. Page, what pics do you have?
Paige_Niedringhaus:
My pick for this week is going to continue on the kitchen tools train. So
Jack_Herrington:
Hmm
Paige_Niedringhaus:
this one is a plastic wrap dispenser. So normally when you get plastic wrap it comes in those cardboard boxes. The little cutter is not very good if there is a cutter at all or just rips and tears and stuff. So we bought a bamboo wooden food dispenser. It comes with a really nice little top cutter and it works like a charm. It's really heavy so you can just pull the wrap out. It doesn't slide across the table after you. The cutter works really well so I would definitely recommend that if you have $20 to spend get one of these things and you'll probably never need another one.
Jack_Herrington:
I've probably seen one of these
Tj_vantoll:
Okay.
Jack_Herrington:
behind a sushi bar or something when they're making the rolls.
Paige_Niedringhaus:
Could
Jack_Herrington:
Pull
Tj_vantoll:
Yeah.
Paige_Niedringhaus:
be.
Jack_Herrington:
it out, kind of thing, yeah.
Tj_vantoll:
Awesome. My pick this week is gonna be a weird one, kind of a very specific one, but I'm gonna pick Amazon Go, which I don't know if any of you have went to one of these stores before, but you'd have to be in either Seattle, Chicago, or New York, so that's why it's a very specific pick, but there are these stores by Amazon where their core tech is, there's no checkout. You just grab, at the door, you go in, there's these turnstiles, and you scan your phone. in the Amazon app so it knows who you are. You grab whatever you're gonna buy and then you just leave. And the system there is smart enough, there's cameras, the entire ceiling is covered with these cameras. And you just get a notification on your phone a few minutes after you walk out with just a receipt of what you bought. And I'm picking it just because if you're in the area, it's just fascinating to do because it's just such a weird experience, right? Like you feel very... very strange. Like
Jack_Herrington:
Hahahaha
Tj_vantoll:
you feel like you're actually committing a crime when you walk out of the place. And for me too, we went with the whole family. So you go in as a group and I was just amazed at the technology because we said we had two 11 year old kids, right? So of course they're just grabbing things off the shelves, putting
Paige_Niedringhaus:
Hehehe
Tj_vantoll:
it on and off, you know, walking around, whatever. And sure enough, we bought like five or six things between the four of us and it perfectly knew exactly what we bought, charged us perfectly. And I was just kind of amazed by it. So if you're ever in the area for, if you're a listener in one of those, those three areas, it's worth doing once just to experience it.
Jack_Herrington:
Is there any security there? Can you just like just walk out?
Tj_vantoll:
you literally walk out. There was not a human employee in the store. There
Paige_Niedringhaus:
Wow.
Tj_vantoll:
might be somebody like in the back or something for all I know, but we did not see in a single employee. It's kind of crazy.
Jack_Herrington:
That's trusting.
Paige_Niedringhaus:
I'm sorry.
Tj_vantoll:
Awesome. So Chris, what pics do you have?
Chris_Frewin:
I guess I'll do two books. The first I guess is quite relevant. We've all read it on the team. It's The Lean Startup by Eric Rice.
Paige_Niedringhaus:
Mm-hmm.
Chris_Frewin:
It's quite interesting and there's a lot of good stuff packed in there. That's my first. The second is a series of books. The Foundation I guess it's made a kind of a resurgence recently because I think Apple did a series on it or something.
Jack_Herrington:
Yeah,
Chris_Frewin:
But
Jack_Herrington:
yeah, Apple did it.
Chris_Frewin:
the books are awesome. I recommend to read the books first.
Jack_Herrington:
I'm surprised Apple did it because
Tj_vantoll:
Sit.
Jack_Herrington:
it seems like an unfilmable show and it kind of was actually.
Tj_vantoll:
Is it science fiction?
Jack_Herrington:
Oh yeah.
Tj_vantoll:
Okay, I will
Jack_Herrington:
Very
Tj_vantoll:
have
Jack_Herrington:
much.
Tj_vantoll:
to check this out. Cool! Well, Chris, last question for you. If people want to follow you, what's the best place to do that sort of thing?
Chris_Frewin:
I guess the easiest is just my blog. It's chrisfrew.in. And I think from there you can find me anywhere. I am trying to get back to making YouTube videos, but I've been extremely busy with the startup, but
Jack_Herrington:
It's
Chris_Frewin:
I
Jack_Herrington:
tough,
Chris_Frewin:
hope this
Jack_Herrington:
man.
Chris_Frewin:
fall.
Tj_vantoll:
Yeah.
Jack_Herrington:
Feel the pain.
Tj_vantoll:
Cool. Well, thanks so much for joining us. This is a lot of fun to chat.
Chris_Frewin:
Yeah,
Jack_Herrington:
Yeah.
Chris_Frewin:
thanks a lot. It's really fun.
Tj_vantoll:
Cool. And until next week, everybody.
Paige_Niedringhaus:
See
Jack_Herrington:
All
Paige_Niedringhaus:
you
Jack_Herrington:
right,
Paige_Niedringhaus:
then.
Jack_Herrington:
see you then.
Chris_Frewin:
Bye.