My like button turns white in dark mode, not blue.... unit test giving false negative = fail. lol This is how a staff software engineer writes good unit tests? sigh... (Yanking your chain btw... kinda...)
Would love to see you teach a beginner tutorial on unit testing. It would be really awesome to learn unit testing from someone with such vast industry experience.
Thanks, with the TDD video I’ll try to include more specific examples. I’m trying to shy away from uploading full blown coding tutorials on UA-cam, but I think I can do more to give better examples in these videos.
The last one I did (Kotlin Collections) took me 2 months to find the will to edit the videos. I also don’t think I’m able to support the comments on those videos as well as I’d like to. I definitely want to make these videos again in the future but they would probably be on Udacity or some other platform (I’d like to keep the courses affordable so between $9.99 and $19.99, or “free” if it was on Skillshare). I do think I can mix in code samples in these videos better going forward though.
How about for a string parameter testing blank, a normal size string and a string that is too long. I assume these would be 3 different unit tests, correct?
If those are important behaviors to your application then yes they would be 3 different tests! Although it all depends on which behaviors are important to capture and test around.
How do you write unit tests for a long class method having 1500+ lines of code? Also it has lots of global dependencies (in a form of class static methods). The test case I set up has 100+ lines just for mocking so as to get to the line of code I am asserting. OMG
If the underlying data doesn't matter, then using random data is a good route to take. If you need to validate that emails ending in @gmail.com are handled differently, then yeah, you probably don't want to use random data for those tests.
I have to agree here. If there’s no need for the data to be random, just use a static string or number. The unit test should have predictable input and output, and be fully reproducible. As you mention in the video, it should be isolated and pass every single time. And random generators are even platform specific.
yeah, with random data no matter how much you are confident it won't happen, there's always a chance for the test to fail on one run but pass on the other, which is super hard to debug.
They are reproducible due to standard computer pseudo random number generators. Use same seed. This is the bases behind recorded game play, for example, in video games.
Unfortunately I cannot 😭 hopefully there are some channels out there that are covering this, but if not maybe it's something I can work on in the future.
That'd turn this into a really long video lol. I would like to create something more robust in the future, although that'd likely be a course because it would flop on UA-cam.
I am a teacher and I've been trying to write tests for my students. However, there are not any good tutorials for testing the main method of a class. When I am teaching constants, I want to test that they are setting specific variable to a constant, and using the convention of capitalizing a constant variable. Would you be able to help with this?
I wouldn't unit test that and instead rely on a linter to make sure the constant variable is always capitalized. I wouldn't write a test to validate that a constant was set to the correct value (just not a terribly useful test). If it's necessary though, you could always write a test that validates the constant is the correct value, shouldn't need to test around the main method for that, just spin up a test function and assert the value of the constant.
That’s not unit testing, that’s automated code review. You would need to do this in a linter or a code quality tool like sonarqube where you can even specify these. But who cares if it’s a capital or not? To me that’s triviality. I like consts to be capitalized but it not then fine. But Rust or example doesn’t even allow you to compile. And you can set this up for C++ too.
I'd like to understand the difference among types of test doubles: mocks, stubs, fakes, dummies and so on. Many books waste many pages to try explaining the subtle differences among them, but without success... imho
I think it is well defined. Fake fakes the implementation. It means that it really has some implementation, but the logic is much simpler. For example, a fake may use in-memory db. Mock mocks the behaviour and tracks how it is used. Stub is like a mock but does not track how it is used. You also did not mention the Spy. Spy uses an original entity to do something, but it tracks how that object is used. It usually follows a decorator pattern. Dummy - I dont know. Maybe it is just to suffice the API and to not bother with implementation. Makes sense when you don't care how particular methods behave and what they return, you just need to suffice API. In my practice, 95% of time I use fakes. Other 5% are mocks. I used spy only once in my life (but maybe I should use them more). I never use stubs and dummies because why... And in my opinion, this terminology is overcomplicated. I'd remove Dummy and Stub terms. Because as I see it, they are just fakes written by a lazy developer :)
Great content . Thanks a ton and much respect for your efforts here. Could you please share how you evaluate new software libraries? how to evaluate Android libraries to see how they fit the needs of an Android application. What kind of metrics do you generate and how ? If you could walk through with an example( like evaluating Room library or Hilt ).Specifically, How do you evaluate a software library for scalability. What tools or tests help? Thanks again.
Hey I'm not sure if I could do an entire dedicated video on that. I mostly look for community sentiment, support from the maintainers of the library, as well as if the license is compatible with my project. Hope this helps, I'll think about how I could make this into a video in the future.
Check out jquick (java), fast-check (js), hypothesis (python)... best property-based testing libs with support for arbitraries (which were called "factories" in the video)
Gotcha thanks for clarifying 😅 I tried to include some smaller samples with b roll, but to your point, it wasn’t super in-depth. I can go more in-depth with my test driven development video.
@@CodyEngelCodes Yeah, when I first found your channel a year back.. I thought you gave the most insight that was more in-depth (with specifics) than what I saw in other channels (which was flashy but vague). Like a yt-mentor for younger coders haha. Keep it up!
It depends, in situations where the value itself doesn't matter then using random can help to illustrate that. With that said, using hardcoded values for testing is probably the way to go, especially when coupled with parameterized tests.
@@CodyEngelCodes i see your Point - show to the Reader that the exact value doesnt matter. Thats a valid Point, but I have found a better way to do it. Pick a Word project-wise, any Word. I pick Word "dummy", "foo" or "bumbum" and I put that Word wherever the exact value doesnt matter. I prefer it, because i hate when test fail randonly, like run it 100 times and 99 times it passed and 1 time it fails. Random with a seed value which always generates the same valuss is Also acceptable, but test that actually puts different values into the test is a horrible mistake IMO.
If you used his idea of random number/string generators, make absolute certain to include the generated string in your messaging. Otherwise, tests will sporadically fail and you will have to suss out the input that made them fail.
The failures should show up in the failure message "expected: blah, but was blahh" as an example. Also make certain the values do not actually matter, randomly generated values are only useful when the test can be written in such a way that the exact value is not important.
You need to expand your definition of unit test, imo. A unit test needs to be standalone runnable from the command line. A unit test needs to be executed as part of your build pipeline. If those two things aren't true, you aren't really unit testing, you're just testing imo. Those two things impose a third restriction on unit tests. They need to be fast.
I think the first part makes sense. I don't think they need to be executed as part of a build pipeline, once they are, they move from being unit tests to being automated unit tests. Which for the record I do think it's a waste of time to write regular unit tests, you should only write automated unit tests. ...So probably on the same page but maybe some different semantics?
@@CodyEngelCodes unit tests that run from the cli also run form a build pipeline. This is the way to go. Because then you rubbing them before checking in your code to the remote branch. This helps also with reverts because you know what is in the branch at least last your unit tests. And of course you want the tests to be run as well as part of your commit. So that when you do a PR the team lead knows that the tests ran fine because otherwise you shouldn’t be able to do a PR.
Why not? If the specific values are not necessary for the test then why waste the energy typing in random values as opposed to using something that will just generate a random value. Yes, if the value is indeed necessary for the test, then do not use a random value.
so how do you make sure your refactoring didn't break anything? Do you manually test the whole application? That becomes infeasible at a certain scale.
@@vishwasrv Unit tests are automated tests that are usually run on CI pipeline. So unit tests do fall into this category, which makes me think you're talking about something else. It's fine as long as those tests are very fast, test all the possible scenarios, are easy to maintain and are run before code is merged to the main branch. If none of the above is true, you need unit tests.
What are your favorite tips for writing good unit tests?
My like button turns white in dark mode, not blue.... unit test giving false negative = fail. lol This is how a staff software engineer writes good unit tests? sigh... (Yanking your chain btw... kinda...)
Only mock operational dependencies (not code dependencies) and use a property-based testing lib!
Don't mock code you don't own.
Don't write them.
@@anthonylosego My like button turns black 😆
Would love to see you teach a beginner tutorial on unit testing. It would be really awesome to learn unit testing from someone with such vast industry experience.
Thanks, with the TDD video I’ll try to include more specific examples. I’m trying to shy away from uploading full blown coding tutorials on UA-cam, but I think I can do more to give better examples in these videos.
Why are you shying away from full tutorials?
The last one I did (Kotlin Collections) took me 2 months to find the will to edit the videos. I also don’t think I’m able to support the comments on those videos as well as I’d like to. I definitely want to make these videos again in the future but they would probably be on Udacity or some other platform (I’d like to keep the courses affordable so between $9.99 and $19.99, or “free” if it was on Skillshare).
I do think I can mix in code samples in these videos better going forward though.
@@CodyEngelCodes Did you make any full testing tutorials on Udacity?
test_like_button ✅ *[PASSED]* (1m21.69s)
Wow ... really useful, thank you so much for sharing. Also, subscribed :)
Really happy this was helpful!
Thank you my friend !
How about for a string parameter testing blank, a normal size string and a string that is too long. I assume these would be 3 different unit tests, correct?
If those are important behaviors to your application then yes they would be 3 different tests! Although it all depends on which behaviors are important to capture and test around.
How do you write unit tests for a long class method having 1500+ lines of code? Also it has lots of global dependencies (in a form of class static methods). The test case I set up has 100+ lines just for mocking so as to get to the line of code I am asserting. OMG
don't try. rewrite that thing.
You don't. You leave that dumpster alone so it can burn while you work on replacing it with code that is maintainable and testable.
Tests with random data generation are not reproducible. Not a very Staff thing to do.
If the underlying data doesn't matter, then using random data is a good route to take. If you need to validate that emails ending in @gmail.com are handled differently, then yeah, you probably don't want to use random data for those tests.
I have to agree here. If there’s no need for the data to be random, just use a static string or number.
The unit test should have predictable input and output, and be fully reproducible. As you mention in the video, it should be isolated and pass every single time. And random generators are even platform specific.
yeah, with random data no matter how much you are confident it won't happen, there's always a chance for the test to fail on one run but pass on the other, which is super hard to debug.
They are reproducible due to standard computer pseudo random number generators. Use same seed. This is the bases behind recorded game play, for example, in video games.
Nah random data tests can show that you have a lack of input sanitization or invariant checks.
package smash.that.like.button had me dying laughing.
😂 really stoked that you caught that.
Hi Cody can you recommend C# unit tests 'how to'?
Unfortunately I cannot 😭 hopefully there are some channels out there that are covering this, but if not maybe it's something I can work on in the future.
wish you had code examples for everything you pointed out, like the factories.
That'd turn this into a really long video lol. I would like to create something more robust in the future, although that'd likely be a course because it would flop on UA-cam.
I am a teacher and I've been trying to write tests for my students. However, there are not any good tutorials for testing the main method of a class. When I am teaching constants, I want to test that they are setting specific variable to a constant, and using the convention of capitalizing a constant variable. Would you be able to help with this?
I wouldn't unit test that and instead rely on a linter to make sure the constant variable is always capitalized. I wouldn't write a test to validate that a constant was set to the correct value (just not a terribly useful test). If it's necessary though, you could always write a test that validates the constant is the correct value, shouldn't need to test around the main method for that, just spin up a test function and assert the value of the constant.
That’s not unit testing, that’s automated code review. You would need to do this in a linter or a code quality tool like sonarqube where you can even specify these.
But who cares if it’s a capital or not? To me that’s triviality. I like consts to be capitalized but it not then fine. But Rust or example doesn’t even allow you to compile.
And you can set this up for C++ too.
I'd like to understand the difference among types of test doubles: mocks, stubs, fakes, dummies and so on.
Many books waste many pages to try explaining the subtle differences among them, but without success... imho
I think it is well defined.
Fake fakes the implementation. It means that it really has some implementation, but the logic is much simpler. For example, a fake may use in-memory db.
Mock mocks the behaviour and tracks how it is used.
Stub is like a mock but does not track how it is used.
You also did not mention the Spy.
Spy uses an original entity to do something, but it tracks how that object is used. It usually follows a decorator pattern.
Dummy - I dont know.
Maybe it is just to suffice the API and to not bother with implementation. Makes sense when you don't care how particular methods behave and what they return, you just need to suffice API.
In my practice, 95% of time I use fakes. Other 5% are mocks.
I used spy only once in my life (but maybe I should use them more).
I never use stubs and dummies because why...
And in my opinion, this terminology is overcomplicated.
I'd remove Dummy and Stub terms. Because as I see it, they are just fakes written by a lazy developer :)
Great content . Thanks a ton and much respect for your efforts here. Could you please share how you evaluate new software libraries? how to evaluate Android libraries to see how they fit the needs of an Android application. What kind of metrics do you generate and how ? If you could walk through with an example( like evaluating Room library or Hilt ).Specifically, How do you evaluate a software library for scalability. What tools or tests help? Thanks again.
Hey I'm not sure if I could do an entire dedicated video on that. I mostly look for community sentiment, support from the maintainers of the library, as well as if the license is compatible with my project. Hope this helps, I'll think about how I could make this into a video in the future.
@@CodyEngelCodes Got it, Sure. Thankyou.
Check out jquick (java), fast-check (js), hypothesis (python)... best property-based testing libs with support for arbitraries (which were called "factories" in the video)
Thanks for the recommendation!
Can you give actual examples with code next time? This was great! Thanks!!!
I meant more like a walk-through tutorial.. haha.
Gotcha thanks for clarifying 😅 I tried to include some smaller samples with b roll, but to your point, it wasn’t super in-depth. I can go more in-depth with my test driven development video.
@@CodyEngelCodes Yeah, when I first found your channel a year back.. I thought you gave the most insight that was more in-depth (with specifics) than what I saw in other channels (which was flashy but vague). Like a yt-mentor for younger coders haha. Keep it up!
Thank you, that means a lot 🥲
I don't think using "random" is the best idea. Perhaps writing "fake" string, but one that doesn't change from run to run would be better.
It depends, in situations where the value itself doesn't matter then using random can help to illustrate that. With that said, using hardcoded values for testing is probably the way to go, especially when coupled with parameterized tests.
@@CodyEngelCodes i see your Point - show to the Reader that the exact value doesnt matter. Thats a valid Point, but I have found a better way to do it. Pick a Word project-wise, any Word. I pick Word "dummy", "foo" or "bumbum" and I put that Word wherever the exact value doesnt matter. I prefer it, because i hate when test fail randonly, like run it 100 times and 99 times it passed and 1 time it fails. Random with a seed value which always generates the same valuss is Also acceptable, but test that actually puts different values into the test is a horrible mistake IMO.
My like button turned white, how do I submit a bug report?
If you used his idea of random number/string generators, make absolute certain to include the generated string in your messaging. Otherwise, tests will sporadically fail and you will have to suss out the input that made them fail.
Also, a good generator/list to have is a minMaxZeroOneNegOne.
I've never had much luck with auto-generated unit tests.
The failures should show up in the failure message "expected: blah, but was blahh" as an example.
Also make certain the values do not actually matter, randomly generated values are only useful when the test can be written in such a way that the exact value is not important.
Like button test needs to be updated
I keep asking UA-cam to fix it but alas my cries for help have gone unheard.
test_like_button ❌ *[Failed]* --> it turned black :D
Oh no!!!
You need to expand your definition of unit test, imo.
A unit test needs to be standalone runnable from the command line.
A unit test needs to be executed as part of your build pipeline.
If those two things aren't true, you aren't really unit testing, you're just testing imo.
Those two things impose a third restriction on unit tests.
They need to be fast.
I think the first part makes sense. I don't think they need to be executed as part of a build pipeline, once they are, they move from being unit tests to being automated unit tests. Which for the record I do think it's a waste of time to write regular unit tests, you should only write automated unit tests.
...So probably on the same page but maybe some different semantics?
@@CodyEngelCodes unit tests that run from the cli also run form a build pipeline. This is the way to go. Because then you rubbing them before checking in your code to the remote branch. This helps also with reverts because you know what is in the branch at least last your unit tests. And of course you want the tests to be run as well as part of your commit. So that when you do a PR the team lead knows that the tests ran fine because otherwise you shouldn’t be able to do a PR.
Like button: Fail. Original state = white outline, black fill. OnClick = Flashed red then turned white and solid.
The down didn't turn blue.
I keep telling UA-cam to fix it and they keep ignoring me.
My like button turned white, test failed
Dang it!
My "Like" button failed the unit test. Exploded with color and went white. Please review your code.
I keep asking UA-cam to fix the like button but my cries for help have been ignored.
The like button turned black for me :c
Oh no!
IT'S BLACK
We need to rewrite tests for like button!
Wow this advice is unbelievably terrible. For the love of god DO NOT generate random inputs for tests.
Why not? If the specific values are not necessary for the test then why waste the energy typing in random values as opposed to using something that will just generate a random value.
Yes, if the value is indeed necessary for the test, then do not use a random value.
Just dont write tests , its useless to unit test , a big waste of time
so how do you make sure your refactoring didn't break anything? Do you manually test the whole application? That becomes infeasible at a certain scale.
@@vyli1 there are automation tests that can check that during CI
@@vishwasrv Unit tests are automated tests that are usually run on CI pipeline.
So unit tests do fall into this category, which makes me think you're talking about something else. It's fine as long as those tests are very fast, test all the possible scenarios, are easy to maintain and are run before code is merged to the main branch.
If none of the above is true, you need unit tests.