8.2 - Unit Testing (part 1) - podcast episode cover

8.2 - Unit Testing (part 1)

Oct 11, 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.2 - Unit Testing (part 1) - AI-generated summary. Online book available at softengbook.org

Transcript

OK, let's unpack this. Have you ever felt, you know, just swamped by information, trying to really get a handle on something new quickly but also properly? Well, that's exactly why we do what we do here on the deep dive. Our whole mission is to sort of cut through the noise, pull out the really important stuff from different sources and hopefully give you that aha moment. Today we're diving into something pretty crucial.

If you're into software development or really just building things that actually work reliably. Unit testing. This deep dive is based on some really interesting bits from Software engineering, a modern approach by Marco Tulio Valente. We're going to explore why unit tests are like everywhere now, and how they help make sure software is up to scratch. Yeah.

And if we kind of step back for a second before we get into the, you know, the nuts and bolts of unit testing itself, it helps to remember what we're fighting against, so to speak, defects, bugs, basically times when the code doesn't do what it's supposed to do, and failures. That's when that buggy code actually runs and causes a problem. Unit tests are what one of our best tools for catching those

issues early on, right? So that brings us straight to section 8.2 in the book, focusing specifically on unit testing. Let's dig in. What exactly are unit tests? What's really fascinating here, I think, is how clearly the source defines them. Unit tests are automated tests, OK, and they focus on these small units of code, usually classes. But the key insight, the really important bit, is that these units are tested in isolation, completely separate from the

rest of the system. Isolation. Yeah. So a unit test at its heart, it's just a little program that calls methods from a class and then checks, you know, did it get the result that expected? And the structure of a system that uses unit tests. It sounds quite neat. The book shows it right. You've got your main code. Exactly. Your main classes doing the actual work, filling the requirements and then totally separate you have this other set of test programs. Glue separation.

I like that. And this separation it brings up something interesting. The source shows this figure right with N classes and M tests, and it's not one to one. Oh right, so not every class gets exactly 1 test. Not at all. You might have one really critical class, maybe it handles payments or something. And it might have, I don't know, 1020 unit tests hitting it from different angles, different scenarios.

And then conversely, you might have some simple classes, maybe just data holders with very few tests, or maybe none if they're super trivial or tested indirectly. So it's flexible. It depends on what the code does. Precisely. That visual really shows it's about focusing effort where it matters most. Complexity importance. OK, that makes sense. So we know what they are testing small bits in isolation. But how do developers actually, you know, do this? They don't just write them a

notepad, right? No, definitely not. You use specialized frameworks, tools built just for this job. And the most famous family of these frameworks is called X Unit. The X is just a placeholder, really. It stands for whatever language you're using. X Unit. Yeah. It's got a history, goes back to the late 80s, actually. A guy named Kent Beck made the first one unit for a language called Small Talk. Wow. OK, so it's been around a while.

It has, and maybe the one people know best today, especially in the Java world, is J Unit. J Unit, Yeah, I've heard of that one. So the first version of J Unit Kent Beck again, along with Eric Gamma. They apparently hammered it out on a plane trip back in 97. No way on a plane. That's the story kind of cool, right? Shows you can do when you're focused I guess. Definitely. So these frameworks J unit X unit, they're available for lots of languages. Oh yeah, that's the huge

advantage. Pretty much any mainstream language you can think of. Java, Python, C#, JavaScript, Ruby, you name it. It's got an X unit style framework, which means developers don't have to learn some whole new testing language. They write the tests in the same language they're building the system in. Uses all the same skills, same tools. Makes it much easier to adopt. Right, seamless integration. That's smart. So to make this a bit more real, the source uses an example, doesn't it?

A stack class. It does a classic data structure, the stack you probably remember, it's like a, well, a stack of plates. Last in, first out Ifo. Exactly. You can push things onto the top, pop them off the top, check the size, see if it is empty. Simple stuff, and it also has this specific rule. If you try to pop from an empty stack, it's supposed to throw an error an empty stack exception. Simple example but good for

showing the testing process. And when you use J unit, there are conventions little rules to follow. Like the test class is usually named after the class it tests, but with test on the end. So stack class gets a stack test class. Makes sense, Easy to find. And the methods inside stack test that actually do the testing, they also have rules. They usually start with test like test is empty or test push. They need to be public, no parameters. And critically, they have this

at Test thing right before them. An annotation. An annotation like A tag? Yeah, exactly like A tag. It's how you tell June it. Hey, this method right here. Run it as a test. Got it. So what is one of these test something methods actually do inside? Well, a typical unit test method follows this nice clean pattern. Three steps basically. First, you set things up. Create the object you're testing. This is something that's called setting up the fixture for the stack.

You just create a new stack instance stack, my stack? Who's that? Something like that. OK, step. One create the thing to test. Step 2. You call the method you're interested in like you'd call my stack dot is empty. Perform the. Action step three. Check the result. Exactly step three, verify the result. You use special assert commands provided by JUnit. There are lots of them, like assert true, assert equals assert NOT NULL. So for is empty. On a brand new stack, you'd use

assert TRUE. My stack dot is empty, so you're asserting. I expect this to be true. OK, setup ACT assert, that's pretty clear. And running these tests you mentioned the IDE. Helps. Yeah, your development environment, your IDE makes this super easy. You don't run the whole application, there's usually just a right click option run as test or something similar. It finds all those at Test methods and just runs them super quick. And when they pav. You get a nice clean output green bar.

Usually it'll say something like 15 tests run, zero failure, 0 errors, and it tells you how fast it was, often just milliseconds. Milliseconds. Wow. Yeah, that speed is huge. It means you can run these tests constantly while you're coding, get feedback almost instantly if you break something, OK. But what about when things go wrong? The source gives an example of a bug, right? Like if the stack size started at 1 instead of 0.

Wait, a subtle bug? Maybe someone type size equal 1 instead of ize equals 0 when initializing the stack O. Now, if you create a new stack and immediately call Waze emty, it's going to return false because it thinks there's one item in there, even though there isn't. And the test that assert true my stack is empty. That test would fail. Unit calls this a failure specifically meaning an assertion didn't hold true. The result wasn't what you expected. So you get a red bar instead of green.

You bet. Red bar big failure text. Yeah, and crucially, you get an error message like assertion failed error. It'll tell you exactly which assertion failed, what it expected true, and what it actually got false. So it points you right to the problem. Directly. That immediate, specific feedback is incredibly powerful for fixing bugs quickly. The source then shows a more fleshed out stack test class right with more tests.

Yeah, it shows examples like test note empty stack checking it's not empty after pushing, test size stack checking the size after pushes, test push pop stack, making sure pushing then popping get you back the same item, just covering more bases. And there was something about setting up at before each. Ah yes, that's a really useful 1. You can write a method often called in it or setup and put the app before each annotation on it.

What Joe Unit does then is it runs that setup method automatically before it runs every single at Test method in the class. Oh OK, so instead of creating a new stack inside each test method. You can do it once in the app before each method. It guarantees every test starts with a fresh identical stack, and since yeah, no interference between tests really important for reliable results. It avoids repeating that setup code everywhere too. That's clever. Keeps things clean. Definitely.

So the whole JUnit process is basically find a test class, then for every at Test method inside it make a new instance of the test class. Run any app before each method. Run the at Test method itself. Repeat isolation and consistency all. The way and one last thing, testing for expected errors like that empty stack exception. Right, you need to test that too.

If the code is supposed to throw an exception under certain conditions, you need to verify that it does June at 5, which the source refers to. Version 5 to 10 specifically has a nice way to do this using a cert throws. How does that work? You basically tell it I expect this specific exception like empty stack exception dot class to be thrown when this piece of code runs. You often provide that piece of code as a little inline function of Lambda. If the runs and throws exactly

that exception, the test passes. If it throws nothing or throws a different exception, the test fails. Got it. So you can even test the error handling. That's pretty comprehensive. It really aims to be. You want confidence that your code works correctly in normal situations and handles errors properly. So wrapping up then, we've taken this deep dive into unit testing. We've seen it's about testing small isolated pieces of code. Using frameworks like JNET following conventions like

naming and annotations. Running tests quickly and getting immediate feedback, especially when things fail. And using features like at before each for clean setup and assert throws for error checking. It really paints a picture of how crucial this is for building solid software. Absolutely that focus on automated testing right down at the smallest level the unit. It's just fundamental these days for building anything complex

and reliable. It builds confidence and quality from the ground U. Well, thank you for joining us on this Dee dive.

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