POPULARITY
Jake and Michael recap their Christmas and New Year break, talk through lingering packages, Laravel 11 upgrades, and breaking changes in PHPUnit.
SANS Internet Stormcenter Daily Network/Cyber Security and Information Security Stormcast
PHPUnit and Androxgh0st https://isc.sans.edu/diary/Command%20Injection%20Exploit%20For%20PHPUnit%20before%204.8.28%20and%205.x%20before%205.6.3%20%5BGuest%20Diary%5D/31528 Mirai Attacks Session Smart Routers https://supportportal.juniper.net/s/article/2024-12-Reference-Advisory-Session-Smart-Router-Mirai-malware-found-on-systems-when-the-default-password-remains-unchanged?language=en_US FortiWLM Unauthenticated limited file read vulnerability https://fortiguard.fortinet.com/psirt/FG-IR-23-144 https://securityonline.info/kaspersky-uncovers-active-exploitation-of-fortinet-vulnerability-cve-2023-48788/ Beyond Trust Security Advisory https://www.beyondtrust.com/trust-center/security-advisories/bt24-10 BadBox Update https://www.bitsight.com/blog/badbox-botnet-back
Today we are talking about some things are on our mind including, The DOJ Accessibility ruling,Drupal CMS Event Recipes and Tooling for core development with our Hosts. We'll also cover @font-your-face as our module of the week. For show notes visit: https://www.talkingDrupal.com/476 Topics DOJ Accessibility Ruling Drupal CMS Tooling for core development Open University Resources Accessibility ruling PHPUnit testing https://www.drupal.org/docs/develop/automated-testing/phpunit-in-drupal/running-phpunit-javascript-tests https://github.com/ddev/ddev-selenium-standalone-chrome Drupal Events Recipes Guests Martin Anderson-Clutz - mandclu.com mandclu Hosts Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Martin Anderson-Clutz - mandclu.com mandclu Joshua "Josh" Mitchell - joshuami.com joshuami MOTW Correspondent Martin Anderson-Clutz - mandclu.com mandclu Brief description: Have you ever wanted to add and manage web fonts for your Drupal site, directly within the admin interface? There's a module for that. Module name/project name: @font-your-face Brief history How old: created in May 2010 by Scott Reynen, but the most recent release was by Henrique Mendes (hmendes) of CI&T Versions available: 7.x-2.8 and 4.0.0 versions available, the latter of which support Drupal 9.4 and 10. Maintainership Actively maintained Security coverage Test coverage Documentation, but looks like it might be ready for a refresh Number of open issues: 48 open issues, 8 of which are bugs against the current branch Usage stats: 32,213 sites Module features and usage The module provides an interface to browse fonts from Google, Adobe, Typekit, and more License restrictions for fonts are clearly indicated When you find a font you want to use, you just click “enable”. You don't need to write any CSS or define a library, and it's easy to mix-and-match fonts from different providers. It can even make it easier to include your own local fonts The module includes submodules for the different font providers, so you enable the submodules based on where you want to use fonts from Then you can import the fonts for those providers, though you do need an API key to import fonts from Google The module does also have an API, so you can write your own modules to integrate with other font providers, or access the information about available fonts
Testing ist nicht gleich Testing - Ein Deep Dive mit Sebastian BergmannViele Software-Entwickler⋅innen kennen Unit-Tests. Einige schreiben Unit Tests bei der Entwicklung. Wenige machen wirklich Test-Driven-Development. Doch beim Unit-Testing fängt das ganze Thema Testing doch erst an. Wie sieht es denn mit Static Testing, Non-Functional-Testing, White-Box-Testing, End-to-End-Testing, Dynamic Testing oder Integration Testing aus? Und hast du schon mal von Mutanten Testing gehört?Ganz schön viele Buzzwords. Und dabei haben wir noch gar nicht die Fragen beantwortet, was eigentlich gute Tests sind, wie viele Tests genug Tests sind, wie AI uns helfen kann bessere Tests zu schreiben oder ob Testing eigentlich moderner Kram ist oder schon seit Anbeginn des Programmier Zeitalters eine Rolle gespielt hat.In dieser Episode gibt es einen Rundumschlag zum Thema Testing mit Sebastian Bergmann.Bonus: Die Amiga-Szene lebt.Das schnelle Feedback zur Episode:
Welcome back to “Skills Upgrade” a Talking Drupal mini-series following the journey of a D7 developer learning D10. This is episode 7. Topics Review Chad's goals for the previous week Test Example Set up phpunit.xml Start with FrontPageLinkTest.php Review Chad's questions In the testing_example module, the file "src/Controller/TestingExampleController.php" has a function for simpletestDescription(). Is this an outdated artifact that should have been removed at some point? The module itself doesn't appear to use Simpletest elsewhere and appears to only rely on PHPUnit. What do you recommend for the minimal code structure to include for any given test type? Is the Testing Example module an ideal model or are there other resources I should review? The testing reference from Selwyn was helpful. In the "FrontPageLinkDependenciesTest.php" setUp() function, the createContentType() function is called without specifying the type. Is that set somewhere else? I may have overlooked it. Nevermind—it's set using randomMachineName() in the createContentType() function. Is there anything extra or standard to write in tests for drupal.org? Tasks for the upcoming week Smart Date - Martin (maintainer) to review promptly, I've already chatted with him about it. Create a new functional test: "submit a range with an end time before the start and validate that an error is returned" Create an issue in the Smart Date queue and assign to yourself. Create an issue fork. Check out the issue fork locally. Write (and test) the test locally. Commit and push to the issue fork. Mark issue as "Needs review". Ask someone to review - if all looks good, the reviewer will mark as RBTC. Resources Chad's Drupal 10 Learning Curriclum & Journal Chad's Drupal 10 Learning Notes The Linux Foundation is offering a discount of 30% off e-learning courses, certifications and bundles with the code, all uppercase DRUPAL24 and that is good until June 5th https://training.linuxfoundation.org/certification-catalog/ Hosts AmyJune Hineline - @volkswagenchick Guests Chad Hester - chadkhester.com @chadkhest Mike Anello - DrupalEasy.com @ultimike
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.Show linksCompare Algolia vs ElasticSearch vs Meilisearch vs TypesenseAspen - The ultimate free API testing tool for macOS with AI integration(02:02) - Laravel 10.41 - Conditional Job Chains, a Number::spell() Threshold, Configurable model:prune Path, and More (06:46) - Laravel 10.42 - Global Defaults for the HTTP Client, a Max Validation Rule for Passwords, and more (09:43) - Laravel Scout Adds Typesense, A Lightening-fast Open-source Search (12:59) - Laravel 11 Introduces the Dumpable Trait (14:46) - Eager Load Limit is Coming to Laravel 11 (18:12) - Dive into the Streamlined Directory Structure in Laravel 11 (23:14) - Meet Aspen: Speedier & Smarter API Testing, Outshining Postman and Insomnia (26:53) - Laravel Live UK (28:25) - Write Tabular Assertions with Pest and PHPUnit (30:39) - Create Beautiful Charts in Filament With the Apex Charts Plugin (31:50) - Generate Tailwind Utility Stylesheets on Demand with Curlwind (34:16) - Download Over 1,500 Google Fonts in Your Laravel Project (35:17) - Create Dynamic Discounts with Custom Conditions on Laravel With the Discountify Package (37:46) - Handling Bulk Imports in Filament
In this episode of the Laravel Podcast we are packing it in! We're diving into the freshest drops, like FrankenPHP, Cashier Quickstarts, and the buzz about the upcoming Laravel Worldwide Meetup. We'll also weigh Cashier against Spark, discuss boot service providers for all your apps, pit Pest versus PHPUnit for testing, and get into the details of how we manage our teams.Taylor Otwell's Twitter - https://twitter.com/taylorotwellMatt Stauffer's Twitter - https://twitter.com/stauffermattLaravel Twitter - https://twitter.com/laravelphpLaravel Website - https://laravel.com/Tighten.co - https://tighten.com/Taylor and Ramus Tweet - https://x.com/taylorotwell/status/1732607829239116057?s=20Chris Fidao Frankenphp video - https://youtu.be/q6FQaaFZVy4?si=MU1AAi7-UNgLH-NiLaravel Worldwide Meetup - meetup.laravel.comColin DeCarlo Twitter - https://twitter.com/colindecarloVehikl Twitter - https://twitter.com/vehiklCashier Quick Start - https://laravel.com/docs/10.x/billing#quickstartDries Vints Twitter - https://twitter.com/driesvintsIan Landsman Twitter - https://twitter.com/ianlandsmanIan Boot Service Tweet: https://x.com/ianlandsman/status/1744903740329443588?s=20Eric Barnes Twitter - https://twitter.com/ericlbarnesTaylor Test Runner Poll Tweet - https://x.com/taylorotwell/status/1744729110163988949?s=20Lambo - https://github.com/tighten/lamboMatt's video Pest as a Test Runner - https://www.youtube.com/watch?v=W3tfEtbMTEIRemote - https://basecamp.com/books/remoteLastlings - https://www.lastlings.com/Harry Styles - https://www.hstyles.co.uk/Don't Worry Darling - https://www.imdb.com/title/tt10731256/Spider Man soundtracks - https://music.apple.com/us/album/spider-man-into-the-spider-verse-soundtrack-from/1453876765 & https://music.apple.com/us/album/metro-boomin-presents-spider-man-across-the-spider/1690685331Jamila Woods - https://www.jamila-woods.com/-----Editing and transcription sponsored by Tighten.
Join us in this episode as we discuss the new Livewire + Volt Functional API stack for Breeze and its capabilities. We also demystify essential testing best practices to keep your code scandal-free and away from front-page mishaps. Uncover the art of crafting meaningful tests, evaluate the pros and cons of Pest vs. PHPUnit, venture into the realm of traits and inheritance, and determine the optimal number of tests for your project. Tune in for a jam-packed episode brimming with insights and strategies to elevate your testing game.• Taylor Otwell's Twitter - https://twitter.com/taylorotwell• Matt Stauffer's Twitter - https://twitter.com/stauffermatt• Laravel Twitter - https://twitter.com/laravelphp• Laravel Website - https://laravel.com/• Livewire Volt - https://livewire.laravel.com/docs/volt• Laravel Folio - https://laravel.com/docs/10.x/folio• PEST - https://pestphp.com/• Podcast: Pest, With Nuno Maduro: https://laravelpodcast.com/episodes/pest-with-nuno-maduro• PHPUnit - https://phpunit.de/• Inertia - https://inertiajs.com/• Tighten.co - https://tighten.com/• Docker - https://www.docker.com/company/• Vala's Pumpkin Patch - https://www.valaspumpkinpatch.com/----- Editing and transcription sponsored by Tighten.
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.This episode is sponsored by Honeybadger - combining error monitoring, uptime monitoring and check-in monitoring into a single, easy to use platform and making you a DevOps hero. (02:35) - Laravel 10.2 (04:28) - Laravel 10.3 (11:34) - Linti and fix your Laravel code with Duster (14:43) - The future of Pest v2 (17:58) - Sponsor: Honeybadger (19:05) - Filter and search Eloquent models with the model filter package (22:34) - Laravel notification log (25:04) - Flaky for Laravel (29:55) - A PHP SDK for the Dolby API (31:37) - A Laravel package to protect routes with a PIN code (33:04) - Convert HTML strings to translation functions (35:37) - Sharing PHPCS rules across projects and teams (36:39) - Uploading files in Laravel using FilePond (38:47) - Livesstream: Playing with Laravel pipelines (40:04) - Building a kanban board with Laravel and Vue.Draggable Using PSR-3 placeholders properly Pest Converter - Convert your tests from PHPUnit to Pest
In this episode, I had a long and winding discussion about software testing with the legendary Grumpy Programmer Chris Hartjes. We talked about the importance of learning the essentials of software testing rather than focusing on a particular framework, as that makes your skills so much more transferable. We discussed how to approach testing; it's not a framework-first approach. And we also discussed the latest PHP testing framework, Pest PHP, covering what it brings to the table and whether people should just stick to older veterans, such as PHPUnit, or not.Some key takeaways are: You should learn the essentials of testing first, and not a specific tool such as PHPUnit or Pest PHP It's better if people worry less about the tool and more about testing concepts The people who write the best tests are also really talented programmers, because you can't be a shitty programmer and write good tests Testing is an intermediate skill. You have to know how code before you can write tests When approaching testing something, ask: "How would I manually do this?". Don't think about testing concepts or a framework straight away If people would spend as much time learning the fundamentals (of testing), they'd see that their skills are transferable. Composer saved PHP. It kept PHP from just being the thing that runs WordPress Bill Joy on Linux and macOS: "Re-implementing what I designed in 1979 is not interesting to me personally. For kids who are 20 years younger than me, Linux is a great way to cut your teeth. It's a cultural phenomenon and a business phenomenon. Mac OS X is a rock-solid system that's beautifully designed. I much prefer it to Linux.' Links The Arrange, Act, Assert pattern Pest PHP PHPUnit Test-Driven Development by Kent Beck Rector PHP's Abstract Syntax Tree (AST) NixOS Mozilla The RemoteOK.io thread Laravel Guests: Chris Hartjes.Hosted By: Matthew Setter.Thanks for tuning in to Free the Geek. If you'd like to be a guest on the podcast or know someone who'd make a great guest, email me: matthew[at]matthewsetter.com. This podcast is produced by Matthew Setter for the Web Dev With Matt podcast network.SupportIf you want to support the show, you can always buy me a coffee. I'd greatly appreciate your financial support. ★ Support this podcast ★
Natural disaster movies, anyone? It's what Steph's been into, and Chris has THOUGHTS on the drilling in Armageddon. Additionally, a chat around RuboCop RSpec rules happens, and they answer a listener's question, "how do you get acquainted with a new code base?" This episode is brought to you by BuildPulse (https://buildpulse.io/bikeshed). Start your 14-day free trial of BuildPulse today. Greenland (https://www.imdb.com/title/tt7737786/) Geostorm (https://www.imdb.com/title/tt1981128/) San Andreas (https://www.imdb.com/title/tt2126355/) Armageddon (https://www.imdb.com/title/tt0120591/) This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: AD: Flaky tests take the joy out of programming. You push up some code, wait for the tests to run, and the build fails because of a test that has nothing to do with your change. So you click rebuild, and you wait. Again. And you hope you're lucky enough to get a passing build this time. Flaky tests slow everyone down, break your flow, and make things downright miserable. In a perfect world, tests would only break if there's a legitimate problem that would impact production. They'd fail immediately and consistently, not intermittently. But the world's not perfect, and flaky tests will happen, and you don't have time to fix all of them today. So how do you know where to start? BuildPulse automatically detects and tracks your team's flaky tests. Better still, it pinpoints the ones that are disrupting your team the most. With this list of top offenders, you'll know exactly where to focus your effort for maximum impact on making your builds more stable. In fact, the team at Codecademy was able to identify their flakiest tests with BuildPulse in just a few days. By focusing on those tests first, they reduced their flaky builds by more than 68% in less than a month! And you can do the same because BuildPulse integrates with the tools you're already using. It supports all of the major CI systems, including CircleCI, GitHub Actions, Jenkins, and others. And it analyzes test results for all popular test frameworks and programming languages, like RSpec, Jest, Go, pytest, PHPUnit, and more. So stop letting flaky tests slow you down. Start your 14-day free trial of BuildPulse today. To learn more, visit buildpulse.io/bikeshed. That's buildpulse.io/bikeshed. CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris. So I've been watching more movies lately. So evenings aren't always great; I don't always feel good being around 33 weeks pregnant now. Evenings I can be just kind of exhausted from the day, and I just need to chill and prop my feet up and all that good stuff. And I've been really drawn to natural disaster like end-of-the-world-type movies, and I'm not sure what that says about me. But it's my truth; it's where I'm at. [chuckles] I watched Greenland recently, which I really enjoyed. I feel like they ended it well. I won't share any spoilers, but I feel like they ended it well. And they didn't take an easy shortcut out that I kind of thought that they might do, so that one was enjoyable. Geostorm, I watched that one just last night. San Andreas, I feel like that's one that I also watched recently. So yeah, that's what's new in my world, you know, your typical natural disaster end-of-the-world flicks. That's my new evening hobby. CHRIS: I feel like I haven't heard of any of the three that you just listed, which is wild to me because this is a category that I find enthralling. STEPH: Well, definitely start with Greenland. I feel like that one was the better of the three that I just mentioned. I don't know Geostorm or San Andreas which one you would prefer there. I feel like they're probably on par with each other in terms of like you're there for entertainment. We're not there to judge and be hypercritical of a storyline. You're there purely for the visual effects and for the ride. CHRIS: Gotcha. Interesting. So quick question then, since this seems like the category you're interested in, Armageddon or Deep Impact? STEPH: Ooh, I'm going to have to walk through the differences because I always get those mixed up. Armageddon is where they take Bruce Willis up to an asteroid, and they have to drill and drop a nuke, right? CHRIS: They sure do. STEPH: [laughs] And then what's Deep Impact about? I guess the fact that I know Armageddon better means I'm favoring that one. I can't place what...how does Deep Impact go? CHRIS: Deep Impact is just there's an asteroid coming, and it's the story and what the people do. So it's got less...it doesn't have the same pop. I believe Armageddon was a Michael Bay movie. And so it's got that Michael Bay special bit of something on it. But the interesting thing is they came out the same year; I want to say. It's one of those like Burger King and McDonald's being right next door to each other. It's like, what are you doing there? Why are you...like, asteroid devastation movies two of you at the same time, really? But yeah, Armageddon is the correct answer. Deep Impact is like a fine movie, but Armageddon is like, all right, we're going to have a movie about asteroids. Let's really go for it. Blow it out. Why not? STEPH: Yeah, I'm with you. Armageddon definitely sticks out in my memory, so I'd vote that one. Also, for your other question that you didn't ask, but you kind of implicitly asked, I'm going to go McDonald's because Burger King fries are trash, and also, McDonald's has better ice cream cones. CHRIS: Okay, so McDonald's fries. Oh no, I was thinking Wendy's, get a frosty from there, and then you make that combination because the frostys are great. STEPH: Oh yeah, that's a good combo. CHRIS: And you need the french fries to go with it, but then it's a third option that I'm introducing. Also, this wasn't a question, but I want to loop back briefly to Armageddon because it's an important piece of cinema. There's a really great...like it's DVD commentary, and it's Ben Affleck talking with Michael Bay about, "Hey, so in the movie, the premise is that the only way to possibly get this done is to train a bunch of oil drillers to be astronauts. Did we consider it all just having some astronauts learn to do oil drilling?" And Michael Bay's response is not safe for radio is how I would describe it. But it's very humorous hearing Ben Affleck describe Michael Bay responding to that. STEPH: I think they addressed that in the movie, though. They mentioned like, we're going to train them, but they're like, no, drilling is such an art and a science. There's no way. We don't have time to teach these astronauts how to drill. So instead, it's easier to teach them to be astronauts. CHRIS: Right. That is what they say in the movie. STEPH: [laughs] Okay. CHRIS: But just spending a minute teasing that one apart is like, being an astronaut is easy. You just sit in the spaceship, and it goes, boom. [laughs] It's like; actually, there's a little bit more to being an astronaut. Yes, drilling is very subtle science and art fusion. But the idea that being an astronaut [laughs] is just like, just push the go-to space button, then you go to space. STEPH: The training montage is definitely better if we get to watch people learn how to be astronauts than if we watch people learn how to drill. [laughs] So that might have also played a role. CHRIS: No question, it is the correct cinematic choice. But whether or not it's the true answer...say we were actually faced with this problem, I don't know that this is exactly how it would play out. STEPH: I think we should A/B test it. We'll have one group train to be drill experts and one group train to be astronauts, and we'll send them both up. CHRIS: This is smart. That's the way you got to do it. The one other thing that I'm going to go...you know what really grinds my gears? In the movie Armageddon, they have this robotic vehicle thing, the armadillo; I believe it's called. I know more than I thought I would remember about this movie. [chuckles] Anyway, continuing on, the armadillo, the vehicle that they use to do the drilling, has the drill arm on it that extends out and drills down into the asteroid. And it has gears on the end of it. It has three gears specifically. And the first gear is intermeshed with the second gear, which is intermeshed with the third gear, which is intermeshed with the first gear, so imagine which direction the first gear is turning, then imagine the second gear turning, then imagine the third gear turning. They can't. It's a physically impossible object. One tries to turn clockwise, and the other one is trying to go counterclockwise, and they're intermeshed. So the whole thing would just cease up. It just doesn't work. I've looked at it a bunch of times, and I want to just be wrong about this. I want to be like; I don't know what's going on. But I think the gears on the drilling machine just fundamentally at a very simple mechanical level cannot work. And again, if you're going to do it, really go for it, Michael Bay. I kind of like that, and I really hate it at the same time. STEPH: I have never noticed this. I'm intrigued. You know what? Maybe Armageddon will be the movie of choice tonight. [chuckles] Maybe that's what I'm going to watch. And I'm going to wait for the armadillo to come out so I can evaluate the gears. And I'm highly amused that this is the thing that grinds your gears are the gears on the armadillo. CHRIS: Yeah. I was a young child at the time, and I remember I actually went to Disney World, and I saw they had the prop vehicle there. And I just kind of looked up at it, and I was like, no, that's not how gears work. I may have been naive and wrong as a child, and now I've just anchored this memory deep within me. In a similar way, so I had a moment while traveling; actually, that reminded me of something that I said on a recent podcast episode where I was talking about names and pronunciation. And I was like, yeah, sometimes people ask me how to pronounce my name. And I can't imagine any variation. That was the thing I was just wrong about because 'Toomay' is a perfectly reasonable pronunciation of my name that I didn't even think... I was just so anchored to the one truth that I know in the world that my name is Toomey. And that's the only possible way anyone could pronounce it. Nope, totally wrong. So maybe the gears in Armageddon actually work really, really well, and maybe I'm just wrong. I'm willing to be wrong on the internet, which I believe is the name of the first episode that we recorded with you formally as a co-host. [chuckles] So yeah. STEPH: Yeah, that sounds true. So you're going to change the intro? It's now going to be like, and I'm Chris 'Toomay'. CHRIS: I might change it each time I come up with a new subtle pronunciation. We'll see. So far, I've got two that I know of. I can't imagine a third, but I was wrong about one. So maybe I'm wrong about two. STEPH: It would be fun to see who pays attention. As someone who deeply values pronouncing someone's name correctly, oh my goodness, that would stress me out to hear someone keep pronouncing their name differently. Or I would be like, okay, they're having fun, and they don't mind how it gets pronounced. I can't remember if we've talked about this on air but early on, I pronounced my last name differently for like one of the first episodes that we recorded. So it's 'Vicceri,' but it could also be 'Viccari'. And I've defaulted at times to saying 'Viccari' because people can spell that. It seems more natural. They understand it's V-I-C-C-A-R-I. But if I say 'Vicceri', then people want to add two Rs, or they want a Y. I don't know why it just seems to have a difference. And so then I was like, nope, I said it wrong. I need to say it right. It's 'Vicceri' even if it's more challenging for people. And I think Chad Pytel had just walked in at that moment when I was saying that to you that I had said my name differently. And he's like, "You can't do that." And I'm like, "Well, I did it. It's already out there in the world." [laughs] But also, I'm one of those people that's like, Viccari, 'Vicceri' I will accept either. In a slightly different topic and something that's going on in my world, there was a small win today with a client team that I really appreciated where someone brought up the conversation around the RuboCop RSpec rules and how RuboCop was fussing at them because they had too many lines in their test example. And so they're like, well, they're like, I feel like I'm competing, or I'm working against RuboCop. RuboCop wants me to shorten my test example lines, but yet, I'm not sure what else to do about it. And someone's like, "Well, you could extract more into before blocks and to lets and to helpers or things like that to then shorten the test. They're like, "But that does also work against readability of the test if you do that." So then there was a nice, short conversation around well, then we really need more flexibility. We shouldn't let the RuboCop metrics drive us in this particular decision when we really want to optimize for readability. And so then it was a discussion of okay, well, how much flexibility do we add to it? And I was like, "Well, what if we just got rid of it? Because I don't think there's an ideal length for how long your test should be. And I'd rather empower test authors to use all the space that they need to show their test setup and even lean into duplication before they extract things because this codebase has far more dry tests than they do duplication concerns. So I'd rather lean into the duplication at this point." And the others that happened to be in that conversation were like, "Yep, that sounds good." So then that person issued a PR that then removed the check for that particular; how long are the examples? And it was lovely. It was just like a nice, quick win and a wonderful discussion that someone had brought up. CHRIS: Ooh, I like that. That sounds like a great conversation that hit on why do we have this? What are the trade-offs? Let's actually remove it. And it's also nice that you got to that place. I've seen a lot of folks have a lot of opinions in the past in this space. And opinions can be tricky to work around, and just deeply, deeply entrenched opinions is the thing that I find interesting. And I think I'm increasingly in the space of those sort of, thou shalt not type linter rules are not ideal in my mind. I want true correctness checks that really tell some truth about the codebase. Like, we still don't have RuboCop on our project at Sagewell. I think that's true. Yeah, that's true. We have ESLint, but it's very minimal, what we have configured. And they more are in the what we deem to be true correctness checks, although that is a little bit of a blurry line there. But I really liked that idea. We turn on formatters. They just do the thing. We're not allowed to discuss the formatting, with the exception of that time that everybody snuck in and switched my 80-line length to a 120-line length, but I don't care. I'm obviously not still bitter about it. [chuckles] And then we've got a very minimal linting layer on top of that. But like TypeScript, I care deeply, and I think I've talked in previous episodes where I'm like, dial up the strictness to 14 because TypeScript tends to tell me more truths I find, even though I have to jump through some hoops to be like TypeScript, I know that this is fine, but I can't prove it. And TypeScript makes me prove it, which I appreciate about it. I also really liked the way you referred to RSpec's feedback to you was that RSpec was fussing at you. That was great. I like that. I'm going to internalize that. Whenever a linter or type system or anything like that when they tell me no, I'm going to be like, stop fussing, nope, nope. [chuckles] STEPH: I don't remember saying that, but I'm going to trust you that that's what I said. That's just my true southern self coming through on the mic, fussing, and then go get a biscuit, and it'll just be a delightful day. CHRIS: So if I give RuboCop a biscuit, it will stop fussing at me, potentially? STEPH: No, the biscuit is just for you. You get fussed at; you go get a biscuit. It makes you feel better, and then you deal with the fussing. CHRIS: Sold. STEPH: Fussing and cussing, [laughs] that's most of my work life lately, fussing and cussing. [laughs] CHRIS: And occasional biscuits, I hope. STEPH: And occasional biscuits. You got it. But that's what's new in my world. What's going on in your world? CHRIS: Let's see. In my world, it's a short week so far. So recording on Wednesday, Monday was a holiday. And I was out all last week, which very much enjoyed my vacation. It was lovely. Went over to Europe, hung out there for a bit, some time in Paris, some time in Amsterdam, precious little time on a computer, which is very rare for me. So it was very enjoyable. But yeah, back now trying to just get back into the swing of things. Thankfully, this turned out to be a really great time to step away from the work for a little while because we're still in this calm before the storm but in a good way is how I would describe it. We have a major facet of the Sagewell platform that we are in the planning modes for right now. But we need to get a couple of different considerations, pick a partner vendor, et cetera, that sort of thing. So right now, we're not really in a position to break ground on what we know will be a very large body of work. We're also not taking on anything else too big. We're using this time to shore up a lot of different things. As an example, one of the fun things that we've done in this period of time is we have a lot of webhooks in the app, like a lot of webhooks coming into the app, just due to the fact that we're an integration of a lot of services under the hood. And we have a pattern for how we interact with and process, so we actually persist the webhook data when they come in. And then we have a background job that processes and watch our pattern to make sure we're not losing anything and the ability to verify against our local version, and the remote version, a bunch of different things. Because turns out webhooks are critical to how our app works. And so that's something that we really want to take very seriously and build out how we work with that. I think we have eight different webhook integrations right now; maybe it's more. It's a lot. And with those, we've implemented the same pattern now eight times; I want to say. And in squinting at it from a distance, we're like; it is indeed identically the same pattern in all eight cases or with the tiniest little variation in one of them. And so we've now accepted like, okay, that's true. So the next one of them that we introduced, we opted to do it in a generic way. So we introduced the abstraction with the next iteration of this thing. And now we're in a position...we're very happy with what we ended up with there. It's like the best of all of the other versions of it. And now, the plan will be to slowly migrate each of the existing ones to be no longer a unique special version of webhook processing but use the generic webhook processing pattern that we have in the app. So that's nice. I feel good about how long we waited as well because it's like, we have webhooks. Let's introduce the webhook framework to rule them all within our app. It's like, no, wait until you see. Check and make sure they are, in fact, the same and not just incidental duplication. STEPH: I appreciate that so much. That's awesome. That sounds like a wonderful use of that in-between state that you're in where you still got to make progress but also introduce some refactoring and a new concept. And I also appreciate how long you waited because that's one of those areas where I've just learned, like, just wait. It's not going to hurt you. Just embrace the duplication and then make sure it's the right thing. Because even if you have to go in and update it in a couple of places, okay, sure, that feels a little tedious, but it feels very safe too. If it doesn't feel safe...I could talk myself back and forth on this one. If it doesn't feel safe, that's a different discussion. But if you're going through and you have to update something in a couple of different places, that's quick. And sure, you had to repeat yourself a little bit, but that's fine. Versus if you have two or three of something and you're like, oh, I immediately must extract. That's probably going to cause more pain than it's worth at this point. CHRIS: Yeah, exactly, exactly that. And we did get to that place where we were starting to feel a tiny bit of pain. We had a surprising bit of behavior that when we looked at it, we were like, oh, that's interesting, because of how we implemented the webhook pattern, this is happening. And so then we went to fix it, but we were like, oh, it would actually be really nice to have this fixed across everything. We've had conversations about other refinements, enhancements, et cetera; that we could do in this space. That, again, would be really nice to be able to do holistically across all of the different webhook integration things that we have. And so it feels like we waited the right amount of time. But then we also started to...we're trying to be very responsive to the pressure that the system is pushing back on us. As an aside, the crispy Brussels snack hour and the crispy Brussels work lunch continue to be utterly fantastic ways in which we work. For anyone that is unfamiliar or hasn't listened to episodes where I rambled about those nonsense phrases that I just said, they're basically just structured time where the engineering team at Sagewell looks at and discusses higher-level architecture, refactoring, developer experience, those sort of things that don't really belong on the core product board. So we have a separate place to organize them, to gather them. And then also, we have a session where we vote on them, decide which ones feel important to take on but try and make sure we're being intentional about how much of that work we're taking on relative to how much of core product work and try and keep sort of a good ratio in between the two. And thus far, that's been really fantastic and continues to be, I think, really effective. And also the sort of thing that just keeps the developer team really happy. So it's like, I'm happy to work in this system because we know we have a way to change it and improve it where there's pain. STEPH: I like the idea of this being a game show where it's like refactor island, and everybody gets together and gets to vote which refactor stays or gets booted off the island. I'm also going to go back and qualify something I said a moment ago, where if something feels safe in terms of duplication, where it starts to feel unsafe is if there's like an area that you forgot to update because you didn't realize it's duplicated in several areas and then that causes you pain. Then that's one of those areas where I'll start to say, "Okay, let's rethink the duplication and look to dry this up." CHRIS: Yep, indeed. It's definitely like a correction early on in my career and overcorrection back and trying to find that happy medium place. But as an aside, just throwing this out there, so webhooks are an interesting space. I wish it were a more commoditized offering of platforms. Every vendor that we're integrating with that does webhooks does it slightly differently. It's like, "Oh, do you folks have retries?" They're like, "No." It's like, oh, what do you mean no? I would love it if you had retries because, I don't know, we might have some reason to not receive one of them. And there's polling, and there are lots of different variations. But the one thing that I'm surprised by is that webhook signing I don't feel like people take it serious enough. It is a case where it's not a huge security vulnerability in your app. But I was reading someone who is a security analyst at one point. And they were describing sort of, I've done tons of in-the-code audits of security practices, and here are the things that I see. And so it's the normal like OWASP Top 10 Cross-Site Request Forgery, and SQL injection, and all that kind of stuff. But one of the other ones he highlighted is so often he finds webhooks that are not verified in any way. So it's just like anyone can post data into the system. And if you post it in the right shape, the system's going to do some stuff. And there's no way for the external system to enforce that you properly validate and verify a webhook coming in, verify that payload. It's an extra thing where you do the checksum math and whatnot and take the signature header. I've seen somewhere they just don't provide it. And it's like, what do you mean you don't provide it? You must provide it, please. So it's either have an API key so that we have some way to verify that you are who you say you are or add a signature, and then we'll calculate it. And it's a little bit of a dance, and everybody does it different, but whatever. But the cases where they just don't have it, I'm like, I'm sorry, what now? You're going to say whom? But yeah, then it's our job to definitely implement that. So this is just a notice out there to anyone that's listening. If you got a bunch of webhook handling code in your app, maybe spot-check that you're actually verifying the payloads because it's possible that you're not. And that's a weird, very open hole in the side of your application. STEPH: That's a really great point. I have not worked with webhooks recently. And in the past, I can't recall if that's something that I've really looked at closely. So I'm glad you shared that. CHRIS: It's such an easy thing to skip. Like, it's one of those things that there's no way to enforce it. And so, I'd be interested in a survey that can't be done because this is all proprietary data. But what percentage of webhook integrations are unverified? Is it 50%? Is it 10%? Is it 100%? It's definitely not 100. But it's somewhere in there that I find interesting. It's not a terribly exploitable vulnerability because you have to have deep knowledge of the system. In order to take advantage of it, you need to know what endpoint to hit to, what shape of data to send because otherwise, you're probably just going to cause an error or get a bunch of 404s. But like, it's, I don't know, it's discoverable. And yeah, it's an interesting one. So I will hop off my webhook soapbox now, but that's a thought. MIDROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers, that can actually help you cut your debugging time in half. So why do developers love Airbrake? Well, it has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. So head on over to airbrake.io/try/bikeshed to create your FREE developer account today! CHRIS: But now that I'm off my soapbox, I believe we have a topic that was suggested. Do you want to provide a little bit of context here, Steph? STEPH: Yeah, I'd love to. So this came up when I was having a conversation with another thoughtboter. And given that we change projects fairly frequently, on the Boost team, we typically change projects around every six months. They asked a really thoughtful question that was "How do you get acquainted with a new codebase? So given that you're changing projects so often, what are some of the tips and tricks for ways that you've learned to then quickly get up to speed with a new codebase?" Because, frankly, that is one of the thoughtbot superpowers is that we are really good at onboarding each other and then also getting up to speed with a new team, and their processes, and their codebase. So I have a couple of ideas, and then I'd love to hear some of your thoughts as well. So I'll dive in with a couple. So the first one, this one's frankly my favorite. Like day one, if there's a team where I'm joining and they have someone that can walk me through the application from the users' perspective, maybe it's someone that's in sales, or maybe it's someone on the product team, maybe it's a recording that they've already done for other people, but that's my first and favorite way to get to know an application. I really want to know what are users experience as they're going through this app? That will help me focus on the more critical areas of the application based on usage. So if that's available, that's fabulous. I'm also going to tailor a lot of this more to like a Rails app since that's typically the type of project that I'm onboarding to. So the other types of questions that I like to find answers to are just like, what's my top-level structure? Like to look through the app and see how are things organized? Chris, you've mentioned in a previous episode where you have your client structure that then highlights all the third-party clients that you're working with. Are we using engines in the app? Is there anything that seems a bit more unique to that application that I'm going to want to brush up on or look into? What's the test coverage like? Do they have something that's already highlighting how much test coverage they have? If not, is there something that then I can run locally that will then show me that test coverage? I also really like to look at the routes file. That's one of my other favorite places because that also is very similar to getting an overview of the product. I get to see more from the user perspective. What are the common resources that people are going to, and what are the domain topics that I'm working with in this new application? I've got a couple more, but I'm going to pause there and see how you get acquainted with a new app. CHRIS: Well, unsurprisingly, I agree with all of those. We're still searching for that dare to disagree beyond Pop-Tarts and IPAs situation. To reiterate or to emphasize some of the points you made, the sales demo thing? I absolutely love that one because, yes, absolutely. What's the most customer-centric point of view that I can have? Can I then login to a staging version of the site so I can poke around and hopefully not break anything or move real money or anything like that? But understanding why is this thing, not in code, but in actual practical, observable, intractable software? Beyond that, your point about the routes, absolutely, that's one of my go-to's, although the routes there often is so much in the routes, and it's like some of those may actually be unused. So a corollary to the routes where available if there's an APM tool like Scout, or New Relic, or something like that, taking a look at that and seeing what are the heavily trafficked endpoints within this app? I like to think about it as the entry points into this codebase. So the routes file enumerates all of them, but some of them matter, and some of them don't. And so, an APM tool can actually tell you which are the ones that are seeing a ton of traffic. That's a really interesting question for me. Similarly, if we're on Heroku, I might look is there a scheduler? And if so, what are the tasks that are running in the background? That's another entry point into the app. And so I like to think about it from that idea of entry points. If it's not on Heroku, and then there's some other system, like, I've used Cronic. I think it's Cronic, Whenever the Cron thing. Whenever, that's what it is, the Whenever gem that allows you to implement that, but it's in a file within the codebase, which as an aside, I really love that that's committed and expressive in the code. Then that's another interesting one to see. If it's more exotic than that, I may have to chase it down or ask someone, but I'll try and find what are all of the entry points and which are the ones that matter the most? I can drill down from there and see, okay, what code then supports these entry points into the application? I want to give an answer that also includes something like, oh, I do fancy static analysis in the codebase, and I do a churn versus complexity graph, and I start to...but I never do that, if we're being honest. The thing that I do is after that initial cursory scan of the landscape, I try and work on something that is relatively through the layers of the app, so not like, oh, I'll fix the text in a button. But like, give me something weird and ideally, let me pair with someone and then try and move through the layers of the app. So okay, here's our UI. We're rendering in this way. The controllers are integrated in this way, et cetera. This is our database. Try and get through all the layers if possible to try and get as holistic of a view of how the application works. The other thing that I think is really interesting about what you just said is you're like, I'm going to give some answers that are somewhat specific to a Rails app. And that totally makes sense to me because I know how to answer this in the context of a Rails app because those organizational patterns are so useful that I can hop into different Rails apps. And I've certainly seen ones that I'm like, this is odd and unfamiliar to me, but most of them are so much more discoverable because of that consistency. Whereas I have worked on a number of React apps, and every single one I come into, I'm like, okay, wait, what are we doing? How are we doing state management? What's the routing like? Are we server-side rendering, are we not? And it is a thing that...I see that community really moving in the direction of finding the meta frameworks that stitch the pieces together and provide more organizational structure and answer more of the questions out of the box. But it continues to be something that I absolutely love about Rails is that Rails answers so many of the questions for me. New people joining the team are like, oh, it's a Rails app, cool. I know how to Rails, and we get to run with that. And so that's more of a pitch for Rails than an answer to the question, but it is a thing that I felt in answering this question. [laughs] But yeah, those are some thoughts. But interested, it sounds like you had some more as well. I would love to hear what else was in your mind when you were thinking about this. STEPH: I do. And I want to highlight you said some really wonderful things. One that really stuck out to me that I had not considered is using Scout APM to look at heavily-trafficked endpoints. I have that on my list in regards as something that I want to know what's my error tracking, observability. Like, if I break something or if you give me a bug ticket to work on, what am I going to use? How am I going to understand what's going wrong? But I hadn't thought of it in terms of seeing which endpoints are heavily used. So I really liked that one. I also liked how you highlighted that you wish you'd do something fancy around doing a churn versus complexity kind of graph because I thought of that too. I was like, oh, that would be such a nice answer. But the truth is I also don't do that. I think it's all those things. I think it would be fun to make it easy. So I do that with new applications. But I agree; I typically more just dive in like, hey, give me a ticket. Let me go from there. I might do some simple command-line checking. So, for example, if I want to look through app models, let's find out which model is the largest. I may look for that to see do we have a God object or something like that? So I may look there. I just want to know how long are some of these files? But I also don't use a particular tool for that churn versus complexity. CHRIS: I think you hit the nail on the head with like, I wish that were easier or more in our toolset. But here on The Bike Shed, we tell the truth. And that is aspirational code flexing that we do not yet have. But I agree, that would be a really nice way to explore exactly what you're describing of, like, who are the God models? I'll definitely do that check, but not some of the more subtle and sophisticated show me the change over time of all these...like nah, that's not what I'm doing, much as I would like to be able to answer that way. STEPH: But it also feels like one of those areas like, it would be nice, but I would be intrigued to see how much I use that. That might be a nice anecdote to have. But I find the diving into the codebase to be more fruitful because I guess it depends on what I'm really looking at. Am I looking to see how complicated of a codebase this is? Because then I need to give more of a high-level review to someone to say how long I think it's going to take for me to work on a particular feature or before I'm joining a team, like, who do I think are good teammates that would then enjoy working on this application? That feels like a very different question to me versus the I'm already part of the team. I'm here. We're going to have complexity and churn. So I can just learn some of that over time. I don't have to know that upfront. Although it may be nice to just know at a high level, say like, okay, if I pick up a ticket, and then I look at that churn and complexity, to be like, okay, my ticket falls right smack-dab in the middle of that. So it's going to be a fun first week. That could be a fun fact. But otherwise, I'm not sure. I mean, yeah, I'd be intrigued to see how much it helps me. One other place that I do browse is I go to the gem file. I'm just always curious, what do people have in their tool bag? I want to see are there any gems that have been pulled in that are helping the team process some deprecated behavior? So something that's been pulled out of Rails but then pulled into a separate gem. So then that way, they don't have to upgrade just yet, or they can upgrade but then still keep some of that existing old deprecated behavior. That kind of stuff is interesting to me. And also, you called it earlier pairing. That's my other favorite way. I want to hear how people talk about the codebase, how they navigate. What are they frustrated by? What brings them joy? All of that is really helpful too. I think that covers all the ways that I immediately will go to when getting acquainted with a new codebase. CHRIS: I think that covers most of what I have in mind, although the question is framed in an interesting way that I think really speaks to the consultant mindset. How do I get acquainted with a new codebase? But if you take the question and flip it around sort of 180 degrees, I think the question can be reframed as how does an organization help people onboard into a codebase? And so everything we just described are like, here's what I do, here's how I would go about it, and pairing starts to get to collaboration. I think we've talked in a number of episodes about our thoughts on onboarding and being intentional with that, pairing people up. A lot of things we described it's like, it's ideal actually if the organization is pushing this. And you and I both worked as consultants for long enough that we're really in the mindset of like, all right, let's assume I'm just showing up. There's no one else there. They give me a laptop and no documentation and no other humans I'm allowed to talk to. How do I figure this out and get the next feature out to production? And ideally, it's something slightly better than that that we experience, but we're ready for whatever it is. Versus, most people are working within the context of an organization for a longer period of time. And most organizations should be thinking about it from the perspective of how do I help the new hires come into this codebase and become effective as quickly as possible? And so I think a lot of what we said can just be flipped around and said from the other way, like, pair them up, put them on a feature early, give them a walkthrough of the codebase, give them a sales-centric demo. Yeah, I feel equally about those things when said from the other side, but I do want to emphasize that this shouldn't be you're out there in the middle of the jungle with only a machete, and you got to figure out this codebase. Ideally, the organization is actually like, no, no, we'll help you. It's ours, so we know it. We can help you find the weird stuff. STEPH: That's a really nice distinction, though, because you're right; I hadn't really thought about this. I was thinking about this from more of the perspective of you're out in the jungle with a machete, minus we did mention pairing in there [laughs] and maybe a demo. I was approaching it more from you're isolated or more solo and then getting accustomed to the codebase versus if you have more people to lean on. But then that also makes me think of all the other processes that I didn't mention that I would include in that onboarding that you're speaking of, of like, how does this team work in terms of where do I push my code? What hooks are going to run? And then what do I wait for? How many people need to review my code? There are all those process-y questions that I think would ideally be included on the onboarding. But that has happened before, I mean, where we've joined projects, and it's been like, okay, good luck. Let us know if you need anything. And so then you do need those machete skills to then start hacking away. [laughs] CHRIS: We've been burned before. STEPH: They come in handy. [laughs] So when you are in that situation, and there's a comet that's coming to destroy earth, and there's a Rails application that is preventing this big doomsday, the question is, do you take astronauts and train them to be Rails experts, or do you take Rails developers and train them to be astronauts? I think that's the big question. CHRIS: What would Michael Bay do? STEPH: On that note, shall we wrap up? CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeee!!!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Steph has an update and a question wrapped into one about the work that is being done to migrate the Test::Unit test over to RSpec. Chris got to do something exciting this week using dry-monads. Success or failure? This episode is brought to you by BuildPulse (https://buildpulse.io/bikeshed). Start your 14-day free trial of BuildPulse today. Bartender (https://www.macbartender.com/) dry-rb - dry-monads v1.0 - Pattern matching (https://dry-rb.org/gems/dry-monads/1.0/pattern-matching/) alfred-workflows (https://github.com/tupleapp/alfred-workflows/blob/master/scripts/online_users.rb) Raycast (https://www.raycast.com/) ruby-science (https://github.com/thoughtbot/ruby-science) Inertia.js (https://inertiajs.com/) Remix (https://remix.run/) Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: AD: Flaky tests take the joy out of programming. You push up some code, wait for the tests to run, and the build fails because of a test that has nothing to do with your change. So you click rebuild, and you wait. Again. And you hope you're lucky enough to get a passing build this time. Flaky tests slow everyone down, break your flow, and make things downright miserable. In a perfect world, tests would only break if there's a legitimate problem that would impact production. They'd fail immediately and consistently, not intermittently. But the world's not perfect, and flaky tests will happen, and you don't have time to fix all of them today. So how do you know where to start? BuildPulse automatically detects and tracks your team's flaky tests. Better still, it pinpoints the ones that are disrupting your team the most. With this list of top offenders, you'll know exactly where to focus your effort for maximum impact on making your builds more stable. In fact, the team at Codecademy was able to identify their flakiest tests with BuildPulse in just a few days. By focusing on those tests first, they reduced their flaky builds by more than 68% in less than a month! And you can do the same because BuildPulse integrates with the tools you're already using. It supports all of the major CI systems, including CircleCI, GitHub Actions, Jenkins, and others. And it analyzes test results for all popular test frameworks and programming languages, like RSpec, Jest, Go, pytest, PHPUnit, and more. So stop letting flaky tests slow you down. Start your 14-day free trial of BuildPulse today. To learn more, visit buildpulse.io/bikeshed. That's buildpulse.io/bikeshed. STEPH: What type of bird is the strongest bird? CHRIS: I don't know. STEPH: A crane. [laughter] STEPH: You're welcome. And on that note, shall we wrap up? CHRIS: Let's wrap up. [laughter] Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris, I saw a good movie I'd like to tell you about. It was just over the weekend. It's called The Duke, and it's based on a real story. I should ask, have you seen it? Have you heard of this movie called The Duke? CHRIS: I don't think so. STEPH: Okay, cool. It's a true story, and it's based on an individual named Kempton Bunton who then stole a particular portrait, a Goya portrait; if you know your artist, I do not. But he stole a Goya portrait and then essentially held at ransom because he was a big advocate that the BBC News channel should be free for people that are living on a pension or that are war veterans because then they're not able to afford that fee. But then, if you take the BBC channel away from them, it disconnects them from society. And it's a very good movie. I highly recommend it. So I really enjoyed watching that over the weekend. CHRIS: All right. Excellent recommendation. We will, of course, add that to the show notes mostly so that I can find it again later. STEPH: On a more technical note, I have a small update, or it's more of a question. It's an update and a question wrapped into one about the work that is being done to migrate the Test::Unit test over to RSpec. This has been quite a journey that Joël and I have been on for a while now. And we're making progress, but we're realizing that we're spending like 95% of our time in the test setup and porting that over, specifically because we're mapping fixture data over to FactoryBot, and we're just realizing that's really painful. It's taking up a lot of time to do that. And initially, when I realized we were just doing that, we hadn't even really talked about it, but we were moving it over to FactoryBot. I was like, oh, cool. We'll get to delete all these fixtures because there are around 208 files of them. And so that felt like a really good additional accomplishment to migrating the test over. But now that we realize how much time we're spending migrating the data over for that test setup, we've reevaluated, and I shared with Joël in the Slack channel. I was like, crap. I was like, I have a bad idea, and I can't not say it now because it's crossed my mind. And my bad idea was what if we stopped porting over fixtures to FactoryBot and then we just added the fixtures to a directory that RSpec would look so then we can rely on those fixtures? And then that way, we're literally then ideally just copying over from Test::Unit over to RSpec. But it does mean a couple of things. Well, one, it means that we're now running those fixtures at the beginning of RSpec test. We're introducing another pattern of where these tests are already using FactoryBot, but now they have fixtures at the top, and then we won't get to delete the fixtures. So we had a conversation around how to manage and mitigate some of those concerns. And we're still in that exploratory. We're going to test it out and see if this really speeds us up referencing the fixtures. The question that's wrapped up in this is there's something different between how fixtures generate data and how factories generate data. So I've run into this a couple of times now where I moved data over to just call a factory. But then I was hitting these callbacks or after-save-hooks or weird things that were then preventing me from creating the record, even though fixtures was creating them just fine. And then Joël pointed out today that he was running into something similar where there were private methods that were getting called. And there were all sorts of additional code that was getting run with factories versus fixtures. And I don't have an answer. Like, I haven't looked into this. And it's frankly intentional because I was trying hard to not dive into understanding the mechanics. We really want to get through this. But now I'm starting to ponder a little more as to what is different with fixtures and factories? And I liked that factories is running these callbacks; that feels correct. But I'm surprised that fixtures doesn't, or at least that's the experience that I'm having. So there's some funkiness there that I'd like to explore. I'll be honest; I don't know if I'm going to. But if anybody happens to know what that funkiness is or why fixtures and factories are different in that regard, I would be very intrigued because, at some point, I might look into it just because I would like to know. CHRIS: Oh, that is interesting. I have not really worked with fixtures much at all. I've lived a factory life myself, and thus that's where almost all of my experience is. I'm not super surprised if this ends up being the case, like, the idea that fixtures are just some data that gets shoveled into the database directly as opposed to FactoryBot going through the model layer. And so it's sort of like that difference. But I don't know that for certain. That sounds like what this is and makes sense conceptually. But I think this is what you were saying like, that also kind of pushes me more in the direction of factories because it's like, oh, they're now representative. They're using our model layer, where we're defining certain truths. And I don't love callbacks as a mechanism. But if your app has them, then getting data that is representative is useful in tests. Like one of the things I add whenever I'm working with FactoryBot is the FactoryBot lint rake task RSpec thing that basically just says, "Are your factories valid?" which I think is a great baseline to have. Because you may add a migration that adds a default constraint or something like that to the database that suddenly all your factories are invalid, and it's breaking tests, but you don't know it. Like subtly, you change it, and it doesn't actually break a test, but then it's harder later. So that idea of just having more correctness baked in is always nice, especially when it can be automated like that, so definitely a fan of that. But yeah, interested if you do figure out the distinction. I do like your take, though, of like, but also, maybe I just won't figure this out. Maybe this isn't worth figuring it out. Although you were in the interesting spot of, you could just port the fixtures over and then be done and call the larger body of work done. But it's done in sort of a half-complete way, so it's an interesting trade-off space. I'm also interested to hear where you end up on that. STEPH: Yeah, it's a tough trade-off. It's one that we don't feel great about. But then it's also recognizing what's the true value of what we're trying to deliver? And it also comes down to the idea of churn versus complexity. And I feel like we are porting over existing complexity and even adding a smidge, not actual complexity but adding a smidge of indirection in terms that when someone sees this file, they're going to see a mixed-use of fixtures and factories, and that doesn't feel good. And so we've already talked about adding a giant comment above fixtures that just is very honest and says, "Hey, these were ported over. Please don't mimic this. But this is some legacy tests that we have brought over. And we haven't migrated the fixtures over to use factories." And then, in regards to the churn versus complexity, this code isn't likely to get touched like these tests. We really just need them to keep running and keep validating scenarios. But it's not likely that someone's going to come in here and really need to manage these anytime soon. At least, this is what I'm telling myself to make me feel better about it. So there's also that idea of yes, we are porting this over. This is also how they already exist. So if someone did need to manage these tests, then going to Test::Unit, they would have the same experience that they're going to have in RSpec. So that's really the crux of it is that we're not improving that experience. We're just moving it over and then trying to communicate that; yes, we have muddied the waters a little bit by introducing this other pattern. So we're going to find a way to communicate why we've introduced this other pattern, but that way, we can stay focused on actually porting things over to RSpec. As for the factories versus fixtures, I feel like you're onto something in terms of it's just skipping that model layer. And that's why a lot of that functionality isn't getting run. And I do appreciate the accuracy of factories. I'd much rather know is my data representative of real data that can get created in the world? And right now, it feels like some of the fixtures aren't. Like, how they're getting created seemed to bypass really important checks and validations, and that is wrong. That's not what we want to have in our test is, where we're creating data that then the rest of the application can't truly create. But that's another problem for another day. So that's an update on a trade-off that we have made in regards to the testing journey that we are on. What's going on in your world? CHRIS: Well, we got to do something exciting this week. I was working on some code. This is using dry-monads, the dry-rb space. So we have these result objects that we use pretty pervasively throughout the app, and often, we're in a controller. We run one of these command objects. So it's create user, and create user actually encompasses a ton of logic in our app, and that object returns a result. So it's either a success or a failure. And if it's a success, it'll be a success with that new user wrapped up inside of it, or if it's a failure, it's a specific error message. Actually, different structured error messages in different ways, some that would be pushed to the form, some that would be a flash message. There are actually fun, different things that we do there. But in the controller, when we interact with those result objects, typically what we'll do is we'll say result equals create user dot run, (result=createuser.run) and then pass it whatever data it needs. And then on the next line, we'll say results dot either, (results.either), which is a method on these result objects. It's on both the success and failure so you can treat them the same. And then you pass what ends up being a lambda or a stabby proc, or I forget what they are. But one of those sort of inline function type things in Ruby that always feel kind of weird. But you pass one of those, and you actually pass two of them, one for the success case and one for the failure case. And so in the success case, we redirect back with a notice of congratulations, your user was created. Or, in the failure case, we potentially do a flash message of an alert, or we send the errors down, or whatever it ends up being. But it allows us to handle both of those cases. But it's always been syntactically terrible, is how I would describe it. It's, yeah, I'm just going to leave it at that. We are now living in a wonderful, new world. This has been something that I've wanted to try for a while. But I finally realized we're actually on Ruby 2.7, and so thus, we have access to pattern matching in Ruby. So I get to take it for a spin for the first time, realizing that we were already on the correct version. And in particular, dry-monads has a page in their docs specific to how we can take advantage of pattern matching with the result objects that they provide us. There's nothing specific in the library as far as I understand it. This is just them showing a bunch of examples of how one might want to do it if they're working with these result objects. But it's really great because it gives the ability to interact with, you know, success is typically going to be a singular case. There's one success branch to this whole logic, but there are like seven different ways it can fail. And that's the whole idea as to why we use these command objects and the whole Railway Oriented Programming and that whole thing which I have...what is this word? [laughs] I feel like I should know it. It's a positive rant. I have raved; that is how our users kindly pointed that out to us. I have raved about the Railway Oriented Programming that allows us to do. But it's that idea that they're actually, you know, there's one happy path, and there are seven distinct failure modes, seven unhappy paths. And now, using pattern matching, we actually get a really expressive, readable, useful way to destructure each of those distinct failures to work with the particular bits of data that we need. So it was a very happy day, and I got to explore it. This is, again, a feature of Ruby, not a feature of dry-monads. But dry-monads just happens to embrace it and work really well with it. So that was awesome. STEPH: That is awesome. I've seen one or two; I don't know, I've seen a couple of tweets where people are like, yeah, Ruby pattern matching. I haven't found a way to use it. So I'm excited that you just shared a way that you found to use it. I'm also worried what it says about our developer culture that we know the word rant so well, but rave, we always have to reach back into our memory to be like, what's that positive word or something that we like? [laughs] CHRIS: And especially here on The Bike Shed, where we try to gravitate towards the positive. But yeah, it's an interesting point that you make. STEPH: We're a bunch of ranters. It's what we do, pranting ranters. I don't know why we're pranting. [laughs] CHRIS: Because it's that exciting. That's what it is. Actually, there was an interesting thing as we were playing around with the pattern matching code, just poking around in the console session with it, and it prints out a deprecation warning. It's like, warning: this is an experimental feature. Do not use it, be careful. But in the back of my head, I was like, I actually know how this whole thing plays out, Ruby 2.7, and I assure you, it's going to be fine. I have been to the future, at least I'm pretty sure. I think the version that is in Ruby 2.7 did end up getting adopted basically as it stands. And so, I think there is also a setting to turn off that deprecation warning. I haven't done it yet, but I mostly just enjoyed the conversation that I had with this deprecation message of like, listen, I've been to the future, and it's great. Well, it's complicated, but specific to this pattern matching [laughs] in Ruby 3+ versions, it went awesome. And I'm really excited about that future that we now live in. STEPH: I wish we had that for so many more things in our life [laughs] of like, here's a warning, and it's like, no, no, I've seen the future. It's all right. Or you're totally right; I should avoid and back out of this now. CHRIS: If only we could know how the things would play out, you know. But yeah, so pattern matching, very cool. I'll include a link in the show notes to the particular page in the dry-monads docs. But there are also other cool things on the internet. In an unrelated but also cool thing that I found this week, we use Tuple a lot within our organization for pair programming. For anyone who's not familiar with it, it's a really wonderful piece of technology that allows you to pair program pretty seamlessly, better video quality, all of those nice things that we want. But I found there was just the tiniest bit of friction in starting a Tuple call. I know I want to pair with this person. And I have to go up and click on the little menu bar, and then I have to find their name, then I have to click a button. That's just too much. That's not how...I want to live my life at the keyboard. I have a thing called Bartender, which is a little menu bar manager utility app that will collapse down and hide the icons. But it's also got a nice, little hotkey accessible pop-up window that allows me to filter down and open one of the menu bar pop-out menus. But unfortunately, when that happens, the Tuple window isn't interactive at that point. I can't use the arrow keys to go up and down. And so I was like, oh, man, I wonder if there's like an Alfred workflow for this. And it turns out indeed there is actually managed by the kind folks at Tuple themselves. So I was able to find that, install it; it's great. I have it now. I can use that. So that was a nice little upgrade to my workflow. I can just type like TC space and then start typing out the person's name, and then hit enter, and it will start a call immediately. And it doesn't actually make me more productive, but it makes me happier. And some days, that's what matters. STEPH: That's always so impressive to me when that happens where you're like, oh, I need a thing. And then you went through the saga that you just went through. And then the people who manage the application have already gotten there ahead of you, and they're like, don't worry, we've created this for you. That's one of those just beautiful moments of like, wow, y'all have really thought this through on a bunch of different levels and got there before me. CHRIS: It's somewhat unsurprising in this case because it's a very developer-centric organization, and Ben's background being a thoughtbot developer and Alfred user, I'm almost certain. Although I've seen folks talking about Raycast, which is the new hotness on the quick launcher world. I started eons ago in Quicksilver, and then I moved to Alfred, I don't know, ten years ago. I don't know what time it is anymore. But I've been in Alfred land for a while, but Raycast seems very cool. Just as an aside, I have not allowed myself... [laughs] this is another one of those like; I do not have permission to go explore this new tool yet because I don't think it will actually make me more productive, although it could make me happier. So... STEPH: I haven't heard of that one, Raycast. I'm literally adding it to the show notes right now as a way so you can find The Duke later, and I can find Raycast later [chuckles] and take a look at it and check it out. Although I really haven't embraced the whole Alfred workflow. I've seen people really enjoy it and just rave about it and how wonderful it is. But I haven't really leaned into that part of the world; I don't know why. I haven't set any hard and fast rules for myself where I can't play around with these technologies, but I haven't taken the time to do it either. CHRIS: You've also not found yourself writing thousands of lines of Vimscript because you thought that was a good idea. So you don't need as many guardrails it would seem. That's my guess. STEPH: This is true. CHRIS: Whereas I need to be intentional [laughs] with how I structure my interaction with my dev tools. STEPH: Instead, I'm just porting over fixtures from one place to another. [laughs] That's the weird space that I'm living in instead. [laughs] CHRIS: But you're getting paid for that. No one paid me for the Vimscript I wrote. [laughter] STEPH: That's fair. Speaking around process-y things, there's something that's been on my mind that Valeria, another thoughtboter, suggested around how we structure our meetings and the default timing that we have for meetings. So Thursdays are my team-focused day. And it's the day where I have a lot of one on ones. And I realized that I've scheduled them back to back, which is problematic because then I have zero break in between them, which I'm less concerned about that because then I can go for an hour or something and not have a break. And I'm not worried about that part. But it does mean that if one of those discussions happens to go over just even for like two or three minutes, then it means that someone else is waiting for me in those two to three minutes. And that feels unacceptable to me. So Valeria brought up a really good idea where I think it's only with the Google Meet paid version. I could be wrong there. But I think with the paid version of it that then you can set the new default for how long a meeting is going to last. So instead of having it default to 30 minutes, have it default to 25 minutes. So then, that way, you do have that five-minute buffer. So if you do go over just like two or three minutes with someone, you've still got like two minutes to then hop to the next call, and nobody's waiting for you. Or if you want those five minutes to then grab some water or something like that. So we haven't implemented it just yet because then there's discussion around is this a new practice that we want everybody to move to? Because I mean, if just one person does it, it doesn't work. You really need everybody to buy into the concept of we're now defaulting to 25 versus 30-minute meetings. So I'll have to let you know how that goes. But I'm intrigued to try it out because I think that would be very helpful for me. Although there's a part of me that then feels bad because it's like, well, if I have 30 minutes to chat with somebody, but now I'm reducing it to 25 minutes each time, I didn't love that I'm taking time away from our discussion. But that still feels like a better outcome than making somebody wait for three to five minutes if something else goes over. So have you ever run into something like that? How do you manage back-to-back meetings? Do you intentionally schedule a break in between or? CHRIS: I do try to give myself some buffer time. I stack meetings but not so much so that they're just back to back. So I'll stack them like Wednesdays are a meeting-heavy day for me. That's intentional just to be like, all right, I know that my day is going to get chopped up. So let's just really lean into that, chop the heck out of Wednesday afternoons, and then the rest of the week can hopefully have slightly longer deep work-type sessions. And, yeah, in general, I try and have like a little gap in between them. But often what I'll do for that is I'll stagger the start of the next meeting to be rather than on the hour or the half-hour, I start it on the 15th minute. And so then it's sort of I now have these little 15-minute gaps in my workflow, which is enough time to do one or two small things or to go get a drink or whatever it is or if things do run over. Like, again, I feel what you're saying of like, I don't necessarily want to constrain a meeting. Or I also don't necessarily want to go into the habit of often over-running. I think it's good to be intentional. Start meetings on time, end meetings on time. If there's a great conversation that's happening, maybe there's another follow-up meeting that should happen or something like that. But for as nonsensical of a human as I believe myself to be, I am rather rigid about meetings. I try very hard to be on time. I try very hard to wrap them up on time to make sure I go to the next one. And so with that, the 15-minute staggering is what I've found works for me. STEPH: Yeah, that makes sense. One-on-ones feels special to me because I wholeheartedly agree with being very diligent about like, hey, this is our meeting time. Let's do a time check. Someone says that at the end, and then that way, everybody can move on. But one on ones are, there's more open discussion space, and I hate cutting people off, especially because it might not be until the last 15 minutes that you really got into the meat of the conversation. Or you really got somewhere that's a little bit more personal or things that you want to talk about. So if someone's like, "Yeah, let me tell you about my life goals," and you're like, "Oh, no, wait, sorry. We're out of time." That feels terrible and tragic to do. So I struggle with that part of it. CHRIS: I will say actually, on that note, I'm now thinking through, but I believe this to be true. Everyone that reports to me I have a 45-minute one-on-one with, and then my CEO I set up the one-on-one. So I also made that one a 45-minute one-on-one. And that has worked out really well. Typically, I try and structure it and reiterate this from time to time of, like, hey, this is your space, not mine. So let's have whatever conversation fits in here. And it's fine if we don't need to use the whole time, but I want to make sure that we have it and that we protect it. Because I often find much like retro, I don't know; I think everything's fine. And then suddenly the conversation starts, and you're like, you know what? Actually, I'm really concerned now that you mentioned it. And you need that sort of empty space that then the reality sort of pop up into. And so with one on one, I try and make sure that there is that space, but I'm fine with being like, we can cut this short. We can move on from one-on-one topics to more of status updates; let's talk about the work. But I want to make sure that we lead with is there anything deeper, any concerns, anything you want to talk through? And sort of having the space and time for that. STEPH: I like that. And I also think it speaks more directly to the problem I'm having because I'm saying that we keep running over a couple of minutes, and so someone else is waiting. So rather than shorten it, which is where I'm already feeling some pain...although I still think that's a good idea to have a default of 25-minute meetings so then that way, there is a break versus the full 30. So if people want to have back-to-back meetings, they still have a little bit of time in between. But for one on ones specifically, upping it to 45 minutes feels nice because then you've got that 15-minute buffer likely. I mean, maybe you schedule a meeting, but, I don't know, that's funky. But likely, you've got a 15-minute buffer until your next one. And then that's also an area that I feel comfortable in sharing with folks and saying, "Hey, I've booked this whole 45 minutes. But if we don't need the whole time, that's fine." I'm comfortable saying, "Hey, we can end early, and you can get more of your time back to focus on some other areas." It's more the cutting someone off when they're talking because I have to hop to the next thing. I absolutely hate that feeling. So thanks, I think I'll give that a go. I think I'll try actually bumping it up to 45 minutes, presuming that other people like that strategy too, since they're opting in [laughs] to the 45 minutes structure. But that sounds like a nice solution. CHRIS: Well yeah, happy to share it. Actually, one interesting thing that I'm realizing, having been a manager at thoughtbot and then now being a manager within Sagewell, the nature of the interactions are very different. With thoughtbot, I was often on other projects. I was not working with my team day to day in any real capacity. So it was once every two weeks, I would have this moment to reconnect with them. And there was some amount of just catching up. Ideally, not like status update, low-level sort of thing, but sort of just like hey, what have you been working on? What have you been struggling with? What have you been enjoying? There was more like I needed bigger space, I would say for that, or it's not surprising to me that you're bumping into 30 minutes not being quite long enough. Whereas regularly, in the one on ones that I have now, we end up cutting them short or shifting out of true one-on-one mode into more general conversation and chatting about Raycast or other tools or whatever it is because we are working together daily. And we're pairing very regularly, and we're all on the same project and all sorts of in sync and know what's going on. And we're having retro together. We have plenty of places to have the conversation. So the one-on-one again, still, I keep the same cadence and the same time structure just because I want to make sure we have the space for any day that we really need that. But in general, we don't. Whereas when I was at thoughtbot, it was all the more necessary. And I think for folks listening; I could imagine if you're in a team lead position and if you're working very closely with folks, then you may be on the one side of things versus if you're a little bit more at a distance from the work that they're doing day to day. That's probably an interesting question to ask, and think about how you want to structure it. STEPH: Yeah, I think that's an excellent point. Because you're right; I don't see these individuals. We may not have really gotten to interact, except for our daily syncs outside of that. So then yeah, there's always like a good first 10 minutes of where we're just chatting about life and catching up on how things are going before then we dive into some other things. So I think that's a really good point. Cool, solving management problems on the mic. I dig it. In slightly different news, I've joined a book club, which I'm excited about. This book club is about Ruby. It's specifically reading the book Ruby Science, which is a book that was written and published by thoughtbot. And it requires zero homework, which is my favorite type of book club. Because I have found I always want to be part of book clubs. I'm always interested in them, but then I'm not great at budgeting the time to make sure I read everything I'm supposed to read. And so then it comes time for folks to get together. And I'm like, well, I didn't do my homework, so I can't join it. But for this one, it's being led by Joël, and the goal is that you don't have to do the homework. And they're just really short sections. So whoever's in charge of leading that particular session of the book club they're going to provide an overview of what's covered in whatever the reading material that we're supposed to read, whatever topic we're covering that day. They're going to provide an overview of it, an example of it, so then we can all talk about it together. So if you read it, that's wonderful. You're a bit ahead and could even join the meeting like five minutes late. Or, if you haven't read it, then you could join and then get that update. So I'm very excited about it. And this was one of those books that I'd forgotten that thoughtbot had written, and it's one that I've never read. And it's public for anybody that's interested in it. So to cover a little bit of details about it, so it talks about code smells, ways to refactor code, and then also common patterns that you can use to solve some issues. So there's a lot of really just great content that's in it. And I'll be sure to include a link in the show notes for anyone else that's interested. CHRIS: And again, to reiterate, this book is free at this point. Previously, in the past, it was available for purchase. But at one point a number of years ago, thoughtbot set all of the books free. And so now that along with a handful of other books like...what's Edward's DNS book? Domain Name Sanity, I believe, is Edward's book name that Edward Loveall wrote when he was not a thoughtboter, [laughs] and then later joined as a thoughtboter, and then we made the book free. But on the specific topic of Ruby Science, that is a book that I will never forget. And the reason I will never forget it is that book was written by the one and only CTO Joe Ferris, who is an incredibly talented developer. And when I was interviewing with thoughtbot, I got down to the final day, which is a pairing session. You do a morning pairing session with one thoughtbot developer, and you do an afternoon pairing session with another thoughtbot developer. So in the morning, I was working with someone on actually a patch to Rails which was pretty cool. I'd never really done that, so that was exciting. And that went fine with the exception that I kept turning on Caps Lock on their keyboard because I was used to Caps Lock being CTRL, and then Vim was going real weird for me. But otherwise, that went really well. But then, in the afternoon, I was paired with the one and only CTO Joe Ferris, who was writing the book Ruby Science at that time. And the nature of the book is like, here's a code sample, and then here's that code sample improved, just a lot of sort of side-by-side comparisons of code. And I forget the exact way that this went, but I just remember being terrified because Joe would put some code up on the screen and be like, "What do you think?" And I was like, oh, is this the good code or the bad code? I feel like I should know. I do not know. I'm not sure. It worked out fine, I guess. I made it through. But I just remember being so terrified at that point. I was just like, oh no, this is how it ends for me. It's been a good run. STEPH: [laughs] CHRIS: I made it this far. I would have loved to work for this nice thoughtbot company, but here we are. But yeah, I made it through. [laughs] STEPH: There are so many layers to that too where it's like, well if I say it's terrible, are you going to be offended? Like, how's this going to go for me if I speak my truths? Or what am I going to miss? Yeah, that seems very interesting (I kind of like it.) but also a terrifying pairing session. CHRIS: I think it went well because I think the code...I'd been following thoughtbot's work, and I knew who Joe was and had heard him on podcasts and things. And I kind of knew roughly where things were, and I was like, that code looks messy. And so I think I mostly got it right, but just the openness of the question of like, what do you think? I was like, oh God. [laughs] So yeah, that book will always be in my memories, is how I would describe it. STEPH: Well, I'm glad it worked out so we could be here today recording a podcast together. [laughs] CHRIS: Recording a podcast together. Now that I say all that, though, it's been a long time since I've read the book. So maybe I'll take a revisit. And definitely interested to hear more about your book club and how that goes. But shifting ever so slightly (I don't have a lot to say on this topic.) but there's a new framework technology thing out there that has caught my attention. And this hasn't happened for a while, so it's kind of novel for me. So I tend to try and keep my eye on where is the sort of trend of web development going? And I found Inertia a while ago, and I've been very, very happy with that as sort of this is the default answer as to how I build websites. To be clear, Inertia is still the answer as to how I build websites. I love Inertia. I love what it represents. But I'm seeing some stuff that's really interesting that is different. Specifically, Remix.run is the thing that I'm seeing. I mentioned it, I think, in the last episode talking about there was some stuff that they were doing with data loading and async versus synchronous, and do you wait on it or? They had built some really nice levers and trade-offs into the framework. And there's a really great talk that Ryan Florence, one of the creators of Remix.run, gave about that and showed what they were building. I've been exploring it a little bit more in-depth now. And there is some really, really interesting stuff in Remix. In particular, it's a meta-framework, I think, is the nonsense phrase that we use to describe it. But it's built on top of React. That won't be true for forever. I think it's actually they would say it's more built on top of React Router. But it is very similar to Next.js for folks that have seen that. But it's got a little bit more thought around data loading. How do we change data? How do we revalidate data after? There's a ton of stuff that, having worked in many React client-side API-heavy apps that there's so much pain, cache invalidation. How do you think about the cache? When do you fetch from the network? How do you avoid showing 19 different loading spinners on the page? And Remix as a framework has some really, I think, robust and well-thought-out answers to a lot of that. So I am super-duper intrigued by what they're doing over there. There's a particular video that I think shows off what Remix represents really well. It's Ryan Florence, that same individual, the creator of Remix, building just a newsletter signup page. But he goes through like, let's start from the bare bones, simplest thing. It's just an input, and a form submits to the server. That's it. And so we're starting from web 2.0, long, long ago, sort of ideas, and then he gradually enhances it with animations and transitions and error states. And even at the end, goes through an accessibility audit using the screen reader to say, "Look, Remix helps you get really close because you're just using web fundamentals." But then goes a couple of steps further and actually makes it work really, really well for a screen reader. And, yeah, overall, I'm just super impressed by the project, really, really intrigued by the work that they're doing. And frankly, I see a couple of different projects that are sort of in this space. So yeah, again, very early but excited. STEPH: On their website...I'm checking it out as you're walking me through it, and on their website, they have "Say goodbye to Spinnageddon." And that's very cute. [laughs] CHRIS: There's some fundamental stuff that I think we've just kind of as a web community, we made some trade-offs that I personally really don't like. And that idea of just spinners everywhere just sending down a ball of application logic and a giant JavaScript file turning it on on someone's computer. And then immediately, it has to fetch back to the server. There are just trade-offs there that are not great. I love that Remix is sort of flipping that around. I will say, just to sort of couch the excitement that I'm expressing right now, that Remix exists in a certain place. It helps with building complex UIs. But it doesn't have anything in the data layer. So you have to bring your own data layer and figure out what that means. We have ActiveRecord within Rails, and it's deeply integrated. And so you would need to bring a Prisma or some other database connection or whatever it is. And it also doesn't have more sort of full-featured framework things. Like with Rails, it's very easy to get started with a background job system. Remix has no answer to that because they're like, no, no, this is what we're doing over here. But similarly, security is probably the one that concerns me the most. There's an open conversation in their discussion portal about CSRF protection and a back and forth of whether or not Remix should have that out of the box or not. And there are trade-offs because there are different adapters that you can use for auth. And each would require their own CSRF mitigation. But to me, that is the sort of thing that I would want a framework to have. Or I'd be interested in a framework that continues to build on top of Remix that adds in background jobs and databases and all that kind of stuff as a complete solution, something more akin to a Rails or a Laravel where it's like, here we go. This is everything. But again, having some of these more advanced concepts and patterns to build really, really delightful UIs without having to change out the fundamental way that you're building things. STEPH: Interesting. Yeah, I think you've answered a couple of questions that I had about it. I am curious as to how it fits into your current tech stack. So you've mentioned that you're excited and that it's helpful. But given that you already have Rails, and Inertia, and Svelte, does it plug and play with the other libraries or the other frameworks that you have? Are you going to have to replace something to then take advantage of Remix? What does that roadmap look like? CHRIS: Oh yeah, I don't expect to be using Remix anytime soon. I'm just keeping an eye on it. I think it would be a pretty fundamental shift because it ends up being the server layer. So it would replace Rails. It would replace the Inertia within the stack that I'm using. This is why as I started, I was like, Inertia is still my answer. Because Inertia integrates really well with Rails and allows me to do the sort of it's not progressive enhancement, but it's like, I want fancy UI, and I don't want to give up on Rails. And so, Inertia is a great answer for that. Remix does not quite fit in the same way. Remix will own all of the request-response lifecycle. And so, if I were to use it, I would need to build out the rest of that myself. So I would need to figure out the data layer. I would need to figure out other things. I wouldn't be using Rails. I'm sure there's a way to shoehorn the technologies together, but I think it sort of architecturally would be misaligned. And so my sense is that folks out there are building...they're sort of piecing together parts of the stack to fill out the rest. And Remix is a really fantastic controller and view from their down experience and routing layer. So it's routing, controller, view I would say Remix has a really great answer to, but it doesn't have as much of the other stuff. Whereas in my case, Inertia and Rails come together and give me a great answer to the whole story. STEPH: Got it. Okay, that's super helpful. CHRIS: But yeah, again, I'm in very much the exploratory phase. I'm super intrigued by a lot of what I've seen of it and also just sort of the mindset, the ethos of the project as it were. That sounds fancy as I say it, but it's what I mean. I think they want to build from web fundamentals and then enhance the experience on top of that, and I think that's a really great way to go. It means that links will work. It means that routing and URLs will work by default. It means that you won't have loading spinner Armageddon, and these are core fundamentals that I believe make for good websites and web applications. So super interested to see where they go with it. But again, for me, I'm still very much in the Rails Inertia camp. Certainly, I mean, I've built Sagewell on top of it, so I'm going to be hanging out with it for a while, but also, it would still be my answer if I were starting something new right now. I'm just really intrigued by there's a new example out there in the world, this Remix thing that's pushing the envelope in a way that I think is really great. But with that, my now…what was that? My second or my third rave? Also called the positive rant, as we call it. But yeah, I think on that note, what do you think? Should we wrap up? STEPH: Let's wrap up. CHRIS: The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Nuno Maduro's Twitter - https://twitter.com/enunomaduroSponsor Nuno Maduro - https://github.com/sponsors/nunomaduroPest - https://pestphp.comPest Discord Server - https://discord.com/invite/bMAJv82Perl - https://www.perl.org/Parallel Plugin - https://pestphp.com/docs/plugins/parallelPHPUnit - https://phpunit.de/Jest - https://jestjs.io/Livewire - https://laravel-livewire.com/Watch Plugin - https://pestphp.com/docs/plugins/watchRetry Plugin - https://docs.php-http.org/en/latest/plugins/retry.htmlDatasets - https://pestphp.com/docs/datasets#datasetsOliver Nybroe's Twitter - https://twitter.com/olivernybroe?lang=enOliver Nybroe's GitHub - https://github.com/olivernybroeOwen Voke's Twitter - https://twitter.com/owenvokeOwen Voke's GitHub - https://github.com/owenvokeLuke Downing's Twitter - https://twitter.com/LukeDowning19Luke Downing's GitHub - https://github.com/lukeraymonddowningFreek Van der Herten's Twitter - https://twitter.com/freekmurzeFreek Van der Herten's Blog - https://freek.dev
Steph and Chris are recording together! Like, in the same room, physically together. Chris talks about slowly evolving the architecture in an app they're working on and settling on directory structure. Steph's still working on migrating unit tests over to RSpec. They answer a listener question: "As senior-level developers, how do you set goals to ensure that you keep growing?" This episode is brought to you by BuildPulse (https://buildpulse.io/bikeshed). Start your 14-day free trial of BuildPulse today. Faking External Services In Tests With Adapters (https://thoughtbot.com/blog/faking-external-services-in-tests-with-adapters) Testing Third-Party Interactions (https://thoughtbot.com/blog/testing-third-party-interactions) Jen Dary - On Future Goals (https://www.beplucky.com/on-future-goals/) Charity Majors - The Engineer Manager Pedulum (https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/) Charity Majors Bike Shed Episode (https://www.bikeshed.fm/302) Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. So, hey, Chris, what's new in your world? CHRIS: What is new in my world? Actually, this episode feels different. There's something different about it. I can't quite put my finger on it. I think it may be that we're actually physically in the same room recording for the first time in two years and a little bit more, which is wild. STEPH: I can't believe it's been that long. I feel like it wasn't that long ago that we were in The Bike Shed...oh, I said The Bike Shed studio. I'm being very biased. Our recording studio [laughs] is the more proper description for it. Yeah, two and a half years. And we tried to make this happen a couple of months ago when I was visiting Boston, and then it just didn't work out. But today, we made it. CHRIS: Today, we made it. Here we are. So hopefully, the audio sounds great, and we get all that more richness in conversation because of the physical in-person manner. We're trying it out. It'll be fun. But let's see, to the normal tech talk and nonsense, what's new in my world? So we've been slowly evolving the architecture in the app that we're working on. And we settled on something that I kind of like, so I wanted to talk about it, directory structure, probably the most interesting topic in the world. I think there's some good stuff in here. So we have the normal stuff. There are app models, app controllers, all those; those make sense. We have app jobs which right now, I would say, is in a state of flux. We're in the sad place where some things are application records, and some things are Sidekiq workers. We have made the decision to consolidate everything onto Sidekiq workers, which is just strictly more powerful as to the direction we're going to go. But for right now, I'm not super happy with the state of app jobs, but whatever, we have that. But the things that I like so we have app commands; I've talked about app commands before. Those are command objects. They use dry-rb do notation, and they allow us to sequence a bunch of things that all may fail, and we can process them all in a much more reasonable way. It's been really interesting exploring that, building on it, introducing it to new developers who haven't worked in that mode before. And everyone who's come into the project has both picked it up very quickly and enjoyed it, and found it to be a nice expressive mode. So app commands very happy with that. App queries is another one that we have. We've talked about this before, query objects. I know we're a big fan. [laughs] I got a golf clap across the room here, which I could see live in person. It was amazing. I could feel the wind wafting across the room from the golf clap. [chuckles] But yeah, query objects, they're fantastic. They take a relation, they return a relation, but they allow us to build more complex queries outside of our models. The new one, here we go. So this stuff would all normally fall into app services, which services don't mean anything. So we do not have an app services directory in our application. But the new one that we have is app clients. So these are all of our HTTP clients wrapping external third parties that we're interacting with. But with each of them, we've taken a particular structure, a particular approach. So for each of them, we're using the adapter pattern. There's a blog post on the Giant Robots blog that I can point to that sort of speaks to the adapter pattern that we're using here. But basically, in production mode, there is an HTTP backend that actually makes the real requests and does all that stuff. And in test mode, there is a test backend for each of these clients that allows us to build up a pretty representative fake, and so we're faking it up before the HTTP layer. But we found that that's a good trade-off for us. And then we can say, like, if this fake backend gets a request to /users, then we can respond in whatever way that we want. And overall, we found that pattern to be really fantastic. We've been very happy with it. So it's one more thing. All of them were just gathering in-app models. And so it was only very recently that we said no, no, these deserve their own name. They are a pattern. We've repeated this pattern a bunch. We like this pattern. We want to even embrace this pattern more, so long live app clients. STEPH: I love it. I love app clients. It's been a while since I've been on a project that had that directory. But there was a greenfield project that I was working on. I think it might have been I was working with Boston.rb and working on giving them a new site or something like that and introduced app clients. And what you just said is perfect in terms of you've identified a pattern, and then you captured that and gave it its own directory to say, "Hey, this is our pattern. We've established it, and we really like it." That sounds awesome. It's also really nice as someone who's new to a codebase; if I jump in and if I look at app clients, I can immediately see what are the third parties that we're working with? And that feels really nice. So yeah, that sounds great. I'm into it. CHRIS: Yeah, I think it really was the question of like, is this a pattern we want to embrace and highlight within the codebase, or is this sort of a duplication but irrelevant like not really that important? And we decided no, this is a thing that matters. We currently have 17 of these clients, so 17 different third-party external things that we're integrating with. So for someone who doesn't really like service-oriented architecture, I do seem to have found myself in a place. But here we are, you know, we do what we have to with what we're given. But yes, 17 and growing our app clients. STEPH: That is a lot. [laughs] My eyes widened a bit when you said 17. I'm curious because you highlighted that app services that's not really a thing. Like, it doesn't mean anything. It doesn't have the same meaning of the app queries directory or app commands or app clients where it's like, this is a pattern we've identified, and named, and want to propagate. For app services, I agree; it's that junk drawer. But I guess in some ways...well, I'm going to say something, and then I'm going to decide how I feel about it. That feels useful because then, if you have something but you haven't established a pattern for it, you need a place for it to go. It still needs to live somewhere. And you don't necessarily want to put it in app models. So I'm curious, where do you put stuff that doesn't have an established pattern yet? CHRIS: It's a good question. I think it's probably app models is our current answer. Like, these are things that model stuff. And I'm a big believer in the it doesn't need to be an application record-backed object to go on app models. But slowly, we've been taking stuff out. I think it'd be very common for what we talk about as query objects to just be methods in the respective application record. So the user record, as a great example, has all of these methods for doing any sort of query that you might want to do. And I'm a fan of extracting that out into this very specific place called app queries. Commands are now another thing that I think very typically would fall into the app services place. Jobs naming that is something different. Clients we've got serializers is another one that we have at the top level, so those are four. We use Blueprinter within the app. And again, it's sort of weird. We don't really have an API. We're using Inertia. So we are still serializing to JSON across the boundary. And we found it was useful to encapsulate that. And so we have serializers as a directory, but they just do that. We do have policies. We're using Pundit for authorization, so that's another one that we have. But yeah, I think the junk drawerness probably most goes to app models. But at this point, more and more, I feel like we have a place to put things. It's relatively clear should this be in a controller, or should this be in a query object, or should this be in a command? I think I'm finding a place of happiness that, frankly, I've been searching for for a long time. You could say my whole life I've been searching for this contented state of I think I know where stuff goes in the app, mostly, most of the time. I'm just going to say this, and now that you've asked the excellent question of like, yeah, but no, where are you hiding some stuff? I'm going to open up models. Next week I'm going to be like, oh, I forgot about all of that nonsense. But the things that we have defined I'm very happy with. STEPH: That feels really fair for app models. Because like you said, I agree that it doesn't need to be ActiveRecord-backed to go on app models. And so, if it needs to live somewhere, do you add a junk drawer, or do you just create app models and reuse that? And I think it makes a lot of sense to repurpose app models or to let things slide in there until you can extract them and let them live there until there's a pattern that you see. CHRIS: We do. There's one more that I find hilarious, which is app lib, which my understanding...I remember at one point having one of those afternoons where I'm just like, I thought stuff works, but stuff doesn't seem to work. I thought lib was a directory in Rails apps. And it was like, oh no, now we autoload only under the app. So you should put lib under app. And I was just like, okay, whatever. So we have app lib with very little in it. [laughs] But that isn't so much a junk drawer as it is stuff that's like, this doesn't feel specific to us. This goes somewhere else. This could be extracted from the app. But I just find it funny that we have an app lib. It just seems wrong. STEPH: That feels like one of those directories that I've just accepted. Like, it's everywhere. It's like in all the apps that I work in. And so I've become very accustomed to it, and I haven't given it the same thoughtfulness that I think you have. I'm just like, yeah, it's another place to look. It's another place to go find some stuff. And then if I'm adding to it, yeah, I don't think I've been as thoughtful about it. But that makes sense that it's kind of silly that we have it, and that becomes like the junk drawer. If you're not careful with it, that's where you stick things. CHRIS: I appreciate you're describing my point of view as thoughtfulness. I feel like I may actually be burdened with historical knowledge here because I worked on Rails apps long, long ago when lib didn't go in-app, and now it does. And I'm like, wait a minute, but like, no, no, it's fine. These are the libraries within your app. I can tell that story. So, again, thank you for saying that I was being thoughtful. I think I was just being persnickety, and get off my lawn is probably where I was at. STEPH: Oh, full persnicketiness. Ooh, that's tough to say. [laughs] CHRIS: But yeah, I just wanted to share that little summary, particularly the app clients is an interesting one. And again, I'll share the adapter pattern blog post because I think it's worked really well for us. And it's allowed us to slowly build up a more robust test suite. And so now our feature specs do a very good job of simulating the reality of the world while also dealing with the fact that we have these 17 external situations that we have to interact with. And so, how do you balance that VCR versus other things? We've talked about this a bunch of times on different episodes. But app clients has worked great with the adapter pattern, so once more, rounding out our organizational approach. But yeah, that's what's up in my world. What's up in your world? STEPH: So I have a small update to give. But before I do, you just made me think of something in regards to that article that talks about the adapter pattern. And there's also another article that's by Joël Quenneville that's testing third-party interactions. And he made me reflect on a time where I was giving the RSpec course, and we were talking about different ways to test third-party interactions. And there are a couple of different ways that are mentioned in this article. There are stub methods on adapter, stub HTTP request, stub request to fake adapter, and stub HTTP request to fake service. All that sounds like a lot. But if you read through the article, then it gives an example of each one. But I've found it really helpful that if you're in a space that you still don't feel great about testing third-party interactions and you're not sure which approach to take; if you work with one API and apply all four different strategies, it really helps cement how to work through that process and the different benefits of each approach and the trade-offs. And we did that during the RSpec course, and I found it really helpful just from the teacher perspective to go through each one. And there were some great questions and discussions that came out of it. So I wanted to put that plug out there in the world that if you're struggling testing third-party interactions, we'll include a link to this article. But I think that's a really solid way to build a great foundation of, like, I know how to test a third-party app. Let me choose which strategy that I want to use. Circling back to what's going on in my world, I am still working on migrating unit tests over to RSpec. It's a thing. It's part of the work that I do. [laughs] I can't say it's particularly enjoyable, but it will have a positive payoff. And along that journey, I've learned some things or rediscovered some things. One of them is read expectations very carefully. So when I was migrating a test over to RSpec, I read it as where we expected a record to exist. The test was actually testing that a record did not exist. And so I probably spent an hour understanding, going through the code being like, why isn't this record getting created like I expect it to? And I finally went back, and I took a break, and I went back. And I was like, oh, crap, I read the expectation wrong. So read expectations very carefully. The other one...this one's not learned, but it is reinforced. Mystery Guests are awful. So as I've been porting over the behavior over to RSpec, the other tests are using fixtures, and I'm moving that over to use factorybot instead. And at first, I was trying to be minimal with the data that I was bringing over. That failed pretty spectacularly. So I have learned now that I have to go and copy everything that's in the fixtures, and then I move it over to factorybot. And it's painful, but at least then I'm doing that thing that we talked about before where I'm trying to load as little context as possible for each test. But then once I do have a green test, I'm going back through it, and I'm like, okay, we probably don't care about when you were created. We probably don't care when you're updated because every field is set for every single record. So I am going back and then playing a game of if I remove this line, does the test still pass? And if I remove that line, does the test still pass? And so far, that has been painful, but it does have the benefit of then I'm removing some of the setup. So Mystery Guests are very painful. I've also discovered that custom error messages can be tricky because I brought over some tests. And some of these, I'm realizing, are more user error than anything else. Anywho, I added one of the custom error messages that you can add, and I added it over to RSpec. But I had written an incorrect, invalid statement in RSpec where I was looking...I was expecting for a record to exist. But I was using the find by instead of where. So you can call exist on the ActiveRecord relation but not on the actual record that gets returned. But I had the custom error message that was popping up and saying, "Oh, your record wasn't found," and I just kept getting that. So I was then diving through the code to understand again why my record wasn't found. And once I removed that custom error message, I realized that it was actually because of how I'd written the RSpec assertion that was wrong because then RSpec gave me a wonderful message that was like, hey, you're trying to call exist on this record, and you can't do that. Instead, you need to call it on a relation. So I've also learned don't bring over custom error messages until you have a green test, and even then, consider if it's helpful because, frankly, the custom error message wasn't that helpful. It was very similar to what RSpec was going to tell us in general. So there was really no need to add that custom step to it. For the final bit that I've learned or the hurdle that I've been facing is that migrating tests descriptions are hard unless they map over. So RSpec has the context and then a description for it that goes with the test. Test::Unit has methods like method names instead. So it may be something like test redemption codes, and then it runs through the code. Well, as I'm trying to migrate that knowledge over to RSpec, it's not clear to me what we're testing. Okay, we're testing redemption codes. What about them? Should they pass? Should they fail? Should they change? What are they redeeming? There's very little context. So a lot of my tests are copying that method name, so I know which tests I'm focused on, and I'm bringing over. And then in the description, it's like, Steph needs help adding a test description, and then I'm pushing that up and then going to the team for help. So they can help me look through to understand, like, what is it that this test is doing? What's important about this domain? What sort of terminology should I include? And that has been working, but I didn't see that coming as part of this whole migrating stuff over. I really thought this might be a little bit more of a copypasta job. And I have learned some trickery is afoot. And it's been more complicated than I thought it was going to be. CHRIS: Well, at a minimum, I can say thank you for sharing all of your hard-learned lessons throughout this process. This does sound arduous, but hopefully, at the end of it, there will be a lot of value and a cleaned-up test suite and all of those sorts of things. But yeah, it's been an adventure you've been on. So on behalf of the people who you are sharing all of these things with, thank you. STEPH: Well, thank you. Yeah, I'm hoping this is very niche knowledge that there aren't many people in the world that are doing this exact work that this happens to be what this team needs. So yeah, it's been an adventure. I've certainly learned some things from it, and I still have more to go. So not there yet, but I'm also excited for when we can actually then delete this portion of the build process. And then also, I think, get rid of fixtures because I didn't think about that from the beginning either. But now that I'm realizing that's how those tests are working, I suspect we'll be able to delete those. And that'll be really nice because now we also have another single source of truth in factory_bot as to how valid records are being built. Mid-Roll Ad: Flaky tests take the joy out of programming. You push up some code, wait for the tests to run, and the build fails because of a test that has nothing to do with your change. So you click rebuild, and you wait. Again. And you hope you're lucky enough to get a passing build this time. Flaky tests slow everyone down, break your flow and make things downright miserable. In a perfect world, tests would only break if there's a legitimate problem that would impact production. They'd fail immediately and consistently, not intermittently. But the world's not perfect, and flaky tests will happen, and you don't have time to fix them all today. So how do you know where to start? BuildPulse automatically detects and tracks your team's flaky tests. Better still, it pinpoints the ones that are disrupting your team the most. With this list of top offenders, you'll know exactly where to focus your effort for maximum impact on making your builds more stable. In fact, the team at Codecademy was able to identify their flakiest tests with BuildPulse in just a few days. By focusing on those tests first, they reduced their flaky builds by more than 68% in less than a month! And you can do the same because BuildPulse integrates with the tools you're already using. It supports all the major CI systems, including CircleCI, GitHub Actions, Jenkins, and others. And it analyzes test results for all popular test frameworks and programming languages, like RSpec, Jest, Go, pytest, PHPUnit, and more. So stop letting flaky tests slow you down. Start your 14-day free trial of BuildPulse today. To learn more, visit buildpulse.io/ bikeshed. That's buildpulse.io/bikeshed. Pivoting just a bit, there's a listener question that I'm really excited for us to dive into. And this listener question comes from Joël Quenneville. Hey, Joël. All right, so Joël writes in, "As senior-level developers, how do you set goals to ensure that you keep growing? How do you know what are high-value areas for you to improve? How do you stay sharp? Do you just keep adding new languages to your tool belt? Do you pull back and try to dig into more theoretical concepts? Do you feel like you have enough tech skills and pivot to other things like communication or management skills? At the start of a dev career, there's an overwhelming list of things that it feels like you need to know all at once. Eventually, there comes a point where you no longer feel like you're drowning under the list of things that you need to learn. You're at least moderately competent in all the core concepts. So what's next?" This is a big, fun, scary question. I really like this question. Thank you, Joël, for sending it in because I think there's so much here that can be discussed. I can kick us off with a few thoughts. I want to first highlight one of the things that...or one of the things that resonates with me from this question is how Joël describes going through and reaching senior status how it can really feel like working through a backlog of features. So as a developer, I want to understand this particular framework, or as a developer, I want to be able to write clear and fast tests, or as a developer, I want to contribute to an open-source project. But now that that backlog is empty, you're wondering what's next on your roadmap, which is where I think that sort of big, fun scariness comes into play. So the first idea is to take a moment and embrace that success. You have probably worked really hard to get where you're at in your career. And there's nothing wrong with taking a pause and enjoying the view and just being appreciative of the fact that you are able to get your work done quickly or that you feel very confident in the work that you're doing. Growth is often very important to our careers, but I also think it's important to recognize when you've achieved certain growth and then, if you want to, just enjoy that and pause. And you're not constantly pushing yourself to the next level. I think that is a totally reasonable and healthy thing to do. The second thing that comes to mind is that you're on a Choose Your Own Adventure mode now, so you get to...I would encourage folks, once you've reached this stage, to reflect on where you're at and consider what is your dream? What are your aspirations? Maybe they're related to tech; maybe they're not. And consider where is it that you want to go next? And then, what are the concrete steps that will help you achieve those goals? So there's a really great article by Jen Dary, who's a career coach and owner of Plucky Manager Training, that describes this process. And there's a really great blog post that I'll be sure to include a link to in the show notes. But she has a couple of great questions that will then help you identify, like, what are my goals? Some of those questions are, "If I could do anything and money wasn't an object, I'd spend my time doing dot dot dot." And that doesn't necessarily mean sitting on a beach with your toes in the sand all day. I mean, it could, but then that probably just means you need a vacation. So take the vacation. And then, once you start to get bored, where does your mind start to wander? What are the things that you want to do? Where are you interested in spending your time? And then, once you have an idea of how you'd like to spend your time, you can consider what actions you could take next that will point you in that direction. There's also the benefit that by this point, you probably have an idea of the type of things that you like to do and where you like to spend your time. And so you can figure out which areas of expertise you want to invest in. So do you like more greenfield projects? Do you like architecture discussions? Do you like giving talks? Do you like teaching? Or maybe you're interested in management. I think there's also a more concrete approach that you can take that. You can just talk to your managers in your team and say, "Hey, what big, hard problems are you looking to solve? And then, you can get some inspiration from them and see if their problems align with your interests. Maybe it's not even your own team, but you can talk to other companies and see what other problems industries are trying to solve. That might be an area that then spurs some curiosity or some interest. And then, where do you feel underutilized? So with your current day-to-day, are there areas where you feel that you wish you had more responsibilities or more opportunities, but you feel like you don't have access to those opportunities? Maybe that's an area to explore as well. This feels like a wonderful coaching question in terms of you have done it; congratulations. You've reached a really great spot in your career. And so now you're figuring out that big next step. This is going to be highly customized to each person to then figuring out what it is that's going to help you feel fulfilled over the next five years, ten years, however long you want to project out. Those are some of my thoughts. How about you? What do you think? CHRIS: Well, first, those are some great thoughts. I appreciate that I get to follow them now. It's going to be a hard act to follow. But yeah, I think Joël has asked a fantastic question. And coming from Joël, I know how intentional and thoughtful a learner, and sharer, and teacher and all of these things are. So it's all the more sort of framed in that for me knowing Joël personally. I think to start, the kernel of the question is as senior developers, that's the like...or senior level developers is the way Joël phrased it, but it treats it as sort of this discrete moment in time, which I think there's maybe even something to unpack. And I think we've probably talked about this in previous episodes, but like, what does that even mean? And I think part of the story here is going from reactive where it's like, I don't know how anything works. I know a little bit. I can code some. And every day, I'm presented with new problems that I just don't understand. And I'm trying to build up that base of knowledge. Slowly, you know, you start, and it's like 95% of the time you feel like that. And slowly, the dial switches over, and maybe it's only 25% of the time you feel like that. Somewhere along that spectrum is the line of senior developer. I don't actually know where it is, but it's somewhere in there. And so I think it's that space where you can move from reactive learning things as necessitated by the work that's coming at you to I want to proactively choose the things that I want to be learning to try and expand the stuff that I know, and the ways that I can think about the work without being in direct response to a piece of work coming at me. So with that in mind, what do you do with this proactive space? And I think the way Joël frames the question, again, to what I know of Joël, he's such an intentional person. And I wouldn't be surprised if Joël is very purposeful and thinks about this and has approached it as a specific thing that he's doing. I have certainly been in more of “I'll figure it out when I get there.” I'll explore. Or actually, probably the most pointed thing that I did was I joined a consultancy. And that was a very purposeful choice early on in my career because I'm like, I think I know a little bit. I don't think I know a lot. I would like to know a lot. That seems fun. So what do I think is the best way to do that? My guess, and it turned out to be very much true, is if I join a consultancy, I'm going to see a bunch of different projects, different types of technologies, organizations, communication structure, stuff that works, stuff that doesn't work. And to be honest, I actually thought I would try out the consultancy thing for a little while, like a year or two, and then go on to my next adventure. Spoiler alert: I stayed for seven years. It was one of the best periods of my professional life. And I found it to be a much deeper well than I expected it to be. But for anyone that's looking for, like, how can I structure my career in a way that will just automatically provide the sort of novelty and space to grow? I would highly recommend a consultancy like thoughtbot. I wonder if they're hiring. STEPH: Well, yes, we are hiring. That was a perfect plug that I wasn't expecting for that to come. But yes, thoughtbot is totally hiring. We'll include a link in the show notes to all the jobs. [laughs] CHRIS: Sounds fantastic. But very sincerely, that was the best choice that I could have made and was a way to flip the situation around such that I don't have to be thinking about what I want to be learning. The learning will come to me. But even within that, I still tried to be intentional from time to time. And I would say, again, I don't have a holistic theory of how to improve. I just have some stuff that's kind of worked out well. One thing is focusing on fundamentals wherever I can, or a different way to put it is giving myself permission to spend a little bit more time whenever my work brushes up against what I would consider fundamentals. So things that are in that space are like SQL. Every time I'm working on something, I'm like, ah, I could use like a CROSS JOIN here, but I don't know what that is. Maybe I'll spend an extra 30 minutes Googling around and trying to figure out what a CROSS JOIN is. Is that a thing? Is a CROSS JOIN a real thing? I may be making it up. [laughs] A window function, I know that those are real. Maybe I'll learn what a window function is. I think a CROSS JOIN is a real thing. A LEFT OUTER JOIN that's a cool thing. And so, each time I've had that, SQL has been something that expanding my knowledge; I've continually felt like that was a good investment. Or fundamentals of HTTP, that's another one that really has served me well. With Ruby being the primary language that I program in, deeply understanding the language and the fundamentals and the semantics of it that's another place that has been a good investment. But by contrast, I would say I probably haven't gone as deep on the frameworks that I work with. So Rails is maybe a little bit different just because, like many people, I came to Ruby through Rails, and I've learned a lot of Rails. But like in JavaScript, I've worked with many different JavaScript frameworks. And I have been a little more intentional with how much time I invest into furthering my skills in them because I've seen them change and evolve enough times. And if anything, I'm trying to look for ones that are like, what if it's less about the framework and more about JavaScript and web fundamentals underneath? Thus, I've found myself in Svelte land. But I think it's that choice of trying to anchor to fundamentals wherever possible. And then I would say the other thing that's been really beneficial for me is what can I do that's wildly outside the stuff that I already know? And so probably the most pointed example I have of this is learning Elm. So I previously spent most of my career working in Ruby and JavaScript, so primarily object-oriented languages without a strong type system. And then, I was able to go over and experience this whole different paradigm way of working, way of structuring programs, feedback loop. There was so much about it that was really, really interesting. And even though I don't get to work in Elm, frankly, as much as I would want at this point or really at all, it informs everything that I do moving forward. And I think that falls out of the fact that it was so different than what I was doing. So if I were to do that again, probably the next type of language I would learn is Lisp because those are like, well, that's a whole other category of thing that I've heard about. People say some fun stuff about them, but I don't really know. So it's that fundamentals and weird stuff is how I would describe it. And by weird, I mean outside of the core base of knowledge that I have. STEPH: I love that categorization, and I'll stick with it, fundamentals and weird stuff, to stretch and grow and find some other areas. I also really like your framing, the reactive versus proactive. I think that's a really nice way to put it because so much of your career is you are just learning what your company needs you to learn, or you're learning what you need to keep progressing and to feel more competent with the types of features or the work that you're handling. And I think that's why Jen Dary's blog post resonates with me so much because it's probably...up until now, a lot of someone's career, maybe not Joël's particularly, but I know probably for my career, a lot of it has been reactive in terms of what are the things that I need to learn? And so then once you reach that point of like, okay, I feel competent and reasonably good at all the things that I needed to know, where do I want to go next? And rather than focus on necessarily the plans that are laid out in front of me, I can then go wide and think about what are some of the bigger things that I want to tackle? What are the things that are meaningful to me? Because then I can now push forward to this bigger goal versus achieving a particular salary band or title or things like that. But I can focus on something else that I really want to contribute to. And there do seem to be two common paths. So once you reach that level, either you typically go into management, or you become that more like principal and then onward and upward, whatever is after principal. I don't even know what's after that, [laughs] but the titles that come after principal. So there's management, and then I've seen the other very strong contributors, so Aaron Patterson comes to mind. And I feel like those people then typically will migrate to places where they get to contribute to a language or to a framework. And I think it comes down to the idea of impact because both of those provide a greater impact. So if you go into management, you can influence and affect a team of individuals, and you can increase the value created by that team. Then you've likely exceeded the value that you would have created as your own individual contributor. Or, if you contribute to a language or a framework, then your technical decisions impact a larger community. So I think that would be another good thing to reflect on is what type of impact am I looking for? What type of communities do I want to have a positive impact on? And that may spur some inspiration around where you want to go next, the things that you want to focus on. CHRIS: Yeah, I think one of the things we're picking up in that that Joël mentioned in his question is the idea of there is the individual contributor path. But then there's also the management path, which is the typical sort of that's the progression. And I think, for one, naming that the individual contributor path and the idea of going to principal dev and those sorts of outcomes is a fantastic path in and of itself. I think often it's like, well, you know, you go along for a certain amount of time, and then you become a manager. It's like, those are actually distinctly different things. And people have different levels of interest and aptitude in them, and I think recognizing that is critically important. And so, not expecting that management just comes after individual contributor is an important thing. The other thing I'll say is Charity Majors, who we had on the podcast a bit back, has a wonderful blog post about the pendulum swing called The Engineer/Manager Pendulum. And so in it, she talks about folks that have taken an exploration over into manager land and then come back to the individual contributor path or vice versa sort of being able to move between them, treating them as two potentially parallel career tracks but ones that we can move between. And her assertion is that often folks that are particularly strong have spent some time in both camps because then you gain this empathy, this understanding of what's the whole picture? How are we doing all of this? How do we think about communication, et cetera? So, again, to name it, like, I think it's totally fine to stay on one of those tracks to really know which of those tracks speaks to you or to even move between them a little bit and to explore it and to find out what's true. So we'll include a link to that in the show notes. And we'll also include a link to the previous episode a while back when we had Charity on. But yeah, those I think are some critical thoughts as well because those are different areas that we can grow as developers and expand on our impact within the team. And so, we want to make sure we have those options on the table as well. STEPH: Absolutely. I love where teams will support individuals to feel comfortable shifting between experiences like that because it does make you a more well-rounded contributor to that product team, not just as an engineer, but then you will also understand what everybody else is working on and be able to have more meaningful conversations with them about the company goals and then the type of work that's being done. So yeah, I love it. If you're in a place that you can maybe fail a little bit, hopefully not in a too painful way, but you can take a risk and say, "Hey, I want to try something and see if I like it," then I think that's wonderful. And take the risk and see how it goes. And just know that you have an exit strategy should you decide that you don't like that work or that type of work isn't for you. But at least now you know a little bit more about yourself. Overall, I want to respond directly to something that Joël highlighted around how do you know what are high-value areas for you to improve? And I think there are two definitions there because you can either let the people around you and your team define that high value for you, and maybe that really resonates with you, and it's something that you enjoy. And so you can go to your manager and say, "Hey, what are some high-value areas where I can make an impact for the team?" Or it could be very personal. And what are the high-value areas for you? Maybe there's a particular industry that you want to work on. Maybe you want to hit the public speaking circuit. And so you define more intrinsically what are those high-value areas for you? And I think that's a good place to start collecting feedback and start looking at what's high value for you personally and then what's high value to the company and see if there's any overlap there. With that, I think we've covered a good variety of things to explore and then highlighted some of the different ways that you and I have also considered this question. I think it's a fabulous question. Also, I think it's one, even if you're not at that senior level, to ask this question. Like, go ahead and start asking it early and often and revisit your answers and see how they change. I think that would be a really powerful habit to establish early in your career and then could help guide you along, and then you can reflect on some of your earlier choices. So, Joël, thank you so much for that question. STEPH: On that note, shall we wrap up? CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Chris switched from Trello over to Linear for product management and talks about prioritizing backlogs. Steph shares and discusses a tweet from Curtis Einsmann that super resonated with the work she's doing right now: "In software engineering, rabbit holes are inevitable. You will research libraries and not use them. You'll write code just to delete it. This isn't a waste; sometimes, you need to go down a few wrong paths to get to the right one." This episode is brought to you by BuildPulse (https://buildpulse.io/bikeshed). Start your 14-day free trial of BuildPulse today. Linear (https://linear.app/) Curtis Einsmann Tweet (https://twitter.com/curtiseinsmann/status/1521451508943843329) Louie Bacaj Tweet (https://twitter.com/LBacaj/status/1478241322637033474?s=20) Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: AD: Flaky tests take the joy out of programming. You push up some code, wait for the tests to run, and the build fails because of a test that has nothing to do with your change. So you click rebuild and you wait. Again. And you hope you're lucky enough to get a passing build this time. Flaky tests slow everyone down, break your flow and make things downright miserable. In a perfect world, tests would only break if there's a legitimate problem that would impact production. They'd fail immediately and consistently, not intermittently. But the world's not perfect, and flaky tests will happen, and you don't have time to fix them all today. So how do you know where to start? BuildPulse automatically detects and tracks your team's flaky tests. Better still, it pinpoints the ones that are disrupting your team the most. With this list of top offenders, you'll know exactly where to focus your effort for maximum impact on making your builds more stable. In fact, the team at Codecademy was able to identify their flakiest tests with BuildPulse in just a few days. By focusing on those tests first, they reduced their flaky builds by more than 68% in less than a month! And you can do the same because BuildPulse integrates with the tools you're already using. It supports all the major CI systems, including CircleCI, GitHub Actions, Jenkins, and others. And it analyzes test results for all popular test frameworks and programming languages, like RSpec, Jest, Go, pytest, PHPUnit, and more. So stop letting flaky tests slow you down. Start your 14-day free trial of BuildPulse today. To learn more, visit buildpulse.io/bikeshed. That's buildpulse.io/bikeshed. CHRIS: Good morning, and welcome to Tech Talk with Steph and Chris. Today at the top of the hour, it's tech traffic hits. STEPH: Ooh, tech traffic. [laughs] I like that statement. CHRIS: Yeah. The Git lanes are clogged up with...I don't know. I got nothing. STEPH: [laughs] Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. So, hey, Chris, what's new in your world? CHRIS: What's new in my world? Actually, I have a specific new thing that I can share, which is, as of the past week, I would say, switched from Trello over to Linear for product management. It's been great. It was a super straightforward transfer. They actually had an importer. We lost some of the comment threads on the Trello cards. But that was easy enough to like each Linear ticket has a link back to Trello. So it's easy enough to keep the continuity. But yeah, we're in a whole new world, a system actually built for maintaining a product backlog, and, man, it shows. Trello was a bunch of lists and cards and stuff that you could link between, which was cool. But Linear is just much more purpose-built and already very, very nice. And we're very happy with the switch. STEPH: I feel like you came in real casual with that news, but that is big news, that you did a switch. [laughter] CHRIS: How are you going to bury the lead like that? You switched project management...[laughter] I actually didn't think it was...I'm excited about it but low-key excited, which is weird because I do like productivity and task management software. So you would think I would be really excited about this. But I've also tried enough of them historically to know that that's never going to be the thing that actually makes or breaks your team's productivity. It can make things worse, but it can't make you great. That's the thing that I believe. And so it's a wonderful piece of software. I'm very excited about it but -- STEPH: Ooh, I like that. It can make you worse, but it doesn't make you great. That's so true, yeah, where it causes pain. Well, and it does make sense. You've been complaining a bit about the whole login with Trello and how that's been frustrating. But I haven't even heard of Linear. That's just...that's, I mean, you're just doing what you do where you bring that new-new. I haven't heard of Linear before. CHRIS: I try to live on the cutting edge. Actually, I deeply try to not live on the cutting edge at this point in my life. That early adopter wave, no, no, no, that's not for me anymore. But I've known a few folks who've moved to Linear. And everyone that I've spoken to who has moved to it has been like, "Yeah, it's been great." I've not heard anything negative. And I've heard or experienced negative things about every other product management tool out there. And so, it seemed like an easy thing. And it was a low-cost enough switch in terms of opportunity costs or the like, it took the effort of someone on our team moving those cards over and setting up the new system and training, but it was relatively straightforward. And yeah, we're super happy with it. And it feels different now. I feel like I can see the work in a different way which is interesting. I think we had brought in a Chrome extension for Trello. I think it's like Hello Epics or something like that that allows...it abuses the card linking functionality in Trello and repurchases that feature as an epic management thing. But it's quarter-baked is how I would describe it, or it's clearly built on top of existing things that were not intended to be used exactly in that way. So it does a great job. Hello Epics does a great job of trying to make something like parent-child list management stuff happen in Trello. But it's always going feel like an afterthought, a secondary feature, something that's bolted on. Whereas in Linear, it's like, no, no, we absolutely have the idea of projects, of course, and you can see burndown charts and things. And the thing that I do want to be careful about is not leaning too much into management. Linear has the idea of cycles or sprints, as many other folks think of them, or iterations or whatever you want to call them. But we've largely not been working in that mode. We've just continued to work through the next up list; that's it. The next up list should be prioritized and well defined at the top and roughly in priority order. So just pick up the next card and work on it. And we just do that every single day. And now we're in a piece of software that has the idea of cycles, and I'm like, oh, this is vaguely interesting. Do we want to do that? Oh, but if you're going to do that, you probably do some estimation, right? And I was like, oh no, now we're into a place that's...okay, I have feelings. I got to decide how to approach that. And so, I am intrigued. And I wonder if we could just say like ten carts that's how many come into a cycle, and that's it. And we use the loosest heuristics possible to define how we structure a cycle so that we don't fall into the trap of, oh, what's our roadmap going to look like six months from now? JK, what's anything going to look like six months from now? That's not a knowable fact. STEPH: I was just thinking where you said that you're moving into sprints or cycles, and then there's that push, well, now you got to estimate. And I just thought, do you? Do you have to estimate? [laughs] CHRIS: We need a burndown chart through 2024, and it must be meticulously accurate down to the hour. STEPH: I think meticulously wrong is how that goes. [laughs] CHRIS: Which is the best kind of wrong. If you're going to be wrong, be meticulous about it. STEPH: Be thorough about it. [laughs] Yeah, the team that I'm on right now, we have our bi-weekly planning, and we go through the board, and we pull stuff in. But there's never a discussion about estimation. And I hadn't really appreciated that until just now. How we don't think about how long is this going to take? We just talked about, well, what's in-flight? And how much work do people still have going on? And then here's the list of things we can pull in. But there's always a list that you can go back to. Like, it's very...we pull in the minimum and knowing that if we run out of work, there's another place to go where there's stuff that's organized. And I just love that cadence, that idea of like, let's not try to make guesses about the future; let's just have it lined up and ready for us to go when we're ready to pull it in. Although I know, that's also coming from a very developer's perspective, and there are product managers who are trying to communicate as to when features are going to get out into the world. So I get that there's a balance, but I still have strong feelings and hesitations around estimating work. CHRIS: Well, I feel like there is a balance there. And so many things in history are like, well, this is an overcorrection against that, and that's an overcorrection against this. And the idea that we can estimate our work that far out into the future that's just obviously false to me based on every project I've ever worked on that has tried to do it. And it has always failed without question. But critically, there is the necessity to sync up work and like, oh, marketing needs to plan the launch of this feature, and it's a critical one. What's it going to look like? When's it going to be ready? You know, we're trying to go for an event, it's not just know...we developers never estimate anything past the immediate moment where like, that's not acceptable. We got to find a middle ground here. But where that middle ground is, is interesting. And so, just operating in the sort of we do work as it comes up is the easiest thing because no one's lying about anything at that point. But sometimes you got to make some guesses and make some estimations. And then it gets into the murky area of I believe with 75% confidence that in three weeks, we will have this feature ready. But to be clear, I said with 75% confidence that means one-quarter of the time; we will not be there at that date. What does that mean? What does that failure mode look like? Let's talk about that. And can you have honest, open, transparent, useful conversations there? That's the space that it becomes more subtle if you need to do that. STEPH: You're reminding me of a conversation that I had with someone where they shared with me some very aggressive team goals. And it was a very friendly conversation. And they're like, "How do you feel about aggressive goals?" And I was like, "Well, it depends. How do you feel about aggressive failure?" Because then once I know where you stand there, then we can talk about aggressive goals. Now, if we're being aggressive, but then we fail to achieve that, and it's one of those, okay, we didn't meet the goal that we'd expected, but everything is fine, and it's not a big deal, then I am okay. Sure, let's shoot for the stars. But if it's one of those, we are communicating these goals to the outside world, and it's going to become incredibly important that we meet these goals, and if we don't, then things are going to go on fire, people are going to be in trouble, and it's just going to be awful, then let's not set aggressive goals. Let's not box ourselves into a space where we are setting ourselves up to fail or feel pain in a meaningful way. I agree that estimations are important, especially in terms of you need to collaborate with other departments, and then also just to provide some sense of where the product is headed and when things may be released. I think estimations then just become problematic when they do become definite, and they're based on so many unknowns, and then when I don't know is not an answer. So if someone asked, "What's your estimate for this?" And the very honest real answer is I don't know, like, we haven't done this type of work before, or these are all the unknowns, and then someone's like, "Well, let's just put an estimation of like two weeks on it," and they just sort of try to force-fit it into being what they want, then that's where it starts to just feel incredibly problematic. CHRIS: Yeah, estimation is a very murky area that we could spend entire episodes talking about, and in fact, I think we have a handful of times. So with that, Linear has been great. We're going to see just how much or how little estimation we actually want to do. But it's been a very nice addition to the toolset. And I'll let you know as we deepen our usage of it what the experience is like, but that's the main thing that's new in my world. What's new in your world? STEPH: Well, before we bounce over to my world, you said something that has intrigued me that has also made me start reflecting on some of the ways that I like to work. And you'd mentioned that you have this prioritized backlog that people are pulling tickets from. And I don't know exactly if there's a planning session or how that looks, but I have recognized that when I am working with a team, and we don't have any planning session, if everybody is just pulling from this backlog, that's being prioritized by someone on the team, that I find that a bit overwhelming. Because the types of work being done can vary so drastically that I find I'm less able to help my colleagues or my teammates because I don't have the context for what they're working on. It surprises me. I'm like, oh, I didn't even know we're working on that feature, or I don't have the context for what's the problem that we're trying to solve here. And it makes it just a lot harder to review and then have conversations with them. And I get overwhelmed in that environment. And I've recognized that about myself based on previous projects that were more similar to that versus if I'm on a project where the team does get together every so often, even if it's high level to be like, hey, here's the theme of the tickets that we're working on, or here's just some of the stuff, then I feel much more prepared for the work that is coming in and to be able to context switch and review. And yeah, so I've kind of learned that about myself. I'm curious, are you similar, or how does that work for you? CHRIS: I'm definitely similar. And I think probably the team is closer to what you're describing. So we do have a planning session every week, just a quick 30-minute scan through the backlog, look at the things that are coming up and also the larger themes. Previously, Epics and Trello now projects and Linear. But talking about what are the bigger pieces of work that we're moving on, and then what are the individual tickets associated with that that we'll be expecting to work on in the next week? And just making sure that everyone has broad clarity around what that feature set is. Also, we're a very small team at this point. Still, we're four people total, but one of the developers is on a break for a couple of weeks this summer. And so there are really only three of us that are driving on the code. And so, with three of us working on the projects, we try very intentionally to have significant overlap between the various...like, we don't want any one person to own any portion of things at this point. And so we're doing a good amount of pairing to cross-pollinate and make sure everyone's...not everyone's aware of everything, but at least one other person is sufficiently aware of everything between the three of us. And I think that's been working well. I don't think we have any major gaps, save for the way that we're doing our mobile architecture that's largely managed by one of the developers on the team and a contractor that we're working with to help do a lot of the implementation. That's a known we chose to silo that thing. We've accepted the cost of that for now. And architecturally, the rest of us are aware of it, but we're not like in the Swift code writing anything because I don't know how to write Swift at this point. I'd love to learn it. I hear good things about the language. [12:26] So yeah, I think conceptually very similar to what you're describing of still want to have people be able to review. Like, I don't want to put up a PR and people be like, I don't know, that looks like code, I guess. I'm not sure what it does. Like, I want it to be very...I want us all to be roughly on the same page, and thus far, we are. As the team grows, that will become trickier to maintain because there are just inherently probably more things that are moving, more different feature areas and surface area that we're tackling in any given week, or there are different ways to approach that. I know you've talked about having a limited number of themes for a given cycle, so that's an idea that can pop up. But that's something that we'll figure out as we get further. I think I'm happy with where we're at right now, so yeah, that's the story there. STEPH: Okay, cool. Yeah, all of that resonates with me, and thinking about it a little more deeply in this moment, I'm realizing I think something you said helped me put this together where when I'm reviewing someone's change, I'm not necessarily just looking to see does your code work? I'm going to trust you that your code works. I may have thoughts about design and other things, but I really want to understand more what's the change to the product that we're making? What's the goal that we're looking to achieve? How are we measuring this? And so if I don't have that context, that's what contributes to that feeling of like, hard context switching of not just context switching, but now I have to level myself up to then understand the problem that's being solved by this. Versus had I known some of the themes going into that particular cycle or sprint, I would have felt far more prepared for that review session versus having to then dig through all the data and/or tickets or talk to someone. Well, switching back to what's going on in my world, I have a particular tweet that I want to share, and it's one that Joël Quenneville brought to my attention. And it just resonates so much with all the type of work that I'm doing right now. So I'm going to read the tweet, and then we'll link to it in the show notes as well. But it's from Curtis Einsmann, and Curtis wrote: "In software engineering, rabbit holes are inevitable. You will research libraries and not use them. You'll write code just to delete it. This isn't a waste; sometimes, you need to go down a few wrong paths to get to the right one." And that describes all the work that I'm doing right now. It's a lot of exploratory, a lot of data-driven work, and finding ways that we can reduce the time that it takes to run RSpec on CI. And it also ties in nicely to one of the things that I think we talked about last week, where we discovered that a number of files have a high runtime variance. And I've really dug into the data there to understand, okay, is it always specific files that have these high runtime variants? Are there any obvious contributions to what's causing this? Are we making real network calls that then could sometimes take a long time to return? And the result is there's nothing obvious. They're giant files. The number of SQL commands that are being run for each file varies drastically. They're all high, but it's still very different. There's no single fact about these files that has really been like, yes, this is what's causing these files to have such a runtime variance. And so while I've been in the data, I'm documenting it, and I'm making a list and putting it all together in a ticket so at least it's there to look at later. But I'm going to move on. It's one of those I would love to know what's causing this. I would love to address it because it would put us in an ideal state for how we're distributing tests, which would have a significant impact on our runtime. But it also feels a little bit like chasing my tail because I'm worried, like with some of the other experiments that we've done in the past where we've addressed tentpoles, that as soon as you address the issue for one or two files, then other files start having the same problem. And you're just going to continue to chase and chase, and I don't want to be in that. So upfront, this was one of those; hey, let's look at the data. If there's something obvious, let's address it; if not, move on. So I'm at that point today where I'm wrapping up all of that data, and then I'm going to move on, move on to the next thing. CHRIS: There's deep truth in that tweet that you shared at the start of this segment. The idea like if we knew the work that we had to do at the front, yeah, we would just do that, but often, we don't. And so, being able to not treat it as a failure when something doesn't work out is, I think, so critical. I think to expand on the idea just a tiny bit, the idea of the scientific method, failure is totally an option and is part of science. I remember watching MythBusters, and Adam Savage is just kind of like, "Failure is always an option," and highlighting that as part of it. Like, it's an outcome. You've learned something. You have a new data point. You can take that and then carry it forward with you. But it's rough in the moment. And so, I do think that this is a worthwhile thing to meditate on. And it's something that I've had to revisit a handful of times in my career of just like, man, I feel like I've just been spinning my tires all week. I'm like, we know what we want to get done, but just each approach I take isn't working for one reason or another. And then, finally, you get to the end. And then you've got this paragraph-long summary of all the things that didn't work in your PR and one-line change sort of thing. And those are painful, but they're part of the game. Like, that is unavoidable. I have not found a way to just know how to do the work upfront always. I would love that. I would sign up for whatever seminar was selling that. I wouldn't. I would know that that seminar is a lie, actually. But broadly, I'm intrigued by the idea if someone were selling that, I'd be like, well, I mean, pitch me on it. Tell me why I should believe you; I don't, just to be clear. But yeah. STEPH: This project has really helped me embrace always setting a goal or a question upfront about what I'm wanting to achieve or what I'm looking to answer because a number of times while Joël and I have been spelunking through data...And then so originally, with the saga, we started out with why doesn't our math match reality? We understand that if these tests are distributed perfectly across the CPUs, then that should cut the runtime in half. But yet, we weren't seeing that even though we had addressed the tentpoles. So we dug into understanding why. And the answer is because they're not perfectly distributed, and it's because of the runtime variance. And that was a critical moment to look back and say, "Did we achieve the goal?" Yes, we identified the problem. But once you see a problem, it's just so easy to dig in and keep going. It's like, well, now I want to know what's causing these files to have a runtime variance. But it's one of those we achieved our goal. We acknowledged upfront that we wanted to at least understand why. Let's make a second decision, do we keep going? And I'm at that point where, frankly, I probably dug in a little more than I should because I'm stubborn. But I'm recognizing that now's the time to back away and then go back and move on to the next high-priority item, which is converting for funsies; I'll share. The next thing is converting Test::Unit test over to RSpec because we have, I think, around 25 tests that are written in Test::Unit. And we want to move them over to RSpec because that particular just step in the build process takes a good three to four minutes. And part of that is just booting up Rails and then running the tests very fast. And we're underutilizing the machine that's running them because it's only 25 tests, but there are 86 CPUs to run it. So we'd really like to combine those 25 tests with the rest of the RSpec suite and drop that step. So then that should add minimal time to the overall build but then should take us down at least a couple of minutes. And then also makes it easier to manage and help folks so that way, there's one consistent testing framework that's in use versus having to manage some of these older tests. CHRIS: It's funny; I think it was just two episodes back where we talked about why RSpec, and I think both of us were just like, well yeah. But I mean, if there are tests and another, like, it's fine, you just leave them with the exception that if there's like 2% of our tests are in Test::Unit, and everything else is in RSpec, yeah, maybe that that conversion efforts seem totally worth it. But again, I think as you're describing that, what I'm hearing is just like the scientific method, just being somewhat structured in the approach to what's the hypothesis? And what's the procedure we're going to use to determine if that hypothesis is true or false? And then what do we do? And then what are the results? And then you just do that on loop. But being not just sort of exploring. Sometimes you have to be on exploratory mode. But I definitely find that that tiny bit of rigor of just like, wait, okay, before I actually do anything, what do I think is going on here? What's my guess? And then, okay, if that guess were true, what would I be able to observe in the world? Okay, here we go. And just that tiny bit of structure is so...it sometimes feels highly formal to go into that mode and be like, no, no, no, let me take a step back. Let me write down my thoughts. I'm going to have a little checklist and do the thing. But I've never regretted doing it. I will say that. I have deeply regretted not doing it. I feel like I should make a list of things that fit that structure. I've never regretted committing in Git ever. That's been great. I've always been able to unwind it, but I've never been able to not unwind it or the opposite. I've regretted not committing. I have not regretted committing. I have regretted not writing out my hypothesis or approach. I have not regretted doing it. And so, yeah, this feels like it falls firmly in that category of like, it's worth just a tiny bit of structure. There's a reason it is the scientific method. STEPH: Yeah, I agree. I've not regretted documenting upfront what it is I look to achieve and how I think I'm going to answer the question. That has been immensely helpful. Because then I also forget, like, two weeks ago, I'll be like, wasn't there a question around why this was happening, and I need to understand? And all of that was so context-heavy that as soon as I'm out of the thick of it, I completely forget it. So if I care about it deeply or if I want to be able to revisit it, then I need to document it for myself. It's given me a lot of empathy for people who do more scientific research around, oh my gosh, like, you have to document everything you do and then still be able to prove it five years from now or however long. I'm just throwing out numbers. And it needs to be organized enough that someone, if they do question your research that, then you have it there. My research documents would not withstand scrutiny at this point because they are still just more personal notes. But yes, it's given me a lot of empathy and respect for people who do run very serious research, experiments, and trials, and then have to be able to prove it to the world. Pivoting just a bit, there's a particular topic that resonated with both you and I; in fact, it's a particular tweet. And, Louie, I do apologize if I mispronounce your last name, but Louie Bacaj. And we'll include a link in the show notes to the tweet, but Louis shared, "I managed multiple engineering teams before quitting tech. Now that I quit, I can speak freely. Here are 12 things your manager may not be telling you, but I know for a fact will help you." So there are a number of interesting discussions and comments that are in this thread. The one thing in particular that really caught my attention is number 10, and it's "Advocate for junior developers." So they said that their friend reminded them that just because you don't have 10-plus years of experience does not mean that they won't be good. Without junior engineers on the team, no one will grow. Help others grow; you'll grow too. And that's the part that I love so much is that without junior engineers on the team, no one will grow because that was very thought-provoking for me. It's something that I find that I agree with deeply, but I hadn't really considered why I agree with that so much. So I'm excited to dive into that topic with you. And then, as a second topic to go along with that is, can juniors start with a remote team? I think that's one of the other questions when you and I were chatting about this. And I'm intrigued to hear your thoughts. CHRIS: A bunch of stuff there. Starting with the tweet, I love elements of this. Some of it feels like it's intentionally somewhat provocative. So like, without junior engineers on the team, no one will grow. That feels maybe a little bit past the bar because I think we can technically grow, and we can build things and whatnot. But I think what feels deeply true to me is truly help others grow; you'll grow too. The act of mentoring, of guiding, of training, of helping someone on their journey will inherently help you grow and, I think, change the way that you think about the work. I think the beginner mind, the earlier in the career folks coming into a codebase, they will see things fundamentally differently in a really useful way. It's possible that along your career, you've just internalized things. You've been like, yeah, no, that was weird. But then I smashed my head against it for a while, and now I understand this thing. And it just makes sense to me. But it's like, that thing actually doesn't make sense. You have warped your mind to match the thing, not, quote, unquote, "come to understand it." This is sounding too judgmental to people who've been in the industry for a while, but I found this of myself. Or I can just take for granted things that took a long time to adapt my head to, and if anything, maybe I should have pushed back a little more. And so, I find that junior engineers can be a really fantastic lens for the complexity of a project. Like, the world is truly a complex place, and that's just true. But our job as software engineers is to tame that complexity and manage it. And so, I love the mindset that can come or the conversations that can come out of that. And it's much like test-driven development is a pressure on the complexity of your code, having junior engineers join the team and needing to explain how all of the different features work, and what the overall architecture is, and the message passing under this and that, it's a really useful conversation to have. And so that "Help others grow; you'll grow too" feels deeply, deeply true to me. STEPH: Yeah, I couldn't agree more in regards to how juniors really help our team and especially, as you mentioned, with complexity and ¬having those conversations. Some of the other things that have come to mind for me as well around the importance of having junior developers on your team...and maybe it's not specifically they're junior developers but that you just have a variety of experience on your team. It's going to help you lean into a culture of learning because you have people that are at different stages of their career. And so you want an environment where people can learn together, that they can fail together, and they can be public about it. And having people that are at different stages of their career will lead, well, at least ideally, it'll lead to more pair programming. It's going to lead to more productive code reviews because then people can ask more questions around why did you choose this, or why are you doing that? Versus if everybody is at the same level, then they may just intuitively have reasons that they think someone did something. But it takes someone that's a bit new to say, "Hey, why did you choose this?" or to bring up some other ideas or ways that they could pursue it. They may bring in new ideas for, like, why has the team always done something this way? Let's think about new ways that we could do this. Or maybe this is really unfriendly, the way that we're doing this, not just for junior people but for people that are new to the team. And then there's typically less knowledge siloing because then you're going to want to pair the newer folks with the more experienced folks. So that way, you don't have this more senior developer who's then off in a corner working by themselves. And it's going to improve your communication skills. There's just...I realized I'm just rambling because I feel like there are so many benefits that go along with having a variety of people on your team, especially in terms of experience. And that just leads to such a better learning environment and, ultimately, better software and better products. And yet, I find that so many companies won't embrace people that are newer to software. They always want the senior developers. They want the 10x-er or whatever those are. They want the people that have many, many years of experience. And there's so much value that comes from mentoring the next group of developers. And it's incredibly frustrating to me that one, companies often aren't open to it. But honestly, more than that, as long as you're upfront and honest about like, hey, this is the team that we need right now to build what we're looking to build, I can get past that; I can understand that. But please don't then mislead people and say that you're a junior-friendly team, and then not be prepared. I feel like some teams will go so far as to say, "Yes, we are junior-friendly," and they may even tweak their interview process to where it is a bit more junior-friendly. But then, by the time that person joins the team, they're really not prepared. They don't have an onboarding plan. They don't have a mentorship plan. And then they fail that person because that person has worked hard to get there. And they've worked hard to bring that person onto the team, but then they don't have a plan from there. And I've seen it too many times. And it just frustrates me so much because it puts that junior person in such a vulnerable state where they really have to be an incredible self-advocate to then overcome those hurdles from a lack of preparation on that company's part. Okay, I think that's my event. I'm sure I could vent about this a lot more, but I will cut it off there. That's the heart of it. CHRIS: I do think, like, with anything else, it's something that we have to be intentional about. And so what you're saying of like, yeah, we're a junior-friendly company, but then you're just hiring folks, trying to find folks that may work at a slightly lower pay grade, and that's what that means to you. So like, no, no, that's not what this is. This needs to be something different. We need to have a structure and an organization that can support folks at different points in their career. But it's interesting to me to think about the sort of why of it. And the earlier part of this conversation, we talked about some of the benefits that can come organizationally from it, and I do sincerely believe in that. But I also believe that it is fundamentally one of the best ways to find really talented people early on in their career and be in a position to hire them where maybe later on in their career, that just wouldn't happen naturally. And I've seen this play out in a number of organizations. I went to Northeastern University for my college, and Northeastern is famous for the co-op program. Northeastern sounds really fancy. Now I learned that they have like a 7% acceptance rate for college applications right now, which is wildly low. When I went to Northeastern, it was not so fancy. So just in case anyone's hearing that and they're like, "Oh, Northeastern, wow." I'm not that fancy. [laughs] But they did have the co-op then, and they still have it now. And the co-op really is a differentiating thing. You do three six-month rotations. And it is this fundamental differentiator in terms of when you're graduating. Particularly, I was in mechanical engineering. I came out, and I actually knew what that meant in the world. And I'd used Outlook, and I knew what a water cooler was and how to talk near one because that's a critical thing to learn in the world. And really transformative experience for me. But also, a thing that I observed was many of my friends ended up working at companies that they had co-opted for. I'm one of those people. I would say more than 50% of my friends ended up with a position at a company that they had done a co-op rotation with. And it really worked out fantastically. That organization and the individual got to try things out, experience. And then, I ended up staying at that company for a number of years, and it was a wonderful experience. But I don't know that I would have ended up there otherwise. That's not necessarily the way that would have played out. And similarly like, thoughtbot has the apprenticeship. And I have seen so many wonderful developers start at that very early point in their career. And there was this wonderful structure around them joining the thoughtbot team, intentional, structured, supported. And then those folks went on to be some of the most talented developers that I've ever worked with at a wonderfully talented organization. And so the story of like, you should do this, organizations. This is a thing that you should invest in for yourself, not just for the individual, like, for both. Everybody wins in this case, in my mind. I will say, though, in terms of transparency, I currently manage a team of three developers. And we hired very intentionally for senior folks this early on in where we're at. And that was an intentional choice because I do believe that if you're going to be hiring more junior developers, that needs to be something that you do very intentionally, that you have a support structure in place, that you're able to invest the time in where they're at and make sure we have sort of... I think a larger team makes more sense to bring juniors into broadly. That's the thing that I'm saying out loud that I'm like, I should push on that a little bit. Is that true? Do I really believe that? But I think so, my actions obviously point to it. But it is an interesting trade-off space of how do you think about that? My hope is that as we grow as an organization, that we would then very intentionally start hiring folks in a more junior, mid-level to junior and be very intentional about how we support them, bring them into the organization, et cetera. I do believe it is a win-win situation for everyone when done with intention and with focus. STEPH: That's such an interesting bit that you just said because I very much appreciate when companies recognize do we have the bandwidth to support someone that's more junior? Because at thoughtbot, we go through periods where we don't have our apprenticeship that's open because we recognize we're not in a place that we can support someone. And we don't want to bring someone in unless we can help them be successful. I very much admire that and appreciate that about companies when they can perform that self-assessment. I am so intrigued. You'd mentioned being a smaller team. So you more intentionally hire senior developers. And I think that also makes sense because then you need to build up who's going to be in that mentorship pool? Because then people could leave, people could take vacations, and so then you need to have that support system in place. But yeah, I don't know what that then perfect balance is. It's like, okay, so then as soon as you have like five people available to mentor or interested in mentorship, it's like, then do you start bringing in the conversation of like, let's bring in someone that we can help build up and help them be successful and join our team? And I don't know what that magical number is. I do think it's important for teams to reflect to say, "Can we take on someone that's junior?" All the benefits of having someone that's junior. And then just being very honest and then having a plan for once that junior person does arrive. What does their career path look like while they've joined that team, and who's going to be that person that's going to help them level up? So not only make that choice upfront of yes, we are bringing someone on but let's also think about like the first six months of their work here at the company and what that's going to look like. It feels like an important step that a lot of companies fail to do. And I think that's why there are so many articles that then are like, hey, if you're a junior dev, here's all the things that you should do to be the best junior dev. That's fabulous. And we're constantly shoring up junior devs to be like, hey, here's all the things that you need to be great at. But we don't have as many conversations around; hey, here's all the things that your manager or the rest of your team should be great at to then support you equally as you are also doing your best to meet them. Like, they need to meet you halfway. And I'm not completely unsympathetic to the plight; I understand. It's often where I've seen with teams the more senior developers that have very strong mentorship communication skills are then also the teammates that get pulled into all the meetings and all the different projects, so then they are less available to be that mentor. And then that's how this often fails. So I don't think anybody is going into this intentionally, but yet, it's what happens for when someone is new and joining a team, and it hasn't been determined the next six months what that person's onboarding and career path looks like. Circling back just a bit, there's the question around, can juniors start with a remote team? I can go first. And I'm going to say unequivocally yes. There's no reason a junior can't start with a remote team. Because all the things that I feel strongly about come down to how is your team going to plan for this person? And how are they going to support this person? And all the benefits that you get from being in an office with a team, I think those do exist. And frankly, for someone like myself, it can be easier to establish a bond with someone that you get to see each day, get to see in person. You can walk up to their desk and can say, "Hey, I've got a question for you." But I think all those benefits just need to be transferred into a remote-friendly way. So I think it does ratchet up how intentional you have to be with your team and then onboarding a junior developer. But I absolutely think it's doable, and we should do it. CHRIS: You went with unequivocally yes as your answer. I'm going to go with a qualified maybe as my answer. I want this to be true, and I think it can be true. But I think it takes all the more intentionality than even what we've been describing. To shift the question around a little bit, what does remote work mean? It doesn't just mean we're doing the work, but we're separate. I think remote work inherently is at its best when we also are largely async first. And so that means more structured writing. The nature of the conversation tends to be more well-formed in each interaction. So it's like I read a big document, and then I pass it over to you. And at your leisure, you respond to it with a bunch of notes, and then it comes back to me. And I think that mode of interaction, while absolutely wonderful and something that I love, I think it fits really well when you're a little bit further on in your career when you understand things a little bit better. And I think the dance of conversation is more useful earlier on and so forth. And so, for someone who's newer to a team, I think having the ability to ask a quick question over and over is really useful to someone who's early on in their career. And remote, again, I think it's at its best when it's async. And those two are sort of at odds. And so it's that mild tension that gives me pause of like, something that I think that makes remote work great I do think is at least a hurdle that you would have to get over in supporting someone who's a little bit newer. Because I want to be deeply present for someone who's newer to their journey so that they can ask a lot of questions so that I am available to be interrupted regularly. I loved at thoughtbot sitting next to someone and being their mentor and being like, yeah, anytime you want, just tap on my desk. If I got my headphones on, that doesn't mean I'm ignoring you; it means I just need to make the sounds go away for a minute because that's the only way my brain will work. But feel free to just tap on my desk or whatever and grab my attention for a moment. And I'm available for that. That's an intentional choice. That's breaking up my continuity of the day, but we're choosing that for a reason. I think that's just a little harder to do in a remote context and all the more so if we're saying, hey, we're going to try this async thing where we write structured documents, and we communicate in these larger, more well-formed, communicates back and forth. But I do believe it can be done. I think it should be done. I just think it's all the harder for all of those reasons. STEPH: I agree that definitely makes it harder. But I'm going to push a little bit and say that when you mentioned being deeply present, I think we can be deeply present with someone and be remote. We can reduce the async requirements. So if you are someone that is more senior or more accustomed to the team, you can fall back to more of those async ways to communicate. But if someone is new, and needs more mentorship, then let's just set up time where we're going to literally hang out for a couple of hours each day or whatever pairing environment works best for them because pairing can also be exhausting. But hey, we're going to have a check-in each day; maybe we close out each day and touchpoint. And feel free to still message me and interrupt me. Like, you're going to just heighten your availability, even though it is remote. And be aware, like, hey, this person could message me at more times, and I'm okay with that. I have opted into this form of communication. So I think we just take that mindset of, hey, there's this person next to me, and I'm their mentor to like, hey, they're not next to me, but I'm still their mentor, and I'm still here for them. So I agree that it's harder. I think it falls on us and the team and the mentors to change ourselves versus saying to juniors, "Hey, sorry, it's remote. That's not going to work for you." It totally works for them. It's us, the mentors, that need to figure out how to make it work. I will say being on that mentor side that then not being able to see someone so if they are next to me, I can pick up on body language and facial expressions, and I can tell when somebody's stuck. And I can see that they're frustrated, or I can see that now's a good time for me to just be like, "Hey, how's it going? What are you working on? Or do you need help with something?" And I don't have that insight when I'm away. So there are real challenges like that that I don't know how to address. I have gone the obnoxious route [laughs] where I just message people, and I'm like, "Hey, how's it going? How's it going? How's it going?" And I try not to do that too much. But I haven't found a better way to manage that other than to constantly check in because I do have less feedback from that person that I'm working with unless they are just incredibly open about sharing when they're stuck. But typically, when you're newer to a team or newer to a career, you're going to be less willing to share when you're stuck. But yeah, there are some real challenges, but I still think it's something for us to figure out. Because otherwise, if we cut off access for remote teams to junior folks, I mean, that's where we're headed. There are so many companies and jobs that are headed remote that not being junior friendly and being remote in my mind is just not an option. It's something that we need to figure out. And it's hard, but we need to figure it out. CHRIS: Yeah, 100% on we need to figure that out and that that's on us as the people managing and structuring and bringing folks into teams. I think my stance would be like, let's just be clear that this is hard. It takes effort to make sure that we've provided a structure in which someone newer to a team can be successful. It takes all the more effort to do so in a remote context, I think. And it's that recognition that I think is critical. Because if we go into this with the wrong mindset, it's like, oh yeah, it's great. We got this new person on the team. And yeah, they should be ready to go in like two weeks, right? It's like, no, no, this is a different thing. We need to be very clear about it. This is going to require that we have someone who is able to work with them and support them in this. And that means that that person's output will likely be a little bit reduced for the period of time that we're talking about. But we're playing a long game here. Let's make sure we're clear on that. This is intentional. And let's be clear, the world of hiring and software right now it's not like super easy. There aren't way more software developers than there are jobs; at least, that's been my experience. So this is something absolutely worth investing in for just core business reasons and also good for people. So hey, it's a win-win. Let's do it. Let's figure it out. But also, let's be clear that it's going to be a little tricky along the way. So, you know, let's be intentional about that. But yeah, obviously do it, got to do it. STEPH: Wait, so I feel like we might have circled back to unequivocally yes. [laughs] Have we gotten there, or are you still on the fence? CHRIS: I was unequivocally yes from the beginning, but I couched it in, but...yeah, I said other things. You're right. I have now come around; let's say to unequivocally yes. STEPH: [laughs] Cool. I don't want to feel like I'm forcing you to agree with me. [laughs] But I mean, we just so rarely disagree. So we've either got to identify this as something that we disagree on, which would be one of those rare occasions like beer and Pop-Tarts. CHRIS: A watershed moment. Beer and Pop-Tarts. STEPH: Yeah, those are the only two so far. [laughter] CHRIS: Not together also. I just want to go on record beer and Pop-Tarts; I don't think would be...anyway. STEPH: Ooh, I don't know. It could work. It could work. CHRIS: Well, there's another thing we disagree on. STEPH: I would not turn it down. If I was eating a Pop-Tart, and you're like, "Hey, you want a beer?" I'd be like, "Sure," vice versa. I'm drinking a beer. "Hey, you want a Pop-Tart?" "Totally." CHRIS: Okay. Well yeah, if I'm making bad decisions, I'm obviously going to chain them together, but that doesn't mean that they're a good decision. It's just a chain of bad decisions. STEPH: I feel like one true thing I know about you is that when you make a decision, you're going to lean into it. So like, this is why you are all about if you're going to have a Pop-Tart, you're going to have the highest sugary junk content Pop-Tart possible. So it makes sense to me. CHRIS: It's the Mountain Dew theorem, yeah. STEPH: I didn't know this had a theorem. The Mountain Dew theorem? CHRIS: No, that's just my name. Well, yeah, if I'm going to drink soda, I'm going to drink Mountain Dew, the nonsense nuclear option of soda. So yeah, I guess you're describing me, although as you say it back to me, I suddenly feel very, like, oh God, is this who I am as a person? [laughs] And I'm not going to say you're wrong. I'm just going to spend a little while thinking about some stuff. STEPH: I mean, you embrace it. I think that's lovely. You know what you want. It's like, all right, let's do this. Let's go all in. CHRIS: Thank you for finding a wonderfully positive way to frame it here at the end. But I think on that note, should we wrap up? STEPH: Let's wrap up. CHRIS: The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Please consider supporting Anna Filina's Ukrainian relatives https://afilina.com/donate/ua-supplies Other ways to support the people of Ukraine https://supportukrainenow.org Change log Due to the traveling we didn't get to do the Twitch Live stream on Sunday so I'm hoping to finish the PHP login course off this Sunday (15th) On Tuesdays (12th) YouTube live stream we continued building the proof of concept for the PHP registration course. Someone in the chat spotted that I wasn't testing the code in PHPUnit, this raised a question about when to test the code. The code will certainly be tested but at this stage I'm just building a proof of concept and I'm literally throwing code at the IDE to see what sticks and to get a feel for the flow of the application. You don't have to test your code all of the time I don't believe you need to test your code all of time. Let me explain what I mean and if you disagree then please let me know at https://howtocodewell.fm/contact My web development courses ➡️ Learn How to build a JavaScript Tip Calculator ➡️ Learn JavaScript arrays ➡️ Learn PHP arrays ➡️ Learn Python ✉️ Get my weekly newsletter ⏰ My current live coding schedule (Times are BST) Thursdays 20:00 = Live Podcast YouTube Sundays 14:30 - Live coding on Twitch
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.This episode is sponsored by Scout APM - Laravel Monitoring and more that identifies slow database queries, memory leaks, and slow custom code - and Honeybadger - combining error monitoring, uptime monitoring and check-in monitoring into a single, easy to use platform and making you a DevOps hero.Show links Laravel 9.7 released Laravel 9.8 released BaseCode: A field guide for writing more readable code Laravel DynamoDB Eloquent models and query builder Add likes, bookmarks, favourites, and other marks in your application with Laravel Markable Style guide generator for Tailwind CSS Laravel Livewire: 14 tips & tricks Learn how to start testing in Laravel with simple examples using PHPUnit and Pest How to use soft deletes in Laravel Using `query()` in Laravel Eloquent queries Job queues and workers in Laravel apps
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.This episode is sponsored by Honeybadger - combining error monitoring, uptime monitoring and check-in monitoring into a single, easy to use platform and was streamed live.Show links Laravel 8.74 released Laravel 8.75 released Filament TALL stack admin panel v2 released Tailwind CSS v3 is now released Laravel Holiday Giveaway Laravel and Vue translation package Badgers Ban Eloquent models with the Laravel Ban package Managing secrets in Laravel with AWS Parameter Store ScoutSuite A bash function to run tests for both PHPUnit and Pest A package for adding more type safety to your PHP projects Using semantic elements to improve your HTML A conversation on the future of PHP
PHP Internals News: Episode 75: Globals, and Phasing Out Serializable London, UK Thursday, February 11th 2021, 09:03 GMT In this episode of "PHP Internals News" I chat with Nikita Popov (Twitter, GitHub, Website) about two RFCs: Restrict Globals Usage, and Phase Out Serializable. The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news Transcript Derick Rethans 0:14 Hi I'm Derick. Welcome to PHP internals news, a podcast dedicated to explain the latest developments in the PHP language. This is Episode 75. In this episode, I'm talking with Nikita Popov about a few RFCs that he has been working on over the past few months. Nikita, would you please introduce yourself? Nikita Popov 0:34 Hi, I'm Nikita, I work at JetBrains on PHP core development and as such I get to occasionally, write PHP proposals RFCs and then talk with Derick about them. Derick Rethans 0:47 The main idea behind you working on RFCs is that PHP gets new features not, you end up talking to me. Nikita Popov 0:53 I mean that's a side benefit, Derick Rethans 0:55 In any case we have a few to go this time. The first RFC is titled phasing out Serializable, it's a fairly small RFC. What is it about? Nikita Popov 1:04 That finishes up a bit of work from PHP 7.4, where we introduced a new serialization mechanism, actually the third one, we have. So we have a bit too many of them, and this removes the most problematic one. Derick Rethans 1:19 Which three Serializable methods or ways of doing things currently exist? Nikita Popov 1:24 The first one, which doesn't really count is just what you get if you don't do anything, so just all the Object Properties get serialized, and also unserialized, and then we have a number of hooks, you can use to modify that. The first pair is sleep and wake up. Sleep specifies which properties you want to serialize so you can filter out some of them, and wake up allows you to run some code, after unserialization, so you can do some kind of fix up afterwards. Derick Rethans 1:52 From what I remember, if you use unserialize, where does the wake up the constructor doesn't get called? Nikita Popov 1:59 During unserialization the constructor, never gets called. Derick Rethans 2:03 So wake up a sort of the static factory methods to re rehydrate the objects. Nikita Popov 2:08 Exactly. Derick Rethans 2:08 So that's number one, Nikita Popov 2:10 Then number two is the Serializable interface, which gives you more control. Namely, you have to actually like return the serialized representation of your object. How it looks like is completely unspecified, you could return whatever you want, though, in practice, what people actually do is to recursively call serialize. And then on the other side when unserializing you usually do the same so you call unserialize on the stream you receive, and then populate your properties based on that. The problem with this mechanism is exactly this recursive serialization call, because it has to share state, with the main serialization. And the reason for that is that, well PHP has objects, or object identity. So if you use the same object in two places you really want it to be the same object and not two objects with the same content. Serializable has to be able to preserve that, and that requires that it runs in the middle of the unserialization. Derick Rethans 3:14 Not sure if I follow that bit. Nikita Popov 3:16 Well maybe it's not a hard requirement more like an issue with our serialization format that comes into play here. Way PHP implements this, is using back references. So at first unserializes an object and then later you can have like a pointer back to it, that says like, I want to use the same object as at position number, 10, or so. For these back references to work, we have to actually execute the serialization handler while unserializing because otherwise the offsets will no longer match. So we can just run this at the end of unserialization for example because then our offsets would be incorrect. And this is a big problem because it's not really safe to run code, during unserialization because things are partially initialized. To make these back references work, PHP has to actually store pointers to these objects. And if you somehow modify things in specific ways, then these pointers become invalid. They point to a memory that no longer exists, and a possibly exploitable crash. This is why we would like to get rid of this mechanism. Derick Rethans 4:25 But of course, in order to get rid of things, we had to have a better way of doing things in place first, right, which came with PHP seven four. Nikita Popov 4:32 That's right. Derick Rethans 4:32 So that's number three. Nikita Popov 4:34 That's number three. Number three is actually very similar to number one: two new magic methods, double underscore serialize and double underscore unserialize. Serialize returns an array, usually like an array of properties for example, and then unserialize populates the object from that array. In practice, this works very similar to the Serializable interface, just that you don't manually call serialize and unserialize, but PHP will do so on your behalf. So you just return an array or get an array, and PHP will integrate that into the like main serialization, and because it's left to PHP, PHP can control where these calls occur. Derick Rethans 5:19 With sleep originally you only return the name of the properties. Whereas with this new interface you return the names of the properties but also their values. Nikita Popov 5:30 That's right. The new mechanism, this, like, in practice, it serves as a replacement for the Serializable interface. But from a technical side it's really close to sleep and wake up, um, just that, as you said, instead of returning property names you return both names and values. Derick Rethans 5:51 And this is now the recommended way of doing serialization. Nikita Popov 5:54 Like the motivation is one problem was, what I mentioned the security problem. Maybe the thing that impacts users more commonly is that things like calling parent::serialize and parent::unserialize with the Serializable interface, usually doesn't do what you want. Again, due to these back references because, like, the calls get out of order, we should do the same thing with the magic methods, with the underscore underscore serialize and unserialize and you can safely call parent methods and compose serialization in that way. Derick Rethans 6:29 That's our state of serialization right now. We haven't spoken about RFC, what are you proposing to do here? Nikita Popov 6:34 The RFC proposes to get rid of the Serializable interface. And, like in a way that is a bit more graceful than just deprecating it outright. And the idea is that if you have code that is still compatible with PHP 7.3, where the new mechanism doesn't exist, you probably still want to use Serializable. So if we just deprecated out right that would be fairly annoying to have code that's compatible with PHP 7.3, and 8.1. So instead what we do is we only deprecate the case where you implement Serializable without implementing the new mechanism. If you implement both of them, then you're fine for now. Derick Rethans 7:15 The new mechanism, the one we're introducing PHP 7.4, would overrides the PHP 7.3 one already anyway. Nikita Popov 7:22 Exactly. So on PHP 7.3 you would end up using Serializable and PHP seven four and higher, you would be using the new mechanism. And then, at a later point in time we would actually also deprecate Serializable itself and then remove it, though, like based on mailing list response, some people at least didn't like the long timeline. I'm not exactly sure what the alternative is, so either to deprecate Serializable right away, or to later remove it without deprecation of the interface itself. Derick Rethans 7:57 Yeah, from what I saw the, the long-term-ness of phasing it out. I think had mentioned that it finally got removed in PHP 10, which is potentially 10 years away right. If we following every five years with a new major release. But then in the end, it does have some merit making sure that people can move on without being left in the dark at some point right. What is your own preference? Nikita Popov 8:22 My own preference is what I proposed. I would also be fine with, like say in PHP 8.1, we call the proposal so you only get a warning if you only implement Serializable without the new mechanism, and the PHP nine we could just drop Serializable entirely. I think that would not be, because then the only problem then would be if you have code that is competitive with PHP 7.3 and PHP 9.0. I am sure that code will exist ... pretty normal version range to have. Derick Rethans 9:08 Yeah, I probably would agree with you there. When I read the RFC it also mentioned PDO. Why would it mention PDO? Nikita Popov 9:15 This all is something I only found out while writing it's on there is a PDO fetch serialize flag, which automatically calls unserialize when fetching values. So I will not comment on the really dubious idea of storing serialized data in the database. Derick Rethans 9:35 I mean, people would currently said that the alternative is to store JSON, in these columns as values. Nikita Popov 9:40 That would still be better. Derick Rethans 9:42 But it's still a serialized format? Nikita Popov 9:44 But at least the way this flag is implemented is effectively broken, because it doesn't just call unserialize, the function; it calls unserialize on the Serializable interface. I have no idea how this was intended to be used in practice, because it's not compatible with, like the normal serialization of the class. In practise like everything I have found about this online is basically just that okay if this functionality is broken, you shouldn't use it. Derick Rethans 10:15 So you have less concerns just removing that straight away, I suppose. Nikita Popov 10:19 Yeah. Derick Rethans 10:20 Do you have anything else out about serialization. Nikita Popov 10:22 I think this proposal is a very simple one and we have actually talked, way too much about this. Derick Rethans 10:29 Let's move on to the next RFC, which is titled Restrict Globals Usage. This title almost sounds worse than it is as it might imply that you want to get rid of the globals array altogether. But I bet that's not the case. And I also suspect that restricting the globals array is a lot more technical as a subject as it might seem. Nikita Popov 10:49 That's right. So this is really, mostly motivated by internal concerns, and has hopefully not a great deal of impact on like practical usage. There are a couple motivations, so some of them are about semantics, so globals is a very magic variable, that does not follow the usual semantics of PHP a number of ways. In particular array are typically by value. In all other cases, they are by value, which means that if you modify, like if you copy an array and modify one copy, then the other one doesn't get modified, I mean it's a copy so obviously it doesn't get modified. For globals if that's not the case. If you make a copy of globals and you modify the copy, then the original array also gets modified. Derick Rethans 11:36 Which is not the case for other super globals such as underscore get and underscore post. Nikita Popov 11:41 The other super globals are a bit magic but not that magic. There are a couple of other concerns with edge cases, but I think the real motivation here is the internal concern. And that's how globals is implemented. PHP, normally, manages variables in functions and scripts, using so called compiled variables. And this works by well when the script is compiled we actually see all the variables with the used, at least all the variables that don't go through something like variable variables or globals or something like that. And we reserve a slot for each of these variables, so we can directly access it. We don't have to look up, like the variable by name, we just say this is variable number seven and we can directly access it, which is much much more efficient. The problem is, then if you have something that globals you want to both have this access by index, and access by name, and they do that by storing a pointer inside the globals array to the actual location of the variable. Yeah, so this is a very special concept. So we call this an indirect, a variable of indirect type, and it essentially occurs only inside the globals array, and for object properties. For object properties it happens for the same reason, so object properties are normally accessed by index, but if you do something like variable object dynamic object access, then we also have to look it up by name. There we do the same thing, so we have a like map from property names to values, and if the value is really stored inside an object property slot then we just store a pointer there. The thing with the objects is that this is like really an internal concern that's well encapsulated and doesn't leak into normal PHP code. That's not the case with globals because globals is on the surface just a normal array. So you can do everything with it, you do with a normal array you can pass it to functions. Like in theory, all the functions, need to deal with this special value type that says: okay actually this is not the value itself is just a pointer to the value. The way you do it is every time you access a value you check okay is this an indirect value; if it is, follow the pointer. Derick Rethans 14:01 I have plenty of code in Xdebug for this. Nikita Popov 14:04 So it's really a super simple operation to do, but you actually have to do it. And you have to do it absolutely everywhere, if you're being pedantic. In practice that just doesn't happen. In PHP's own code, in the standard library, the array functions are those do consistently handle this edge case. But if you like go further, even most bundled extensions, and certainly most third party extensions, they are not going to do this and if they don't either they just get some, like you know benign misbehaviour where it looks like array elements are missing, or you get a crash, because the type is simply not handled. Yeah, well that's not a great state to be in, because like pushing passing the globals array into something like array pop or something, is very weird operation to do. I don't know if ever, anyone has done that for purposes outside testing PHP. But to support it, we have to like handle this special case everywhere, which is not robust and also has a certain performance impact when it comes to low level operations. So we also have to do this check every time you access an array for example from normal PHP code The idea is to remove the special case. That's the motivation here. Derick Rethans 15:23 What are you proposing to change? Nikita Popov 15:26 One is if you just access variable in globals. So you write $GLOBALS[], some variable name. Then we treat that especially and compile it down to an access to this global variable. So it could be a read access, could be a write access, or anything else, Derick Rethans 15:44 But it is something that happens, when PHP compiles scripts. Nikita Popov 15:48 That's right. The second part is you can also access the globals array in a read-only way, so you can take the whole array, and for example, do a for each loop over it. And that continues to work. The part that doesn't work is to take the whole globals array and modify it in some way, for example, passing globals to array pop, which requires passing it by reference is going to throw an error. Derick Rethans 16:13 At which state. Is that going to throw an error? Nikita Popov 16:15 That's usually during compilation, but specifically for the case of by-reference passing it can't be detected at runtime, because we don't always know if it's a by-reference or by-value pass. But for most of the cases it's a compile time error. Maybe one particular case that's worth mentioning is that you also can do a foreach by-reference over it. So if you like want to loop over globals and modify entries while doing so the way to do it now would be to do by-value loop and then just again access specific elements in it, like access globals key or something. And the reason why this helps us is that we can just return, like when you access globals, we can actually return a copy of the array. We don't have to maintain these like indirect pointers which are only necessary to support modifications, we can just return a copy. That means we no longer have to deal with this edge case in most places, in the engine and in third party extensions, Derick Rethans 17:15 Talking about third party extensions, the code that implements this RFC has already been merged into PHP eight one, but the moment you did that, tests in Xdebug started failing, because I read the globals array, but it doesn't seem like it exists any more now. Nikita Popov 17:31 That's actually a good point. Globals, I would know view it as a like, more like a syntax construct, similar to variable variables, or even the $this variable. So this is also not a real variable. Globals is no longer added as an actual variable in the symbol table, which is directly compiled down to either an access to the specific global or returns a copy of the table. So for Xdebug you, I probably filter you you have to access the EG symbol table. Derick Rethans 18:02 Yes, but it wasn't as simple as it seemed because this is a hash table, and no longer is that a full array, which means that all my logic code doesn't work with that. So I've decided that globals just no longer exists and stuff, which is what it logically is in PHP eight one anyway. Nikita Popov 18:22 So that might actually be nice. So I know that, like code that does work with globals, like as an array, usually also always skips skips globals itself when iterating over it, because otherwise you usually run into some kind of infinite recursion issue. That's actually another thing, so globals is the one way you can have a recursive array, without references being involved. So I know that the Symfony like variable/cloner dumper. That goes for a lot of effort to detect cycles, like has some extra fun hacks to detect globals correctly for that reason, because usually you just take references but for globals that doesn't work. Derick Rethans 19:09 Right, how much of an impact is this going to have to existing code? Nikita Popov 19:12 So I like analysed the top composer packages and found, not a lot of usages. I don't remember the exact number, it was maybe five cases that break. That's not to say that it has no impact. I do know that PHPUnit eight point whatever, had such a globals use, which was fixed already because Sebastian Bergmann now, adds support for new PHP versions to PHPUnit eight and nine both. If you're using PHPUnit seven, then probably, it's no longer going to work for that reason. Of course, it also doesn't work for many other reasons, as well. Depending on which features to use, but I do know that you know sometimes if you're not using mocks, then you can often use old PHPUnit versions, but I think that's no longer going to work in this case. Derick Rethans 20:04 It's something that users of PHP and PHPUnit, probably should start testing once the alpha and beta releases of PHP eight one start happening. Nikita Popov 20:16 Right. I mean, I hope that it's not going to be a big issue. After all, this is minor PHP version. So we really shouldn't be introducing bad breaks, but at least the usage I've seen in open source project suggests that it should not be a big problem. Derick Rethans 20:33 Excellent. As I've mentioned this RFC is already been merged. So I don't really have to ask about feedback, because it's irrelevant right now. It's already there. Nikita Popov 20:44 Well, you could still have feedback afterwards. Derick Rethans 20:48 Thank you, Nikita for taking the time to explain these several RFCs to me today. Nikita Popov 20:52 Thanks for having me Derick. Derick Rethans 20:57 Thank you for listening to this instalment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast, as well as the Xdebug debugging tool. You can sign up for Patreon at https://drck.me/patreon. If you have comments or suggestions, feel free to email them to derick@phpinternals.news. Thank you for listening, and I'll see you next time. Show Notes RFC: Restrict Globals Usage RFC: Phase Out Serializable Credits Music: Chipper Doodle v2 — Kevin MacLeod (incompetech.com) — Creative Commons: By Attribution 3.0
Hans, Schepp und Peter lassen sich von PHP-Oberguru Sebastian Bergmann (bekannt von thePHP.cc und PHPUnit, online zu finden unter sebastian-bergmann.de sowie auf GitHub und Twitter) erklären, was PHP …
Hans, Schepp und Peter lassen sich von PHP-Oberguru Sebastian Bergmann (bekannt von thePHP.cc und PHPUnit, online zu finden unter sebastian-bergmann.de sowie auf GitHub und Twitter) erklären, was PHP im Jahr 2020 alles so zu bieten hat. Es stellt sich raus: nicht alles an 2020 ist eine Vollkatastrophe! Unser Sponsor Seit 2016 ist ecx.io Teil der […]
196:Late Arrivalphp,coding,web development, laravel, phpunitShow #196 - 2020-06-25 - Show NotesThis week on the podcast, Eric, John, and Thomas are back to discuss facial recognition for the third week in a row, PiHoles, PHP Security and much moreTechnical Debt / Cowboy CodingStory about LeadStream issues I caused this weekFacial recognition leads to wrongful arrest of Black man in DetroitPi-hole®: A black hole for Internet advertisements – A black hole for Internet advertisementsBlock EVERY Online Ad with THIS - Pi-Hole on Raspberry Pi - YouTubePHP Security Center | Zendphp.internals: PHP 8.0.0alpha1 is ready for testingTypingOfTheDead
195:A New Branch Of Lifephp,coding,web development, laravel, phpunitShow #195 - 2020-06-18 - Show NotesThis week on the podcast, Eric, John, and Thomas discuss renaming of master branch, SQLite with PHPUnit, and moreGitHub to replace "master" with alternative term to avoid slavery references | ZDNetDeployHQ goes down in the middle of a pushDating App LeakTim Hortons TrackingSQLite in testsFacial Recognition: Last Week Tonight with John Oliver (HBO)
Show #193 - 2020-06-04 - Show NotesThis week on the podcast, Eric, John, and Thomas discuss testing in PHP, some new proposed RFCs, new hardware, and a lot more.Twitter Will Allow Employees To Work At Home Forever Command and Conjure Remasterd Episode 100: The Final Rant - /dev/hell The Grumpy Programmer's Guide To Testing PHP Applications | php[architect] Just shaved half the runtime off my tests in CI Microsoft Open-Sources GW-BASIC | Windows Command Line Stop Using Sqlite in Laravel Unit Tests [My new keyboard - Kinesi](https://kinesis-ergo.com/keyboards/advantage2-keyboard/sErgoDox EZ: An Incredible Mechanical Ergonomic Keyboard RFC: nullsafe_operator PHPUnit and Attributes Suspect Asks for “a Lawyer, Dawg.” Judge Says He Asked for “a Lawyer Dog.” PHPUnit order of operations
We're joined by John Bonaccorsi (one of Tighten's Lead Programmers) to talk about the pros and cons (spoiler: there aren't too many cons) of using class-based model factories in Laravel.To learn more about class-based model factories, check out https://tighten.co/blog/tidy-up-your-tests-with-class-based-model-factories/
Direct .mp3 file download. We talk with Mike Pirog about the Lando Alliance, April Sides about DrupalCamp Asheville, and Chris Weber debuts his new segment, The Change Record. URLs mentioned Get Lando from Lando.dev Sponsor Lando DrupalCon Minneapolis Coronavirus information page Nerdery Update on the Status of Drupal’s New Olivero Theme Popper.js updated Update to PHPUnit 8 DrupalEasy News Professional local development with DDEV - 2-hour, hands-on, online workshop held monthly (Tuesday, April 7). Local Web Development with DDEV Explained MidCamp Composer Basics workshop - Wednesday, March 18, 2020. Drupal 8 Module Development Basics - DrupalCon Minneapolis - Monday, May 18, 2020 Sponsors MyDropWizard.com - Long-term-support services for Drupal 6, 7, and 8 sites. Subscribe Subscribe to our podcast on iTunes, Google Play or Miro. Listen to our podcast on Stitcher. If you'd like to leave us a voicemail, call 321-396-2340. Please keep in mind that we might play your voicemail during one of our future podcasts. Feel free to call in with suggestions, rants, questions, or corrections. If you'd rather just send us an email, please use our contact page.
Candente actualidad hablamos sobre la vulnerabilidad afectada a PrestaShop por el framework phpUNIT, hablamos de que es y como solucionarlo en nuestro PrestaShop
Candente actualidad hablamos sobre la vulnerabilidad afectada a PrestaShop por el framework phpUNIT, hablamos de que es y como solucionarlo en nuestro PrestaShop
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.
Today we ask the big question on every PHP developer's mind. We weigh out the pros and cons of the language, things we like and dislike, and ultimately, what keeps us coming back.
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.
Direct .mp3 file download. Matt Glaman, (mglaman) and Bojan Zivanovic, (bojanz) join Mike live from Disney World to talk about decoupling Drupal Commerce as well as the roadmap for Drupal Commerce as a project. We take a quick side trip into some blog posts Matt recently wrote about running all of Drupal core's automated tests in DDEV-Local. Interview Commerce Guys Drupal Commerce project Commerce Guys projects on GitHub Decoupling Drupal Commerce Commerce Cart Flyout module JSON:API module Composer support in Drupal core initiative Commerce Shipping Matt's blog posts related to running Drupal's automated tests with DDEV: Nightwatch, FunctionalJavascript, PHPUnit. Snowboard wrist guards Three Colors: Blue DrupalEasy News Drupal Career Online - the 12-week (3 half-days/week) best-practice focused training program begins February 25, 2019. Learn more at one of our free Taste of Drupal webinars (December 17, January 9, February 6, February 20). Professional local development with DDEV - 2-hour, hands-on, online workshop held monthly (December 12). Local Web Development with DDEV Explained - new book from Mike! Upcoming events Florida DrupalCamp 2019 - Feb 15-17 - registration and session proposals now open. Sponsors Drupal Aid - Drupal support and maintenance services. Get unlimited support, monthly maintenance, and unlimited small jobs starting at $99/mo. WebEnabled.com - devPanel. Follow us on Twitter @drupaleasy @ultimike @bojan_zivanovic @nmdmatt Subscribe Subscribe to our podcast on iTunes, Google Play or Miro. Listen to our podcast on Stitcher. If you'd like to leave us a voicemail, call 321-396-2340. Please keep in mind that we might play your voicemail during one of our future podcasts. Feel free to call in with suggestions, rants, questions, or corrections. If you'd rather just send us an email, please use our contact page.
Jake and Michael discuss all the latest Laravel releases, tutorials, and happenings in the community.
The Season 2 crew reunites. Laracon Venue: The Museum of Science and Industry Evan You Ryan Holiday / Conspiracy Jocelyn K. Glei / Hurry Slowly / Unsubscribe Marvel.app Zeplin.io Laravel: Up and Running A Brief Introduction to Progressive Web Apps, or PWAs Marcus Aurelius book - Meditations The Daily Stoic AWS Lambda Esther Perel - sample TED talk: The secret to desire in a long-term relationship The Imposter's Handbook The Millionaire Next Door The Simple Path to Wealth Editing sponsored by Larajobs Transcription sponsored by GoTranscript.com [music] Matt Stauffer: Welcome back to a special edition of the Laravel Podcast season three. It's season three but it feels like season two. Stay tuned. [music] Matt Stauffer: Welcome back to a special edition of the Laravel Podcast. This is season three but I wouldn't hold it against you if you got surprised because I have two guests with me. Not only do I have two guests but I have the OG two guests. Can you guys say hello to the people? Jeffrey Way: Hey, everybody. I'm Jeffrey Way. Good to be back. Taylor Otwell: I'm Taylor Otwell. Matt Stauffer: You may have heard of Taylor. We got Jeffrey Way, the creator of Laracasts and bringer of many of us to Laravel and then Taylor Otwell, OG Laravel Podcast, OG Laravel. We figured it's time for a little bit of a breather in season three with all these episodes and just catch up and see how the crew is doing and catch up on things. Stuff we've got on our plate for today is definitely talking about how Laracon is looking for this year, what's going on with the development of Laravel and Laracasts and everything like that. I figure the easiest and most concrete thing for us to talk about is Laracon. What is going on? How is ticket sales? How is speaker lineups? How's the venue looking? How's Chicago looking? How's everything going for Laracon right now. Taylor Otwell: I think it's going pretty well. The venue is the Museum of Science and Industry in Chicago which is a really large museum. On the South side of Chicago. We'll be in their auditorium and the ticket sales are going really good. We already sold out. That's about 850 attendees, about 50 of those attendees are going to be speakers and sponsors and then around 800 of them are going to be actual ticket purchasers from the community. This will definitely be the biggest US Laracon. It'll probably be the biggest Laracon yet so far. Although Laracon EU is usually a little bigger, so I wouldn't be surprised if they sold more tickets this year. I'm pretty excited about it. All the speakers are pretty much lined up. Some of the big name speakers that people may have heard of so far. Of course, I'll be there. Creator of Laravel, Evan You creator of Vue will be there. Uncle Bob Martin who's famous for writing some very popular programming books and just being a programming teacher will be there. Ryan Holiday, the author of several books that people may have heard of. His latest book is called Conspiracy but he also wrote The Daily Stoic, Perennial Seller, Obstacle is the Way, Ego is the Enemy. Some pretty popular books actually. Who else? Adam Wathan will be there. Several other community members will be there. I'm really looking forward to it. I think it's going to be a great talk. Right now, what I'm working on is just ironing out food, drinks, all those extra things you have to do for a conference. T-shirts, about to order those probably. Sponsors, we'll have 11 sponsor tables at the venue. We have quite a few sponsors again this year. It's going to be a packed house. Jeffrey Way: I always wonder how you keep track of everything. Matt Stauffer: Yes, me too. Jeffrey Way: Do you ever get close to the conference and think, "Oh, my god. I didn't even do that yet?" Taylor Otwell: One way I-- Matt Stauffer: Do you have a checklist? Taylor Otwell: One way I keep track is I have a spreadsheet from last year with every expense. That actually serves as a checklist. Like, "Hey, badges are on here as an expense. I should probably order those for this year." I just duplicate that every year and then I type in the new expenses and it also serves as a projection for profit and loss on the whole conference. It serves a dual purpose as a checklist and as a profit estimator for how the conference is looking to make sure I'm not way overspending. Especially, on speakers this year. We've spent probably $50,000 on speakers this year just because we several speakers that have a speaking fee and then we try to pay every speaker at least a few thousand dollars to make sure they're not just losing money coming to the conference which can happen. I don't know if you've spoken at conferences. As a listener, you may know that often it's a breakeven or maybe even a losing affair. Trying to make it somewhat worthwhile. Jeffrey Way: I've been to some where you don't get anything and that's just how it is. Look, you can come and speak but we're not giving you a penny. Taylor Otwell: [chuckles] I feel like I usually lose money. Matt Stauffer: That's most of them. Jeffrey Way: I used to go to a lot of WordPress conferences. What were they called back then? WordCamp? Taylor Otwell: Yes, WordCamp. Jeffrey Way: Maybe. With them is like they just don't have the money. They don't have the budget. You're doing that all on your own dime, if you want to go. Matt Stauffer: I'm looking through this list of speakers. There's quite a few people who I don't know of, but I've heard you guys talk about them. Jocelyn Glei, maybe? Ryan Holiday, you've mentioned him being an author. Then, there's one other person who I didn't know. Who do I not know? I guess it's just them. I think everyone else here is either, Jason Freed or Bob Martin or Evan Yu or people who are pretty reputable members of the Laravel community. Although we do have a few first-time speakers, TJ Miller, Caleb Porzio, Colin DiCarlo are all speakers-- Taylor Otwell: Collin DiCarlo is not. Matt Stauffer: He's not-- Geez, I thought he was-- Taylor Otwell: No. I think he's a 2016 Louisville speaker. Matt Stauffer: That was the year I was at home with the baby, so my bad. Caleb and TJ. Jocelyn, you mentioned Ryan. He's written a couple books. I need to go check those out. Can you tell us a little bit about Jocelyn? Taylor Otwell: Jocelyn runs a podcast called Hurry Slowly where she talks about work, productivity, burn-out, stuff like that. She's actually interviewed Jason Freed on the podcast. She also wrote a book called Unsubscribe which is on Amazon. You can check out. It's just about the overabundance of notifications and busy-ness that's prevalent in our tech world especially. I think she's going to talk about similar topics at the conference. I entirely forgot Jason Freed would be there. That's kind of a big deal. [laughter] I've been so busy with other stuff. Matt Stauffer: Let me ask you. Do you guys feel overwhelmed sometimes by all of the work you have to do? Do you feel that you can manage it fairly well day-to-day? [crosstalk] Jeffrey Way: I'm often overwhelmed by the work on my plate. My life is a constant battle of trying to figure out whether I'm overwhelmed because I don't have everything settled on my side or whether it's because we need to readjust the company a little bit. There's always a the, "Oh, Dave quit and he used to do all this high-level administration stuff so I took on all of his jobs for a while. We need to hire a new Dave." That was the thing for the longest time. "Oh, we've got four more developers than we did a year ago so there's a lot more management" or "This one client is requiring all these needs." Sometimes, it's process stuff. Sometimes, it's just I need to stop screwing around in my free time and actually, work through my email backlog, or I need to figure out how to handle my tasks better. Right now, I'm actually doing really good. It's because I've spent the last couple of weeks really putting in a concerted effort. We also have hired someone who is not joining us until mid-May, who's going to take probably a third of my job off my plate. It's funny because I was actually-- That whole thing, there was this guy, Dave, who managed all this. A lot of those responsibilities are going to be back off my plate soon, so I'm getting to that point. I usually can tell, "Do I finish my day with an empty email inbox and a task list with a couple items left on it and a clean desk? Do I finish my day with 70 emails still in my inbox, 20 things in my task list, a big pile of paper on my desk." Usually, those are the signs for me of, "Am I struggling to keep up, or am I actually on top of my life?" Matt Stauffer: What about you, Taylor? Taylor Otwell: I was just thinking I feel less overwhelmed by the work, and more overwhelmed by the expectations of everything. Because I don't really have that much I have to work on every single day, like Forge is going to run so I just have to answer the emails. It's a little different, I guess, because you probably want to crank out videos. I don't know what your schedule is and then, Matt probably has his daily tasks. For me, it's this expectation of somewhere out in the future, I have to do something impressive again. Matt Stauffer: Do something amazing. Taylor Otwell: I have to get up on stage and speak about it and it has to not fail. That's the pressure I feel really-- weighs on me every day, basically, because at Laracon, there has to be something cool to unveil, which, nobody panic, we are working on something but things can come up, or problems can arise. It could be buggy, it may not be finished in time, and that stuff's really overwhelming, more so than just the daily routine. Like Laracon itself could-- There's expectations there for it not to suck, for people to have a good time, for the food not to be terrible, for the speakers to do well, all that stuff is high expectation, too. Matt Stauffer: Had you guys seen the grid of urgent versus important? I'm trying to remember who it is, but somebody from a long time ago, basically, drew a grid and any given thing that's on your plate as a pressure should be doing can be urgent or not urgent, and important or not important. The really interesting thing is that you can put all the things that are pressing on you into that grid and figure out which of the quadrants they find themselves in. The things we're mostly like to do that are most wasteful is the urgent and not important. The things we're least likely to do that sounds like, really, what's on your plate a lot, Taylor, is the important and not urgent. It's the things that don't have that immediate time pressure but are the most important. It sounds like a lot of your life is important but not urgent which I know those are the hardest things to have the discipline, the focus on. Is that something where you have developed practices to make sure you're not just letting that stuff slip? Taylor Otwell: Past couple of years it's been trying to start really early on stuff like Horizon and then the thing I'm working on for this year's Laracon. I don't know. I do agree because Mohammad's going to take care of a lot of Forge stuff for me. I don't really spend a lot of time working on those features lately. I would say yes, you're right, it is important but not urgent. That is a challenging spot to be in. Jeffrey Way: Plus you have so many products. I wonder does it ever get to the point where you think "Well, I'd love to do another one but I just don't have the capacity to maintain yet another project" Taylor Otwell: Yes. There is a sense of when do you say "I did what I set out to do." This is what success is, basically. I should just maintain what I have and be happy that it got this far and not really try to overwhelm myself with a new impressive thing year after year because-- Most people will never reach the popularity of something like Laravel ever. I should just enjoy that maybe and not really try to stress out about creating the next big thing all over again, every single year. Which I think there's some merit to that as well but people don't really like that I guess [laughs]. Matt Stauffer: It's a little bit of the Apple thing, right? Is a WWDC where they don't completely blow your mind an acceptable WWDC? I would say "Yes man, I'm happy with what I've got. Just don't break it". Taylor Otwell: Yes. I remember Steve Jobs saying not to compare Laravel to Apple in any way really but he said something like most companies are lucky to ever invent one amazing product, They had invented the iPhone, the mac itself was amazing and then iPhone and iPod and all the stuff that came with it. I don't know. At some point, there's only so much you can do. I'm going to keep trying this year we'll see. Matt Stauffer: Jeffrey, what about you? Jeffrey Way: I'm okay right now but it's more of the anticipatory type of thing because my wife's pregnant so we're going to having a second child. We're not going to be having two children. Matt, I know you have more experience with that than me but it's stressing me out a little bit. Then, also this is the first year I've been working with a UI guy. I don't know what you call him, a designer or UX, I don't know what the terminology is anymore but he's doing really great work but every time he cranks out something new it ads to the backlog of stuff I have to implement, which I'm very thankful for but I'm kind of anticipating an insane amount of work in the next five months. I was just curious how you guys handle it. Then, there's also that thing where I worry sometimes when you feel stress and anxiety it's like to some extent you're creating it yourself and it's hard to determine, is this something I'm just doing myself and I am entirely in control of or are you not in control of it? That's something I think about a lot. Is there a way to turn that switch off when you need to? I don't know. Matt Stauffer: I know that you have at least some, like talking about that urgent versus not urgent thing. I know you have some urgency because there's this expectation of a certain timeline for delivering videos. Are there a lot of things on your plate, for work, that are in the longer terms? You mentioned one thing being the implementation in the UI. I know that you do visual refreshes occasionally, although in your latest podcast you talked about how a lot of that was early days and it probably will be a little bit less the case going on where you feel like you're getting more of a handle on things. Do you have a lot of things that are in the longer term bucket? Or are most things still locked in the immediate video production timeline? Jeffrey Way: Most is in the immediate. The UI work we're doing will probably be next year or at the end of this year. That's probably the most long-term work thing I'm doing. Most of it is immediate. It's very difficult to crank out content all of the time. Sometimes if I go even four days without something new I will get a tweet or somebody is complaining. It's like, you have to understand I've been doing this for three years, there's like thousands of videos. At some point, I'm going to have trouble thinking of new stuff to cover. I'm amazed every week I'm able to, I'm not complimenting myself, but I'm amazed th I'm able to think of something to publish every single week but that does wear on me a little bit to finding things to cover every week. Matt Stauffer: I hit episode 100 of the 5 Minute Geek Show and I just was like you know what I've talked for 10 to 15 minutes at a time for about 100 episodes and I don't have anything else stuff to say. People keep saying bring it back. I'm like-- Jeffrey Way: Yes and I think that's-- Have you close that down? Is it done? Matt Stauffer: It's not over. It's just on the hiatus. It's on hiatus until I come up with something else to say. You know what I mean? Jeffrey Way: Yes. Matt Stauffer: I'm not saying it's over because I'm sure that moment will come again, but right now, I'm just like, "I don't have anything else to say." If I felt that pressure like you do, to keep saying things, man-- granted, everytime the new tech comes out you can choose to go learn that tech and go to it. There's some things you can reach for, but still, I totally identify with what you're saying. It's just at some point, I just might not have anything else to teach right now. [laughs] One real quick, on ask for a pro tip, two kids. The big shift for two kids for me-- Taylor, I want to hear if you have the same perspective as-- With one kid, there's always the possibility for one parent to be taking care of the kid and the other parent being an adult. With two kids, there's now-- Even if one parent takes care of the kid, the other parent is taking care of another kid. All of a sudden, those rests that you get-- What I can imagine is, once you have three kids, it's even crazier. Because now, all of a sudden, there's never a one on one. That was the big shift that I noticed with the second kid was. Let's say, the other parent is feeding the baby or something like that, you're not cleaning up, you're taking care of a three-year-old or whatever else it ends up being. That's the biggest shift for me for a second kid. Jeffrey Way: Sounds stressful. Matt Stauffer: [laughs] It's not that bad. It's just a perspective shift, I think. Jeffrey Way: I have heard one bonus is that, like in your case, Matt, your oldest probably helps entertain your youngest quite a bit more, whether or not, depending upon you and your wife at all times for entertainment. Matt Stauffer: The older she gets, the more they play with each other and the more moments we get where they're playing together in the toy room for 45 minutes. We go, "Oh, my gosh." We sat down and had an adult conversation. That's definitely, definitely a boom. All right, that's what's going on with Laracon. You said the tickets are already sold out. Do you have a waiting list like you have previous years, Taylor? Taylor Otwell: There's not really an official waiting list right now. As people email me, I actually do put their name in a little file. I have sold a few tickets that way, but there hasn't been a lot of cancellations lately. There's not really any tickets to give out right now, anyway. Matt Stauffer: Got it, all right. I have a couple questions, but before we do that, let's talk Laracasts real quick. What kind of stuff have you-- let's say, anybody who hasn't been to Laracast for a little while, what have you been covering? What's your latest technologies that you've been looking at? Is there anything exciting you want to share with people? Jeffrey Way: Yes, sure. Let me take a look. Been doing a bunch of things lately. I finally covered Laravel Echo in full. Somehow, that was one of the things that I just missed a year ago. I went through that top to bottom. I think if you're intrigued by that, on how to communicate with the client, I think that would be really useful. It's a series called Get Real With Laravel Echo. Some things, I just have to refresh. That's one of the worst parts of my job is, even if it's from 2014 and it still works, it's like, there's just a few differences where you sort of have to record it all over again. That's the worst part of my job. Other than that, one of the things we're working on right now which I'm excited about, it's a series called How To Read Code. The whole point is not for me to write code, it's to work through the process of how you learn from the code that other people have written. There's that phrase about, "If you want to become better as a developer, you have to--" I can't remember what it is. You have to read a lot of code, you have to write a lot of code, and you have to learn, I guess. A lot of times, I think young people really get into the learning phase where they're reading the books and they're watching the videos, but they're not actually taking enough time to read code that other people have written. I notice that's sometimes a black box. People are afraid to dig behind the scenes and learn how these things are constructed, so they stay away from that. Then, also, they end up not writing as much code as they should, because they don't know what to build. This is the thing that comes up a lot. I learned this from students, is they don't know what to build. They haven't been hired yet, they're trying to think of projects they can flex their muscles on, and they have no idea where to start. With the How To Read Code, Taylor, we're actually going through the Laravel.com source code. I haven't told you about this. Taylor Otwell: Nice. Jeffrey Way: We're just pulling it up on GitHub, and we're figuring out every step, like, "Okay, if there's this repository for the markdown files, well, how is this project getting access to those markdown files and how is reading it and parsing it and replacing the URLs? How is versioning being handled?" What's fun about it is I don't have any experience with that codebase, so it's how I would exactly figure out how things are constructed. It seems like the feedback's been pretty good. Once again, I think, for so many, it's a black box. You're kind of scared to dig in because you don't know where to start. I encounter this a lot, so I hope it's useful. Then, other than that, I've been working with this UI guy. It's been fun because most of the time, I do things myself. That's a lot of coding in the browser, writing a lot of CSS and zeroing in on something that doesn't look horrible, which I'm not very good at. He is so much more systematized. He has me set up with this-- what is this app called? Marvel? Are you guys familiar with this? Marvelapp.com. It's new to me. It's amazing. He'll share a link with me and it's like an interactive website where he can swap things out, he can show me interactions and animations. Then, once I signed off on it, he sends me a link to this Mac app called Zeplin, zeplin.io. It's amazing because I'm so used to-- When extracting designs, I use Photoshop. If there's some SVG, I have to cut it out and save it as SVG. Very hard, creating new layers all the time. With this, everything is just clickable. If I need a particular icon, I click on it, and there's a button that says "Save as SVG." This is all new to me. I don't have any experience with tools like this. It's been a huge benefit to me in the last couple of months. I love it. Matt Stauffer: It's very cool. I'm going to try and go back through, listen to this, put all this in the show notes, everybody. Well, real quick going on with me. I'm updating Laravel, up and running for 5.5, so that's exciting. We finally got approval - actually, 5.5 or 5.6, I'm not sure I remember. I think we might be doing 5.6. I was going to do LTS and I think we've picked 5.6. Finally got my editors to sign off in doing that. I've got Wilbur Powery, who's doing some of the groundwork for me, and just reading through all the change logs, and making a list of all the things that are out of date, so that I don't have to do that work, so that he can just give me that list, and I'm going to sit down and write. The hope is for that to be some time in the fall for us to have edition two, so that's fun. I just left a project where I had been writing code, basically, for 20 to 30 hours a week on top of doing my normal job at Tighten just because we had a project that hit a point where no BLs was available. I felt that I just needed to fish it out. That's part of why I'm feeling so good right now because I'm going back to being a real boy again. [laughs] I'm not going to make any promises I keep making like, "I'm going to blog again. I'm gonna newsletter again." I'm actually feeling this possibility, especially when that new employee joins in May that I might actually start being a human again. I have said that at three or four times since my daughter was born two years ago and it hasn't happened yet. Who knows? Maybe that day will come. Jeffrey Way: That's great. It's great news. Matt Stauffer: Yes. That's very exciting. Okay, so I have a topic for us to talk about. I didn't prep you guys for this, so sorry about that. There's a couple of topics of conversation that have been coming up really recently at Tighten about - and if anybody listens to Twenty Percent Time podcast, you'll know at least a little bit about this. Talking about JavaScript versus PWAs versus straight Blade apps versus Blade apps that have some JavaScript components. First off the bat, before we go to the deeper conversation, I want to talk about PWAs. I want to see, have you guys dug into that at all? The iOS has just pushed out some of the core features that would make it so that you can actually write a PWA and have it work on iOS. This is the first day where you can actually even realistically consider building one that would work on the most modern devices. It's like when Flexbox first finally actually worked versus like, "This has been a thing for a while." We haven't written any production PWAs for anybody, but it's finally a point where we're like, "We can." Is that something you guys have dug into that you're even interested in or is it like, "Hey, it just became legitimate a week ago, so now, maybe, I'll put my brand on it"? Jeffrey Way: Yes. Beyond a blog post or two, I have no experience with that at all. Like you said, it's always tricky. Do I try and invest my time in this if I can't use it too much yet? It sounds like it's now becoming a possibility, but, for now, I have no experience at all. Taylor Otwell: Yes. Me either. Matt Stauffer: Okay. Well, I have no experience other than I did a whole bunch of research to write that blog post, November 9. Jeffrey Way: Right. It's one of the ones I read [chuckles]. Matt Stauffer: Yes. Nine months ago I did all that and then, basically, I said, "I'm going to go build some." Then, I discovered that it didn't even work on iOS, and I said, "Well, maybe I'll hit pause and all that until iOS supports it." They do, and I know that Keith, who works at Tighten, has been doing a lot more thinking about that than I have. I've been pushing him to-- with all his copious free time he's on at this point, he and Samantha are nearly as busy as I am - to see if he can do a part two write-up now that it's viable. I'll see if he can do that. Jeffrey Way: I'm curious to what extent it's viable. In the latest browsers, that's the idea? Matt Stauffer: Yes. Basically-- Jeffrey Way: What's the fallback look like? I wonder. Matt Stauffer: In theory, PWA should work on fallback browsers. In theory, it's not like it's not going to work, but it's more like it's just going to be a website with JavaScript versus the value that a PWA is going to provide. You don't want to really go hole-hogging to something, expecting it's going to be a PWA where people can use it offline, they can use it when their internet goes out, it's going to save stuff, stuff like that, and then have it not work on the major browsers. We're basically at a point where all the major mobile browsers are going to be little work with it. I don't know what the whole mobile Opera situation is like because I haven't dug into that. I know that we're at a point where literally all iPhone users couldn't even use PWAs up until a week ago. It was very non-viable up until a little bit ago. Now, your mobile Chrome, and your mobile Safari, and all those are all possible to use it. The biggest thing with the PWA is just it's a lot of work. It's a lot of work, and it's a lot of learning, and it's a lot of different ways of thinking about things because you're having to make things, basically, function regardless of whether or not the internet is there. It's that biggest shift in perspective over anything else. There's a lot of complexity in architecture that you need to introduce to make that happen. The good thing is, people are building tooling to make that easier, but it's something where you're not going to do it unless the client definitively needs it. I can imagine maybe you eventually building a Laracast PWA if you really wanted to so people could go on a Laracast, open up the PWA in their phone, in their iPad, and then tap the seven videos they want to download so they can watch them on a plane or something like that. That might be the possibility for it. But I still think the vast majority websites won't be PWAs because it's cost and you got to be sure that you're actually getting the benefit. Like you said, if most major browsers can't use it, then you're not going to get that benefit. We're now to the point where most major browsers could get the benefits so people should start learning about it. But again, it's just really early days right now. Jeffrey Way: Okay. Yes, I find in general, most of the apps I build are that combination you said. A little Blade, a little Vue, sometimes they're interconnected, that and something that the sort of apps I build. Although I find it gets tricky. I find that I do want to reach for something a little different. I do sometimes feel like, "If I just built this as an SPA entirely, this would be a lot cleaner." I think a lot of Laravel developers probably end up in the same boat where you're trying to do both at the same time. It gets tricky because you often end up reproducing the same logic in two different locations: one for the comments side and one for your back end. I think it's a common thing developers in our space are going through right now. Matt Stauffer: That's the second part of this conversation so I'm glad you transitioned to it. We're having this internal chat where Daniel Coborn is basically saying, "Look, most of the sites were hired to do or eventually are going to have some JavaScript so why don't you just go whole hog in the first place?" Caleb is saying, "I want to build Blade apps that have little widgets, and I'd rather explicitly do all the work in my controller and then pass it in these props to the Vue, which is when it comes up." I'm saying, "I want to do all Blade until I find a definitive need the JavaScript's going to happen. When that happens, then I'll modify it the way it should be. We have this kind of continue or whatever. We chose as a different side. I wanted to hear from you guys. If you were to start a new app today, are you in the world where you say, "You know what? I'm going to do Blade and then I'll modify it." Are you in the world where you're like, "You know what? I'm just going to do single-page app all the way." Or are you somewhere in between? Jeffrey just answered a little bit so I guess Taylor, what's your approach right now? Taylor Otwell: The latest thing I wrote which hasn't been unveiled yet, I did basically build it as a single-page app using Vue and Vue Router. Honestly, I really like it. I think Vue Router is pretty nice and easy to use. I think for this particular use case, it just solved the bunch of problems that we would have had trying to make it all Blade. I feel like my use cases, both times I've interacted with Vue Router, which is Horizon as a single-page app, basically, and the new thing. But then, there are unique situations where I wasn't having to duplicate a lot of rules on the front end. Either you authenticated to view the whole thing or you're not. There wasn't a bunch of other authorization that had to happen for various little features. That made it a little simpler, I feel like, to build it as a single-page app because I wasn't having to duplicate a bunch of junk. But if I was going to build something like Forge as a single-page app, I probably would have a little more duplication on various things. I don't know, man. I see Daniel's point to an extent that it does feel good to just go whole hog and embrace it because it feels nice to do it all in JavaScript if you go down that path. I don't know. I think Caleb's point, I feel that pain most often on authorization. I feel like than anything else. Jeffrey Way: Yes, absolutely. Matt, I'm curious about your point. Because I have seen a bit of a backlash to JavaScript in general, where people think, "Okay, you're getting some extra interactivity but the complexity you introduce to make all of these work is sometimes insane." Just the fact that Mix has to exist to make that build process somewhat easy to understand, shows how complicated this stuff can be. I understand exactly what Taylor's saying but I also get the angle of, "Let's put this off as far as we possibly can." Has your thinking on that changed in the last year? Matt Stauffer: Yes. I would say that I love Vue, I love React, I love single-page apps when they're appropriate. I think that knowing what a lot of projects Daniel has spanned recently, and that type of thing that I know Taylor is working on right now. I would pick SPA. I pick Vue Router SPA and I'd pick an API first in that context but I think that we can do that and we can then assume that that is always the right way to go forward. To me, that's not the case at all because of what you just said. I think testing is harder. I think debugging is harder. I think NPM and all the node modules issues breaks more. I think the entire complexity of this system is significantly higher. I think onboarding new developers in the system is more complicated and I want to make sure that it's not because I know PHP better than I know Javascript. I've been writing Javascript for as long as I've been writing PHP. Granted I haven't been writing React and Vue as long as I've been writing Laravel. I think I understand them relatively well and just the whole system everything is more complex than an all Javascript app. I am willing to make that statement and so to me- Taylor Otwell: The testing is definitely more complex. Jeffrey Way: Yes. Matt Stauffer: Yes. So to me, if I'm in a place where I can accomplish it with Blade then I'm not going to introduce any Javascript. If I can accomplish with Blade and the occasional Javascript widget then I'm going to use it with Blade and the occasional Javascript widget. That doesn't mean I don't believe that there are plenty of apps that are better as all Javascript or maybe even not using Vue Router or whatever but like a Javascript page that navigates to another Javascript page so you're doing your React containers or whatever else it ends up doing. I'm 100% on board with that possibility but I need to be convinced that that's the way to do it before I go there. Jeffrey Way: Taylor, for the SPAs you're building, when it comes to testing, are you doing endpoint testing for your backend code? In addition to that, how much client-side testing are you doing? Do you have tons of [crosstalk] Taylor Otwell: I wrote all of the endpoint test and there's hundreds of them for a new project and then we haven't even written the front end test yet, mainly because I'm working with other people on this. Of course, I have Steve, my designer, and then I have another person working on front-end stuff. It's also complicated by the fact that this is a package, it's not an app that Dusk is really easy to pull in to and so we haven't really toyed around with making Dusk work in a package environment yet. I don't know what Dusk's going to look like. We may end up using some kind of Javascript solution. There's just so many little subtle interactions on the front-end that are going to be one, important to test and two, hard to test I think. I don't know, we'll see I haven't gotten there yet. Jeffrey Way: Yes, I'm curious to see how you figure that out. Taylor Otwell: I would like to pull dusk in and just use it to test the package. Ideally kind of like the test bench for the back end which I used to write all my endpoint tests. Hopefully something similarly -- we can do something similar to that with Dusk, we'll see. Matt Stauffer: I hadn't thought about that because I was like, "Oh yes, Javascript just use Java--" but it's not, it's multiple pieces. We have found that once you put the work into the Javascript testing if that thing is full-on Javascript you can get it to be tenable? I feel like Javascript testing is, in our world, is probably the next great hurdle for us to make simple for people. Basic Laravel testing was one hurdle and then, what do you call it?, your package Jeffrey that was eventually pulled in the core like application testing that was the next hurdle. Gulp was a hurdle and Mix was a hurdle. These are hurdles where they're really complicated things that we look at and said, "You know what? People in the community are needing this to be simpler" and someone sat out usually one of the two of you sat out to make it a lot easier. I know that there's at least two people talking at Laracon about testing. Testing in Javascript and stuff like that. I'm super excited about the possibility that -- I thought there's two. I know that Samantha is at least. Her talk is about full-stack testing strategies. The reason for this is because at Tighten we're always asking this question of, what are our different ways of testing the whole way up and down the stack? Samantha's our resident React guru and we've had quite a few React developers at this point but she's the lead in thinking there and she's been asking this question a lot of like, "What does testing look like?" what I told her was like, "I'm going to wait until you give this talk to demand this of you of you but I want you to make it really easy for me and any app to write a Javascript test" I know Dusk and I know Laravel and PHPUnit but I want you to make it super easy for me. I'm hoping that that's what her talk is going to do for me and for everybody else. No pressure, Samantha. [laughs] Jeffrey Way: That would be great. I think so many times developers don't think about that. I think maybe they get too deep in the woods thinking, "okay, this is quite you have to do. You got to get this and this and this and this and this and then pull in these 8 dependencies then you're ready to go." They forget that to a newcomer that's horrible it's so frustrating. The view test utils library works great but just to get to the point where you can start writing your first test it's a lot of work. In many cases like this, it's not spotlighting them specifically but in so many cases like this you find situations where, "This could be significantly easier to get started" and it's not a badge of honor that you have to go through so many hurdles to write your first test, it should be easier. Matt Stauffer: I like that as a metric. I would like to have the ability to write a Reactor Vue test out of the gate. The same way that with a new Laravel app, I can write a test out of the gate without. I literally open up example test and just change some letters and I'm writing my test, that's brilliant. That was not what writing tests in PHP unit used to be like. It's not as if PHP unit is easy to bootstrap but Taylor and company did the work to make that easy, and you did the work to make it easy with application testing upon the core. I'm hopeful that we're we're moving in that direction. Alright. JavaScript, backends, Laracon , Laracasts, Laravel up and running. What are you guys learning these days? Are there any books you're reading? I know Taylor you've been talking about stoicism a lot. I started that one book, the really old one is it Marcus Aurelius or something like that? Taylor Otwell: Yes. Matt Stauffer: I started the book and I'm just moving really slowly through it. Could you could you give me the TLDR elevator pitch for stoicism? Is that is that possible? Jeffrey Way: What is stoicism? Matt Stauffer: Yes. What is stoicism, Taylor? Taylor Otwell: I think the one-sentence thing is this? It reminds me of that serenity prayer, I don't know if you ever heard that where stoicism is very focused on not worrying at all about the things that are out of your control. They define the things that are in your control as only your own boss, basically. Your health is not in your control, your job is not really, it's influenced by external factors. That was a little confusing to me at first because some things, say you're in a tennis match and you're facing someone, and whether you win or not is partly in your control, but it's partly not. I was always confused by that from a stoic perspective. There was one book that helped me resolve that situation, where it was like, You want to internalize your goals a little bit. To succeed at the tennis match is basically to give it your best so to speak. Whether you win or lose, is out of your control at that point, but you're still succeeding as long as you prepare and practice to give it your best shot. That's the main gist of Stoicism is not worrying about anything that's out of your control. Only worrying about the things you actually can control. Everything revolves around that. Matt Stauffer: I like that. Taylor Otwell: Basically Marcus Aurelius' book re-visits that theme a lot in various circumstances. One of the other popular stoic books, probably the other most popular Seneca's letters. He visits that topic on a variety of issues. Death and dying, sickness, what it means to be wealthy, and be a stoic because he was pretty wealthy. Of course, Marcus Aurelius was the Emperor so he was extremely privileged and wealthy. I think Marcus Aurelius' book is surprisingly relatable for a Roman Emperor that lived 2,000 years ago. [laughter] A lot of the things he mentions struggling with are very relatable. I was surprised at how modern it all came across really for someone that you would think would be very disconnected from our life experience. Matt Stauffer: Did I remember you saying something along the lines of Ryan Holiday, the guy who's speaking doing something about stoicism? Taylor Otwell: Yes, he wrote the Daily Stoic which is a really popular book. There's 365 little chapters, every day it's like a little daily reading. He expounds on it in a couple paragraphs. It's a pretty cool little book. Matt Stauffer: Cool. Taylor Otwell: On the tech side what I've been looking into a lot recently is containers, AWS, deployment, stuff like that. Serverless stuff like AWS Lambda. I feel there's gold in those hills somewhere. [laughter] I just feel like it's not really being presented and packaged up in a very approachable way right now. Because AWS feels very low level, it gives you all the tools you need to make things happen but you still have to tie them together in pretty complicated ways to build something useful. Probably the person that ties that kind of thing together the best is something like Heroku but just playing with some of those technologies. I think AWS Lambda is really cool. I really love the idea behind it, where basically you start out with just a function. By default, it's just like a JavaScript function that receives some arguments. You think of it like a little artisan command that receives a payload from the command line. You can invoke this function and pass it, little arguments. Then you can do whatever you want, you never really have to think about the underlying server. I think their concurrency limit is like 1000 concurrent tasks running at a time. It's pretty scalable for most situations, but you can actually do pretty interesting things like you can run a Laravel app on AWS Lambda which I actually did this week. I'm using some tutorials that people had written. It's a really interesting technology and like I said I feel like there's cool stuff there that just needs to be mined out, repackaged, and presented to people in this sort of digestible way. I've been trying to digest it myself and it's very complicated and there's actually a real lack of quality, like guides and documentation on how to do anything actually useful. There's lots of like, "Let's deploy a hello world" nginx page to elastic container service but how do I do zero downtime deployments reliably? How do I set up all my key workers reliably?" All that stuff is not there. Jeffry: You guys are making me feel bad. I'm trying to think of what I'm learning right now and the answer is nothing. I can't think of anything. Taylor Otwell: I've been playing Rocket League like an hour and a half a day. [laughs] Jeffrey Way: I think sometimes it's good to not always reach for something new but to get yourself in a habit of just a daily routine of every single day I'm going to chip away at this. There have been plenty of times where I'm really pushing my boundaries for a little bit trying to learn something new but I can't say that right now. I'm feeling horrible right now. Matt Stauffer: I can tell you, Jeffrey, I'm not learning anything about code right now so don't feel horrible. Jeffrey Way: Really? Matt Stauffer: I'm learning things. Let me tell you the things I'm learning and I bet you you'll have something related. I'm listening to this woman, Esther Perel, who's this relationship expert. I'm listening to her stuff nonstop. My wife and I are both listening to all her stuff. It's really good. It's like this progressive thinking about relationships but every time I've listened or read to people who are talking about this type of relationship stuff they're like, "By the way, you should just have open relationships and be married to 20 people and have sex with all of them. It's no big problem." I'm like, "That's not me so much." But she has progressive thinking that kind of throws of some of the old croft that we brought along with us but stills very much focused on, "Well you're married to this person, stay married to this person." It's helpful. It's like opening up my mind a little bit. The other thing I'm thinking about is money. I may have talked to you guys a little bit I've been- Jeffry: Yes, you're into that lately- Matt Stauffer: I'm so into it. I just got obsessed with how much I hate having a mortgage. It became this massive thing for me. I literally just looked at my mortgage statement and I think this is it, beginning balance, applied balance, and ending balance. I lived in my house for I feel like several years now. It's atleast one year and it might be two years. I'm paying thousands of dollars a month towards my mortgage and I've applied $5,000 to my balance because I'm paying everything to the interest this whole time. I just feel like I'm in this awful system. You guys know this but I've been listening to these audiobooks. One of them is the millionaire one, what's it called? The Millionaire Next Door and then the other one is The Simple Path To Wealth and just focusing on like really simple investment strategies, really simple decisions you can make. I'm not going to talk about -- I could talk to you guys your ear off in the next half hour but to me, the two things I've been learning about are simpler, healthier approaches to money and investment. Then relationship stuff where it's kind of like helping you understand what kind of garbage you're bringing into your marriage or your relationship but in a way that is for the focus of you staying there, to that person long-term versus a lot of the other alternative. You know, half ways to thinking about it. Jeffrey Way: I live everything you say on the finance stuff because you think the more you can simplify your financial situation the better it's going to improve your relationship as a result, too. I think it's the number one or the number two cause of fighting in relationships, is financial issues and of course, not everyone is in control of it. The more you can simplify your finances then and not buy a new car and instead buy an older car or something you can afford. The more you can simplify it, the better it's going to improve your relationship with your wife or your spouse and your kids. I see nothing but good things there. One thing I am doing, though -- This may interest you, Matt, when we had the Laravel podcast months ago I said, "Years ago I stopped playing guitar and the interest I had left" it's come back in the last couple of months. Matt Stauffer: That's awesome. Jeffrey Way: I know and I'm very happy about it. I went and bought a guitar and an amp. I've been playing lately. You can maybe see it in the back there and it's funny to see the parallels with code. I'm kind of getting in -- I'm approaching guitar from a more mature point of view, I guess. I'm getting more into this idea of like, "Okay, every single day I'm going to be working on this. I'm going to take a very fundamental approach to building up skills, whereas when I was a kid it was more, "I want to learn how to do this. Let's figure out how to do this as quickly as possible." Now, I take a very different approach to it, which I feel all of this parallels with code. It's very funny. I noticed on Twitter the other day a bunch of people were talking about how many coders have some interest in music or have some experience with music. It's interesting, the overlap there. Matt Stauffer: I just read the intro to this Imposters Handbook thing that I tweeted out. I wish I could remember the guy's name because he's a well-known software author but he's talking about being a saxophone player. I remembered having read a book by him in the past where he is making a lot of those parallels. Do you know who that is what is? Jeffrey Way: What is it? Hanselmann? Matt Stauffer: It wasn't Hanselmann. He wrote one but then it was the one after that. You guys would definitely know who this guy is but I just remember that he had studied saxophone. I remember him talking about that in his book that I read but yes, who knows who wrote that. Anyway, I'm only a chapter into this Imposters Handbook but I like that. Jeffrey Way: Very cool. Matt Stauffer: We are at 50 minutes, which is usually when we start ramping it down. Is there anything else going on with you guys, anything you've been thinking about or learning or exciting about that you want to get a chance to chat about? Taylor Otwell: Not for me that I haven't already discussed, I don't think. No, just what I already discussed but we're working on new Forge things, trying to make people's lives easier and Envoyer is getting redesigned, which it hasn't gotten since I originally wrote it in bootstrap, so that will be nice. Other than that, I think that's about it really on my end. Jeffrey Way: Matt, can you share any news about who's coming up on the podcast? Matt Stauffer: Oh man, I don't actually know who's next but let me go pull up my Trello board real quick. Basically what I'm trying to do is, I've been a little sneaky on this but I'm trying to mix up people who everybody knows, who everyone's been waiting for because every once in a while people are like, "Why has Adam not been in the podcast or whatever". I'm trying to mix up those people who I know that people are anxious about, for the people who they're not anxious about but I know that they're going to be really excited when they hear it. There's a couple of people who I know everybody want to hear and I'm trying to spread them out like every three or four guests and then be like, "Yes, but there's these other people that you don't know are super awesome." Some of my favorite responses have been people like, "I've never even heard that person's name before and now I want to be their best friend", I'm like, "Yes, I did my job well." Of course, the well-known names in Laravel are all going to get interviewed. I've got a list of dozens and dozens and dozens of people. I know that Adam's going to be coming up soon for sure and your Eric Barnes and your Chris Fidao's and them are going to be up in there, of course, as well and Freek and folks like that. One of the things I did also, was I didn't interview anybody from Tighten because I didn't want to seem like it was nepotism, but there's quite a few really interesting people at Tighten, so I think the Tightenites are going-- I'm going to start slipping in some Tightenites and some Vehikl and Spatie folks. I'm going to start slipping in some of those folks as well too. There's a huge list, I mean, you guys, I could do dozens and dozens and dozens of more just from the list I originally spit out before even touching any of the suggestions I got on Twitter. There's a lot of good ones coming. Jeffrey Way: I'm excited. It's been fun hearing from people that I'm not overly familiar with. I think that's a very wise choice you've made. Matt Stauffer: I'm happy to hear it, I had so much fun. Of course, I miss you guys which is why we're back here for today. I figured we can do this one, every dozen or something like that, keep that lines of communication going. Jeffrey Way: Yes. Cool. Matt Stauffer: All right guys, feeling good. Anything else? Jeffrey Way: That's it. Matt Stauffer: It was a ton of fun talking to you guys and I can't wait to see you in a couple months. Until then, thanks for hanging out and we'll see you all later. Taylor Otwell: Alright. See you. [music]
Jake and Michael return to discuss the latest Laravel releases, community projects, and upcoming changes.
Recorded December 28, 2017 Topics Holiday recap SDPHP/SD Laravel year in review 2017, the year of Laravel? Symfony 4.0.0 released PHP 7.2 released Visual Studio Code for PHP Developers The Future of HHVM https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0 MongoDB Apocalypse Is Here as Ransom Attacks Hit 10,000 Servers PHP 5 is switching to security fixes only In Memoriam
Our attempt to make a wishlist for new PHPUnit features devolves into yet another discussion of VS Code.
Chris and Ed do an extremely rare daytime recording of the show on the American Memorial Day holiday. But why is a Canadian not working on an American Holiday? You’ll have to tune in to find out why along with some thoughts on mentoring and why the current crop of browser-centric testing tools are completely shit. Thanks to Ben Ramsey for his poetry choice and Chance Garcia for allowing us to bring another health issue to people’s attention. Do these things! Support us via our Patreon Buy stickers at devhell.info/shop Follow us on Twitter here Rate us on iTunes here Listen Download now (MP3) Links and Notes Please support Ed’s efforts to make OSMI his main gig! Both Chris and Ed will be at CakeFest 2017 WebDriver is an API in heavy use at Mozilla (and elsewhere) for doing browser automation work Ed talked about a testing tool called Fake from his webOS development days that promoted a very different testing paradigm Chris has done browser automation in PHP using Behat, Mink and a lot of swearing Most current browser-centric UI testing tools are Rube Goldberg machines Great blog post from the ClojureScript community showing off property-based testing and immutibility Also some great work being done in PHPUnit with snapshot testing
Jake and Michael recap a relatively quiet period of change on the Laravel landscape, talking about 5.4 maintenance releases, upcoming features in Laravel 5.5, and some contributions from the community.
Part 2 of 2 - Sebastian Bergmann, the maintainer of the PHPUnit testing framework, came to our office in Cologne, Germany to talk with Campbell Vertesi (@CampbellVertesi) and me about PHP, PHP FIG and the PSRs, and of course testing. It is another in the series of interviews we carried out with important and interesting people from the PHP community in preparation for DrupalCon Asia in Mumbai. Read the full post and see the conversation video at the Acquia Developer Center: https://dev.acquia.com/podcast/223-benefits-testing-php-fig-drupal-8-sebastian-bergmann-22
Part 1 of 2 - Sebastian Bergmann, the maintainer of the PHPUnit testing framework, came to our office in Cologne, Germany to talk with Campbell Vertesi (@CampbellVertesi) and me about PHP, PHP FIG and the PSRs, and of course testing. It is another in the series of interviews we carried out with important and interesting people from the PHP community in preparation for DrupalCon Asia in Mumbai. Now we're releasing those to you! Read the full post and see the conversation video at the Acquia Developer Center: https://dev.acquia.com/podcast/222-drupal-meet-php-fig-and-phpunit-sebastian-bergmann-12
90% of developers don't test their code. Made up percentages aside, I think you'll find that this is fairly accurate, when you gather the entire development community. How come? With so much evangelism across the board, what's the reason behind this hesitation?
## Automated Testing * Before we actually get started talking about Red Test, can we take a step back and talk about what automated testing is in general? * I am sure you are all aware of manual testing and QA. Once you build a site or a feature in the site, you go to the browser and test it out. As an example, you added a workflow to your blog post. You will go to the browser and test whether the blog you create gets the draft state. Then you will log in as an editor and you will move it to published state. Now you will log out and check whether the blog post is visible to anonymous users. What you are doing is manual testing. It works very well for smaller projects. * For bigger projects, and especially for projects with multiple developers, what starts happening is adding a feature may break an older feature. Let’s take the example above. Earlier all the blog posts used to be published by the writer directly as soon as he saved the form and an email used to go out to all your blog subscribers that a new blog has been created. Now after adding the functionality to save the blog post as a draft state, you want the email to go out only after the blog post has been published. Suppose the developer changed and tested the workflow functionality without changing the email sending rule and pushed the feature to live site. You will soon be flooded by complaints from your blog subscribers. * This is a very simple example but such problems increase exponentially when the software grows in size over time. Such problems can be prevented by having automation testing in place. For each feature in your software, you write test code and you run all these tests often, and especially after working on a feature. You push your new feature to production only after all the tests pass. This way, as long as you have ample test coverage, you minimize your chances of finding a bug on the production site. * Who generally does this testing, the developer? site-builder? site-owner? * There are different schools of thought here. In practice, I have seen two different approaches: * If you are following test-driven development, then the developer writes these automated tests. In fact, he writes the tests before he even writes the code for the feature and makes sure that the tests fail. Then he implements the feature and makes sure that all the tests pass. In our company, our developers write the tests but that’s usually done after he has implemented the feature. We are experimenting with test driven development as of now. * The other approach I have seen in having a separate QA team for testing. They write automated tests as well as do manual QA. The advantage of this approach is that you can hire QA person, who is usually much cheaper than a developer. The problem I have seen in this approach is miscommunication between the developer and tester. Because of the delay due to communication and also since tester writes the tests after developer has completed the task, as compared to in parallel, it takes more time for a feature to get out of the door. * What do these automated tests test for? * Ideally everything but practically that’s not possible. As everything in life, this follows pareto rule. 20% of tests will cover 80% of the functionality and you should definitely write these 20% tests. In addition to that, we follow a rule that no bug should appear on production twice. So if a bug is found on production, we write an automated test for it so that it doesn’t appear on production again. What these tests should cover is very dependent on your application. If you are building an information blog site with a beautiful theme and you are making changes mostly to the theme, then you should write regressions tests for your CSS and JS. On the other hand, if your site has a lot of custom business logic, access permissions and rules, then focus on testing the logic. * I always assumed tests were for functionality, can you give me an example of something you would test on the theme layer? * I have to admit that I haven’t ever written an automated test for any of the sites I’ve built. I did have an experience a little over a year ago where the videos on my site (that were supposed to be behind a pay-wall) weren’t because I made a change to panels that messed up the access control. I didn’t realize it for two months! So, if I had had tests in place to check the access to those videos, I would have been in better shape. So, even though my site is a small site in the grand scheme of things, even I can bennefit from writting appropriate tests. ## RedTest * Red Test, as I understand it, is an open source integration testing framework for Drupal that you developed at Red Crackle. Can you tell us briefly what it does and why we should use it? * Red Test is an open-source integration testing framework for testing your Drupal applications. If you have multiple developers working on a big Drupal application stretching into months, you know that you need automated testing to keep adding more and more functionality without breaking old code. Red Test is ideal for testing: * Site structure and configuration * Custom business logic of your application * User access, roles and permissions * Rules * Drupal 7 supports Simpletest by default. Simpletest has unit testing and functional testing. Why do we need another automated testing solution? How is Red Test different from Simpletest and why should people use it? * You correctly mentioned that Drupal 7 supports Simpletest by default. In real life, when you are working on a big project, there are quite a few challenges when you test Drupal sites. * Drupal assumes that there is a persistent database connection available so any hook or function is free to access the database at will. This means that any function that accesses the database, unit testing is not possible. You can obviously refactor your code but that takes a long time. Also since Drupal stores all the configuration in the database, most of your custom code will need to access the database anyway. * For every test, simpletest creates a new test environment that has only minimal modules enabled. So if you want to test your current site with all the configuration, you have to first set all that configuration in code and then run the tests. That is too much of an overhead. * Functional testing in Simpletest is very slow because it uses a headless browser and every request needs to bootstrap Drupal. It’s not uncommon for a test suite on a large site to take multiple hours to finish. * Red Test alleviates these problems. It is an integration testing framework so it tests your site with the current configuration. It actually depends on the database so there is no need to refactor your code to make it work with Red Test. In fact, Red Test code is totally separate from Drupal code. We have created Red Test so that it runs in parallel on multiple processors of your machine and bootstraps Drupal only once at the start so it is 60 times faster than Simpletest. * A lot of Drupal developers have started using Behat which helps in testing your site functionally through a browser. With Behat gaining traction, is there still a need for Red Test? * Behat is an excellent tool and in fact, we use it in addition to Red Test. Since Red Test is an integration testing framework written in PHP and resides on the server, it can’t really test the javascript. So wherever JS functionality needs to be tested, Behat is the right tool. On the other hand, for testing all the other business logic in the application, we use Red Test. If you have used Behat on a big project, you will know that creating and especially maintaining Behat tests takes a long time. Every time an HTML id changes, Behat test needs to be changed. * Similarly, when you add a new required field in a form, Behat test needs to be updated to fill that field in the form. Red Test, on the other hand, knows about Drupal and its entities, nodes, people, roles and permissions. So it does a lot of tasks automatically in the background. As an example, if you added a new required field to a node form, Red Test will automatically fill suitable values in that field without you having to change anything in your tests. This makes it very easy for you to create and develop tests on Red Test. * In fact, we have done some measurement over the last couple of months and found that with the latest version of Red Test, creating and developing automated tests takes about 12% of total development time. * Is it easy to get started with writing automated tests using Red Test? * Yes, we are using all the standard PHP tools so it’s pretty easy for a developer to get started. Red Test uses Composer for installation and is based on PHPUnit. In fact, we measured how much time it takes a newbie to create the first integration test using Red Test and it comes to be a little less than 15 minutes. Below is the blog post you can follow to get started: http://redcrackle.com/red-test/documentation/first-integration-test ## Use Cases * What are some concrete examples of what you should test? * Red Test is ideal for testing: * Site structure and configuration * Custom business logic of your application * User access, roles and permissions * Rules * If you are building just a basic informational site on Drupal without much functionality, you may not want to use Red Test. Use it only if you are building a large Drupal application. * What’s in the future for Red Test? Do you have improvement plans, or plans to integrate with D8? * Currently a developer needs to create tests using Red Test. We are considering whether enhancing it so that it works using Gherkin language makes sense. The next obvious step is to migrate it to Drupal 8.
In our action-packed 30th episode Ed and Chris discussed their experiences with JavaScript testing tools, specifically how certain tools push you towards specific refactoring patterns. Chris talked about the successful launch of his latest book on using PHPUnit and got into some honest talk about revenue and how the product development course helped him make this book do 4 times the launch day revenue of his previous one. Ed discussed his plans to talk about mental illness on the conference circuit this year. Please help out by donating to the campaign! Rate us on iTunes here Follow us on Twitter here. Like us on Facebook here Listen Download now (MP3, 25.2MB, 55:13) Links and Notes Mocha Sinon.JS Jasmine and Jasmine-node QUnit The Grumpy Programmer’s PHPUnit Cookbook 30x500 LoneStar PHP Open Sourcing Mental Illness Require.JS PhantomJS Zombie.js Karma “It’s pronounced ‘jif’” Chris' new favourite thought leader Async JavaScript made the jump from Leanpub to bigger publisher DadBoner
Zend Screencasts: Video Tutorials about the Zend PHP Framework (iphone)
A walkthrough on how to build up a simple model layer using a test-driven development approach.
Zend Screencasts: Video Tutorials about the Zend PHP Framework (iphone)
Building on the Introduction to Doctrine 1.2 video, this video will show how you can easily test the persistence of Doctrine models within the Zend_Test environment. I also touch briefly on how to setup the latest version of MAMP with phpunit. Edit: I spoke to Guilherme Blanco (one of the core developers behind Doctrine) and…
Zend Screencasts: Video Tutorials about the Zend PHP Framework (iphone)
This video tutorial is going to look at how we can build a simple authentication mechanism with Zend_Acl with complete unit test coverage. I wouldn’t say that this is entirely the Zend way of doing things since we’re not using Zend_Auth, however it would be relatively trivial to create a Zend_Auth Adapter for each of…
Zend Screencasts: Video Tutorials about the Zend PHP Framework (iphone)
I have to preface this video by saying that I’m still a bit of a novice when it comes to unit testing (especially in Zend). Also, I feel that I wouldn’t be able to take credit for the whole implementation. Here are some great resources on unit testing in the Zend Framework to beef up…