8.1 - Introduction to Testing - podcast episode cover

8.1 - Introduction to Testing

Oct 09, 202510 min
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

Software Engineering: A Modern Approach - Chapter 8 - Section 8.1 - Introduction to Testing (AI-generated summary). Online book available at softengbook.org

Transcript

Welcome to the Deep dive. Today we're getting into something really fundamental in the tech world, the whole practice of software testing. We're going to, you know, unpack why it's basically essential these days, absolutely critical. And our thinking today, it's guided by some great material. Excerpts from Software Engineering a Modern Approach by Marco Tulio Valente. A really solid source.

So the mission today, we want to look at how testing grew up right from the old ways to agile and then really dig into automated tests, especially using this this model called the test pyramid. That pyramid's a great visual, yeah. To kick things off, there's this quote from the book that just jumps out. Code without tests is bad code. I mean, that's quite a statement, isn't it, it? Absolutely is. And it's it's way more than just being catchy.

OK, The thing is, writing software, it's like building something incredibly complex from the ground up. I mean, software is one of those intricate things humans make. So it's just naturally going to have flaws, inconsistencies, bugs. So testing isn't just, you know, checking things at the end. It's going to be part of the building process itself. It's how you build in robustness from the start instead of just fixing things when they break

later. So the quote isn't just being dramatic, it's about engineering integrity. Exactly. That's a perfect way to put it. Engineering Integrity. OK, so if testing is so baked into modern development, how did it used to be? What was the the old way? Oh, it was a totally different world really. Think traditional waterfall development. OK, waterfall. Testing was its own separate box, a distinct phase. You do requirements analysis, design, coding, then you test.

After everything else was supposedly done, pretty much. And it often wasn't even the developers doing it, you had separate test teams. Right, the QA department. Exactly, and a lot of what they did was manual, like literally clipping through the application, typing stuff in, looking at the screen to see if it was right. Since slow it was. And the main goal was simple, find the bugs before this thing gets out to real users before production. OK, so that was the old way, but

then things changed. We talked about Agile a lot. How did Agile just completely flip the script on testing? Agile, yeah, it was a seismic shift for testing. I mean fundamentally. How so? Well, for starters, a huge chunk of testing became automated. Developers started writing code whose whole job was to test other code. So the code tests itself in a way. Kind of, yeah. Programs became self testable. That's a massive change. Definite way. And because of that, tests were

only done after coding. You could actually write the test before you even wrote the class it was supposed to test. Whoa, OK. Test Driven Development, right? That's part of it, yeah. And those big separate test teams mostly gone or they handle very specialized stuff now. So who does the test in? The developer, the person writing the class, is now responsible for writing its tests too. That makes sense responsibility wise. It does, and testing took on new jobs. It wasn't just finding bugs

anymore. Tests became like living documentation for the code. Documentation. Well, a good test shows you exactly how a piece of code is supposed to be used and what it should do better than comments sometimes. Interesting. Plus, they're crucial for checking if a bug fix over here accidentally broke something over there. You know, regression testing. Right, Run the tests, make sure

everything still passes exactly. So. Going back to that Michael Feathers quote, code without tests is bad code in this agile world. It's like if your code can't be easily tested, if it doesn't have those automated tests, it's just not good quality. Maybe even legacy code from day one you've. Nailed it. That's precisely the modern view. And this focus on automated tests wasn't just like a nice to have, it became necessary.

Why necessary? Think about it, how could you possibly manually test a complex system that's changing maybe multiple times a day? Yeah, impossible. It's way too slow. Humans make mistakes, it costs fortune, and you have to do it every single time anything changes. Yeah, automation was the only way to keep up. Right. OK. So automation is key. And you mentioned the test pyramid earlier. Our source calls it an interesting way to classify these automated tests. Mike Kuhn's idea, Yeah.

Mike Kuhn originally proposed it. It's a really, really helpful model. It basically sorts tests based on how big of a piece they're looking at their granularity. Granularity, OK. It breaks automated tests down into three main layers, Unit integration and end to end. Unit integration end to end, right? And the pyramid shape isn't just random, it tells you something about how many of each type you should probably have. It guides the proportions.

OK, proportions are important, so let's start at the bottom, the base of the pyramid. What's down there? Down at the wide base, you've got unit tests. Unit tests. These check the smallest testable bits of your code. Usually that means a single class, or maybe even just one method within a class. OK, really small pieces. Exactly. Yeah, and they test it completely alone, isolated from everything else in the system. Isolated.

How do they do that? Often using things like mock objects or stubs to pretend to be the other parts the class might talk to. Got it. And they're at the base because you should have the most of these lots and lots. The general guideline like you see in the source is maybe around 70% of your total automated tests. 70% Wow. That's the vast majority. Why so many? Because they have big advantages. They're usually simple to write.

They run super fast, like thousands and seconds, and if one fails you know exactly where the problem is. Pinpoints the issue. Precisely. They're like tiny little quality checks on every single component. Before you even assemble the machine they check. Does this specific function give the right output for this specific input? Makes sense. OK, base layer covered. Moving up the pyramid, what's the next level? In the middle we have integration tests.

Sometimes people call them service tests. Integration tests. What do they integrate? They check out different parts of your system work together, so instead of just one class in isolation, an integration test might involve several classes, maybe from different modules or packages. OK, testing the connection. Exactly. They often verify a specific piece of functionality or a transaction that scans across

these components. They might even interact with external things like hitting a real database or calling an external API. OK, so less isolated now. Much less isolated, and because they involve more moving parts, maybe external systems, they naturally take longer to write and definitely longer to run than unit tests. And proportion wise. The recommendation is usually around, say, 20% of your tests. Significantly fewer than unit tests, but still a good chunk. 20% OK unit integration.

That brings us to the very top of the pyramid. What's up there? At the pointy top you have end to end tests. End to end, E to E. Right. You might also hear them called UI tests, User interface tests or sometimes system tests. And what are they testing end to end? They try to simulate a real user's journey through the entire application as realistically as possible. Like someone actually using the software.

Pretty much clicking buttons, filling out forms, navigating between screens, the whole sequence of actions a user might take to complete a task, logging and doing something complex, logging out. OK, that sounds comprehensive. It is. That's the goal, yeah, But they're at the top, the smallest section, maybe only 10% of your tests, for good reason. Why so few?

They're way more complex to set up and maintain, they take a long time to run compared to the others, and crucially, they tend to be. Brittle. Brittle. What does that mean? It means they break easily, often for reasons unrelated to actual bugs in the logic. Like what? Like if someone just changes the layout of the user interface slightly, moves a button, changes an ID, the test script might fail even if the underlying functionality is perfectly fine. So they need a lot of

maintenance. A lot. That's why you want fewer of them, focusing them on the most critical user paths. Got it. That pyramid structure makes a lot more sense now, balancing speed, scope, and stability. OK, one last thing from the source that seems really important for just clear communication. The difference between a defect and a failure. Yes, this is a really useful distinction. People often use bug for everything but technically. Technically.

A defect or a bug is the actual mistake in the code. It's where the code doesn't match its specification or requirement. It's the flaw itself. The error written down essentially. Right, the incorrect line of code, the wrong logic. Now a failure is what happens when that defective code actually runs. And because it runs, the program does something wrong. It produces an incorrect result or crashes, or just behaves unexpectedly. So the failure is the observable wrong thing.

Exactly. The defect is the hidden cause. The failure is the visible symptom that occurs when the defect gets triggered. You need the defect to be executed to cause a failure. A defect is the cause, failure is the effect. That's a great clarification. Also, won't be on the same page, yeah. Definitely. Wow, this has been quite the

deep dive today. We've really covered a lot, you know, starting with why testing is just non negotiable now, tracing that big shift from waterfall separate phase to Agile's integrated automated way. A huge transformation. And then breaking down the test pyramid, unit tests at the base, integration in the middle and to end at the top, and finally getting that clear distinction between a defect and a failure. Absolutely.

I think the main thing to take away is how central this automated layered testing approach is to building good software today. It's not an add on, It's fundamental to quality, speed and just making sure things don't fall apart. Totally agree. So here's a final thought for you, our listener to chew on. We heard that modern software is becoming self testable, right? And that tests also act as documentation for the production

code. If those things are true, what else could that mean for how we actually create software? Does it open up new the possibilities beyond just sketching bugs? Could it change what we even think it means for software to be, you know, done or truly complete? Interesting question. Something to think about. We'll leave it there for this time. Thanks for joining us on the Deep Dive.

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android