title
Python Tutorial: Unit Testing Your Code with the unittest Module

description
In this Python Programming Tutorial, we will be learning how to unit-test our code using the unittest module. Unit testing will allow you to be more comfortable with refactoring and knowing whether or not your updates broke any of your existing code. Unit testing is a must on any large projects and is used by all major companies. Not only that, but it will greatly improve your personal code as well. Let's get started. The code from this video can be found at: https://github.com/CoreyMSchafer/code_snippets/tree/master/Python-Unit-Testing Unittest assert methods: https://docs.python.org/3/library/unittest.html#unittest.TestCase.debug if __name__ == '__main__' video: https://www.youtube.com/watch?v=sugvnHA7ElY OOP Series: https://www.youtube.com/playlist?list=PL-osiE80TeTsqhIuOqKhwlXsIBIdSeYtc ✅ Support My Channel Through Patreon: https://www.patreon.com/coreyms ✅ Become a Channel Member: https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join ✅ One-Time Contribution Through PayPal: https://goo.gl/649HFY ✅ Cryptocurrency Donations: Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3 Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33 Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot ✅ Corey's Public Amazon Wishlist http://a.co/inIyro1 ✅ Equipment I Use and Books I Recommend: https://www.amazon.com/shop/coreyschafer ▶️ You Can Find Me On: My Website - http://coreyms.com/ My Second Channel - https://www.youtube.com/c/coreymschafer Facebook - https://www.facebook.com/CoreyMSchafer Twitter - https://twitter.com/CoreyMSchafer Instagram - https://www.instagram.com/coreymschafer/ #Python

detail
{'title': 'Python Tutorial: Unit Testing Your Code with the unittest Module', 'heatmap': [{'end': 142.024, 'start': 112.045, 'weight': 0.736}, {'end': 376.788, 'start': 302.583, 'weight': 0.704}, {'end': 451.603, 'start': 423.382, 'weight': 0.705}, {'end': 496.55, 'start': 469.997, 'weight': 0.795}, {'end': 1132.558, 'start': 1050.844, 'weight': 0.701}, {'end': 1201.289, 'start': 1151.211, 'weight': 0.748}, {'end': 1607.178, 'start': 1546.592, 'weight': 0.784}, {'end': 1650.198, 'start': 1618.925, 'weight': 0.787}, {'end': 1934.98, 'start': 1831.869, 'weight': 0.831}], 'summary': 'This python tutorial on unit testing with the unittest module covers basics, effective test writing, debugging, testing code changes, strategies, setup methods, and mocking for reliable testing. it emphasizes writing good tests over quantity, demonstrates debugging a typo, and discusses the use of mocking to ensure reliable testing by isolating code failures from external dependencies.', 'chapters': [{'end': 299.08, 'segs': [{'end': 43.82, 'src': 'embed', 'start': 0.229, 'weight': 0, 'content': [{'end': 4.113, 'text': "Hey there, how's it going everybody? In this video, we're going to learn about unit testing in Python.", 'start': 0.229, 'duration': 3.884}, {'end': 9.117, 'text': "So we'll go over how to write tests, how to set up and tear down your tests, and also some best practices.", 'start': 4.373, 'duration': 4.744}, {'end': 15.042, 'text': "So if you're not currently testing your code, then it's definitely something that you're going to want to learn and start adding to your projects.", 'start': 9.477, 'duration': 5.565}, {'end': 19.046, 'text': 'So a lot of you have probably heard of testing, but you might not know exactly what it is.', 'start': 15.383, 'duration': 3.663}, {'end': 26.051, 'text': "Testing your code isn't the most exciting thing to do, but there's a reason that most companies and teams require their code to be thoroughly tested.", 'start': 19.986, 'duration': 6.065}, {'end': 31.334, 'text': "And if you're going to get a job working on any large projects, then you're going to need to know how to properly write tests.", 'start': 26.431, 'duration': 4.903}, {'end': 35.437, 'text': "And the reason for that is that it's going to save you a lot of time and headache down the road.", 'start': 31.754, 'duration': 3.683}, {'end': 38.118, 'text': 'So when you write good tests for your code,', 'start': 35.857, 'duration': 2.261}, {'end': 43.82, 'text': "it gives you more confidence that your updates and refactoring don't have any unintended consequences or break your code in any way.", 'start': 38.118, 'duration': 5.702}], 'summary': 'Learn about unit testing in python, its importance, and benefits for code quality and project success.', 'duration': 43.591, 'max_score': 0.229, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI229.jpg'}, {'end': 163.748, 'src': 'heatmap', 'start': 112.045, 'weight': 3, 'content': [{'end': 117.928, 'text': "so we're going to go ahead and just move, remove this print statement and actually start adding some unit tests.", 'start': 112.045, 'duration': 5.883}, {'end': 120.71, 'text': 'So to do this, first we need to create a test module.', 'start': 118.288, 'duration': 2.422}, {'end': 129.515, 'text': "So I'm going to create a new file here in this current directory and I'm going to call this test underscore calc dot py.", 'start': 121.03, 'duration': 8.485}, {'end': 136.101, 'text': "Now that's the naming convention when writing tests is to start with test underscore and then what you're testing.", 'start': 129.856, 'duration': 6.245}, {'end': 138.583, 'text': 'So in this case it was test underscore calc.', 'start': 136.181, 'duration': 2.402}, {'end': 142.024, 'text': "And that's actually going to be required within our test.", 'start': 139.423, 'duration': 2.601}, {'end': 148.165, 'text': "So now we have this test underscore calc module pulled up and we're currently working with an empty file.", 'start': 142.424, 'duration': 5.741}, {'end': 151.025, 'text': "So first let's import the unit test module.", 'start': 148.505, 'duration': 2.52}, {'end': 155.166, 'text': "Now this module is in the standard library, so there's no need to install anything.", 'start': 151.325, 'duration': 3.841}, {'end': 157.587, 'text': 'You can just say import unit test.', 'start': 155.486, 'duration': 2.101}, {'end': 161.287, 'text': "And now we're also going to want to import the module that we want to test.", 'start': 158.367, 'duration': 2.92}, {'end': 163.748, 'text': "So I'm going to import that calc module.", 'start': 161.568, 'duration': 2.18}], 'summary': 'Creating unit tests for the calc module by importing unit test and calc module.', 'duration': 45.46, 'max_score': 112.045, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI112045.jpg'}, {'end': 231.102, 'src': 'embed', 'start': 207.375, 'weight': 5, 'content': [{'end': 215.137, 'text': 'So inheriting from unit test dot test case is going to give us access to a lot of different testing capabilities within that class.', 'start': 207.375, 'duration': 7.762}, {'end': 217.498, 'text': "So let's write our first test.", 'start': 215.497, 'duration': 2.001}, {'end': 224.14, 'text': "So to do this, we'll write a method and the method needs to start with test underscore.", 'start': 217.878, 'duration': 6.262}, {'end': 231.102, 'text': 'Now that naming convention is actually required so that when we run this, it actually knows which methods represent tests.', 'start': 225.1, 'duration': 6.002}], 'summary': 'Inheriting from unit test dot test case gives access to testing capabilities. naming convention requires methods to start with test underscore.', 'duration': 23.727, 'max_score': 207.375, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI207375.jpg'}], 'start': 0.229, 'title': 'Python unit testing basics and writing unit tests for python modules', 'summary': 'Introduces the importance of unit testing, emphasizing time-saving and ensuring code functionality. it covers setting up and writing tests in python and outlines creating test modules, naming conventions, and inheritance from the unit test module.', 'chapters': [{'end': 117.928, 'start': 0.229, 'title': 'Python unit testing basics', 'summary': 'Introduces the importance of unit testing, emphasizing how it saves time and ensures code functionality, and provides an overview of the content covered in the video, including setting up and writing tests in python.', 'duration': 117.699, 'highlights': ['Unit testing saves time and ensures code functionality', 'Importance of learning unit testing for job prospects', 'Introduction to setting up and writing tests in Python']}, {'end': 299.08, 'start': 118.288, 'title': 'Writing unit tests for python modules', 'summary': 'Outlines the process of creating a test module, importing necessary modules, creating test cases, and writing test methods for a python module, emphasizing naming conventions and inheritance from the unit test module.', 'duration': 180.792, 'highlights': ["The chapter emphasizes the naming convention for test modules, requiring the file to start with 'test_' and followed by what is being tested, such as 'test_calc'.", "It explains the process of importing the unit test module and the module to be tested, highlighting the standard library's accessibility of the unit test module.", "The chapter stresses the creation of test cases by inheriting from the unit test module's test case and the importance of naming test methods with 'test_' prefix."]}], 'duration': 298.851, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI229.jpg', 'highlights': ['Unit testing saves time and ensures code functionality', 'Introduction to setting up and writing tests in Python', 'Importance of learning unit testing for job prospects', "The chapter emphasizes the naming convention for test modules, requiring the file to start with 'test_' and followed by what is being tested, such as 'test_calc'", "It explains the process of importing the unit test module and the module to be tested, highlighting the standard library's accessibility of the unit test module", "The chapter stresses the creation of test cases by inheriting from the unit test module's test case and the importance of naming test methods with 'test_' prefix"]}, {'end': 750.105, 'segs': [{'end': 376.788, 'src': 'heatmap', 'start': 299.46, 'weight': 3, 'content': [{'end': 302.223, 'text': "So we're going to use assert equals to test our add function.", 'start': 299.46, 'duration': 2.763}, {'end': 316.835, 'text': "So I can run our add function from here by saying something like result is equal to calc.add and we'll just add those same values 10 and 5 and we would expect this to equal 15.", 'start': 302.583, 'duration': 14.252}, {'end': 324.981, 'text': 'so to test this, we can say self.assert equals, and now we want to assert that that result is equal to 15.', 'start': 316.835, 'duration': 8.146}, {'end': 328.363, 'text': 'okay, so now how do we run this test?', 'start': 324.981, 'duration': 3.382}, {'end': 330.425, 'text': 'so we could do it from the command line.', 'start': 328.363, 'duration': 2.062}, {'end': 337.129, 'text': 'so I have my command line here pulled up and I am navigated to the directory where our module is currently located.', 'start': 330.425, 'duration': 6.704}, {'end': 345.114, 'text': 'Now, you might think that we could just run the test by saying, you know, Python test underscore calc dot pi.', 'start': 337.529, 'duration': 7.585}, {'end': 348.076, 'text': "But if I run that, you can see it doesn't actually return anything.", 'start': 345.434, 'duration': 2.642}, {'end': 354.76, 'text': 'So instead, we need to run unit test as our main module and pass in test underscore calc.', 'start': 348.436, 'duration': 6.324}, {'end': 365.684, 'text': 'And we can do that by saying python-m and then unit test and now the test underscore calc.py module.', 'start': 355.2, 'duration': 10.484}, {'end': 372.907, 'text': 'And we can see that when we run that, it puts a dot here and it says ran one test.', 'start': 366.024, 'duration': 6.883}, {'end': 375.267, 'text': 'And at the bottom it says okay.', 'start': 373.347, 'duration': 1.92}, {'end': 376.788, 'text': 'So that means that everything passed.', 'start': 375.287, 'duration': 1.501}], 'summary': 'Using assert equals to test add function, expected result 15, passed 1 test.', 'duration': 28.903, 'max_score': 299.46, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI299460.jpg'}, {'end': 469.577, 'src': 'heatmap', 'start': 423.382, 'weight': 0, 'content': [{'end': 426.544, 'text': 'I do have a separate video specifically what that is about.', 'start': 423.382, 'duration': 3.162}, {'end': 432.148, 'text': "But basically it's just saying that if we run this module directly, then run the code within the conditional.", 'start': 426.905, 'duration': 5.243}, {'end': 436.591, 'text': 'And that code within our conditional is this unit test dot main.', 'start': 432.508, 'duration': 4.083}, {'end': 439.373, 'text': 'And that unit test dot main will run all of our tests.', 'start': 436.851, 'duration': 2.522}, {'end': 442.335, 'text': 'So now if we go back here, this is now saved.', 'start': 439.753, 'duration': 2.582}, {'end': 446.178, 'text': 'If we go back here to our terminal and I will clear this out.', 'start': 442.455, 'duration': 3.723}, {'end': 451.603, 'text': "So now let's rerun that using that first method of just Python and our test module.", 'start': 446.519, 'duration': 5.084}, {'end': 457.508, 'text': 'And if we run that, you can see that now we can run it directly and it runs our unit test and says that it passed.', 'start': 452.043, 'duration': 5.465}, {'end': 464.233, 'text': 'And since we can run it this way within the terminal, that should mean that it can also run within our editor.', 'start': 457.928, 'duration': 6.305}, {'end': 469.577, 'text': 'So if I run this, then you can see that within our editor, we can now run these tests also.', 'start': 464.553, 'duration': 5.024}], 'summary': 'Running module directly executes unit tests, ensuring they pass in both terminal and editor.', 'duration': 46.195, 'max_score': 423.382, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI423382.jpg'}, {'end': 500.111, 'src': 'heatmap', 'start': 469.997, 'weight': 0.795, 'content': [{'end': 470.737, 'text': "Okay, so that's good.", 'start': 469.997, 'duration': 0.74}, {'end': 472.058, 'text': "So we're running our first test.", 'start': 470.757, 'duration': 1.301}, {'end': 474.921, 'text': "So it's saying that we're only running one test.", 'start': 472.359, 'duration': 2.562}, {'end': 482.286, 'text': "Now, do you remember earlier when I said that your tests have to start with the word test? Well, let me show you what it does if it doesn't.", 'start': 475.241, 'duration': 7.045}, {'end': 489.888, 'text': "So instead of test underscore add here as our test, let's call this add underscore test and save this and run it.", 'start': 482.626, 'duration': 7.262}, {'end': 496.55, 'text': "So when we run this, it might not be obvious right off the bat that anything is wrong because we didn't get any errors or any warnings.", 'start': 490.228, 'duration': 6.322}, {'end': 500.111, 'text': 'But if we look at how many tests ran, it says zero.', 'start': 496.89, 'duration': 3.221}], 'summary': 'Initial test run resulted in running only one test, which failed to execute due to naming convention error.', 'duration': 30.114, 'max_score': 469.997, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI469997.jpg'}, {'end': 535.096, 'src': 'embed', 'start': 502.292, 'weight': 4, 'content': [{'end': 506.893, 'text': 'So you have to be careful that all of your tests are named properly and start with the word test.', 'start': 502.292, 'duration': 4.601}, {'end': 509.854, 'text': "So let's go ahead and change that back and rerun it.", 'start': 507.013, 'duration': 2.841}, {'end': 518.842, 'text': "Okay, so now what happens if our test fails? So let's change this value here with the assert equals, the result is equal to 15.", 'start': 510.334, 'duration': 8.508}, {'end': 524.086, 'text': "Let's change this to a 14 so that our test of adding 10 and 5 fails.", 'start': 518.842, 'duration': 5.244}, {'end': 525.628, 'text': "So let's save that and run it.", 'start': 524.406, 'duration': 1.222}, {'end': 535.096, 'text': 'So now if I pull this up a little bit here to where we can see, we can see that instead of a dot, we got an F for fail.', 'start': 526.008, 'duration': 9.088}], 'summary': 'Testing process ensuring proper test naming and failing test with modified values.', 'duration': 32.804, 'max_score': 502.292, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI502292.jpg'}, {'end': 598.382, 'src': 'embed', 'start': 572.35, 'weight': 5, 'content': [{'end': 578.271, 'text': "So let's copy and paste this line here a couple of times and test a couple of edge cases.", 'start': 572.35, 'duration': 5.921}, {'end': 582.092, 'text': 'So one edge case might be one negative number and one positive number.', 'start': 578.651, 'duration': 3.441}, {'end': 588.836, 'text': "So let's make sure that negative 1 plus 1 is equal to 0.", 'start': 582.472, 'duration': 6.364}, {'end': 591.418, 'text': 'And two negative numbers would also be another edge case.', 'start': 588.836, 'duration': 2.582}, {'end': 598.382, 'text': "So let's make sure that negative 1 plus negative 1 is equal to negative 2.", 'start': 591.738, 'duration': 6.644}], 'summary': 'Testing edge cases with negative and positive numbers for addition.', 'duration': 26.032, 'max_score': 572.35, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI572350.jpg'}, {'end': 639.754, 'src': 'embed', 'start': 615.373, 'weight': 1, 'content': [{'end': 622.138, 'text': "But even though it still says that there's only one test, We still made this test better by adding in these additional checks.", 'start': 615.373, 'duration': 6.765}, {'end': 628.364, 'text': "So it's not our goal to write as many tests as possible, but just make sure that we write good tests.", 'start': 622.498, 'duration': 5.866}, {'end': 631.026, 'text': "So that's something that a lot of people get tripped up on.", 'start': 628.644, 'duration': 2.382}, {'end': 637.512, 'text': 'They just shoot for full coverage without making sure their tests are actually good enough to catch mistakes.', 'start': 631.486, 'duration': 6.026}, {'end': 639.754, 'text': 'So try to be mindful of that when writing tests.', 'start': 637.792, 'duration': 1.962}], 'summary': 'Improving test quality over quantity is crucial for catching mistakes.', 'duration': 24.381, 'max_score': 615.373, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI615373.jpg'}, {'end': 761.031, 'src': 'embed', 'start': 731.17, 'weight': 7, 'content': [{'end': 732.992, 'text': 'So you can imagine how useful this is.', 'start': 731.17, 'duration': 1.822}, {'end': 739.197, 'text': 'So if you have a module with some complicated functions, then once you put in the work to write good tests like this,', 'start': 733.372, 'duration': 5.825}, {'end': 743.54, 'text': 'then you can just come back and rerun these tests to make sure that everything still works.', 'start': 739.197, 'duration': 4.343}, {'end': 750.105, 'text': 'So if you change something in your program that you think will work, but it actually broke some stuff, then your test should catch that.', 'start': 743.86, 'duration': 6.245}, {'end': 751.165, 'text': 'So, for example,', 'start': 750.385, 'duration': 0.78}, {'end': 761.031, 'text': "let's say that I came in here to our calc function and we just made a typo in this multiply function and instead of one asterisk there we put two.", 'start': 751.165, 'duration': 9.866}], 'summary': 'Writing good tests allows for easy and efficient program checks, preventing potential errors and ensuring functionality.', 'duration': 29.861, 'max_score': 731.17, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI731170.jpg'}], 'start': 299.46, 'title': 'Writing effective tests for code', 'summary': 'Covers writing effective tests for code, including using assert equals to test functions, running tests using command line and within the editor, importance of naming test cases properly, and testing edge cases such as negative and positive numbers. it also emphasizes writing good tests over quantity, demonstrated by adding and testing multiple functions in a single test method, and highlights the importance of ensuring test quality to catch mistakes, as demonstrated by running four tests for calculator functions with assert equal statements and all passed.', 'chapters': [{'end': 598.382, 'start': 299.46, 'title': 'Unit testing and test cases', 'summary': 'Covers the usage of assert equals to test the add function, running tests using command line and within the editor, the importance of naming test cases properly, and testing edge cases such as negative and positive numbers.', 'duration': 298.922, 'highlights': ['The chapter covers the usage of assert equals to test the add function.', 'Running tests using command line and within the editor.', 'The importance of naming test cases properly.', 'Testing edge cases such as negative and positive numbers.']}, {'end': 750.105, 'start': 598.382, 'title': 'Writing effective tests for code', 'summary': 'Emphasizes writing good tests over quantity, demonstrated by adding and testing multiple functions in a single test method, and highlights the importance of ensuring test quality to catch mistakes, as demonstrated by running four tests for calculator functions with assert equal statements and all passed.', 'duration': 151.723, 'highlights': ['The chapter emphasizes writing good tests over quantity, demonstrated by adding and testing multiple functions in a single test method.', 'Running four tests for calculator functions with assert equal statements and all passed.', 'The importance of ensuring test quality to catch mistakes is highlighted.', 'Emphasizing not just writing as many tests as possible, but making sure that the tests are good enough to catch mistakes.', 'Adding and testing multiple functions in a single test method.', 'The significance of rerunning tests to ensure everything still works after making changes in the program.']}], 'duration': 450.645, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI299460.jpg', 'highlights': ['Running tests using command line and within the editor.', 'The importance of ensuring test quality to catch mistakes is highlighted.', 'The chapter emphasizes writing good tests over quantity, demonstrated by adding and testing multiple functions in a single test method.', 'The chapter covers the usage of assert equals to test the add function.', 'The importance of naming test cases properly.', 'Testing edge cases such as negative and positive numbers.', 'Emphasizing not just writing as many tests as possible, but making sure that the tests are good enough to catch mistakes.', 'The significance of rerunning tests to ensure everything still works after making changes in the program.', 'Running four tests for calculator functions with assert equal statements and all passed.']}, {'end': 1081.725, 'segs': [{'end': 806.374, 'src': 'embed', 'start': 775.379, 'weight': 0, 'content': [{'end': 778.681, 'text': 'So that means that three of our tests pass and one test failed.', 'start': 775.379, 'duration': 3.302}, {'end': 787.705, 'text': "And the one that failed, it says that we have an assertion error that the 10 times 5 should actually be equal to 50, and it's not.", 'start': 779.021, 'duration': 8.684}, {'end': 789.086, 'text': 'Instead, we got this value here.', 'start': 787.765, 'duration': 1.321}, {'end': 795.649, 'text': 'So that gives us an idea of exactly where the problem is and where we can make that change to get these tests to pass again.', 'start': 789.406, 'duration': 6.243}, {'end': 798.471, 'text': "So let's go ahead and go back here and change this back.", 'start': 795.95, 'duration': 2.521}, {'end': 806.374, 'text': "Now sometimes you might make a change that doesn't actually break your test, but will actually unexpectedly break your code.", 'start': 798.991, 'duration': 7.383}], 'summary': '3 tests pass, 1 fails due to assertion error. identifies problem and makes necessary change.', 'duration': 30.995, 'max_score': 775.379, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI775379.jpg'}, {'end': 868.997, 'src': 'embed', 'start': 836.75, 'weight': 2, 'content': [{'end': 841.114, 'text': 'So if we run our test, then we can see that currently all of these tests are passing.', 'start': 836.75, 'duration': 4.364}, {'end': 849.441, 'text': "So let's say that at some point that floor division broke our program and after some debugging, we traced it back to that and found the problem.", 'start': 841.474, 'duration': 7.967}, {'end': 857.127, 'text': "Now, in that case, it's always a good practice to go update your test with a test that would have caught the problem that you just found.", 'start': 849.821, 'duration': 7.306}, {'end': 861.771, 'text': "That way, we can know that we don't revisit the same bugs over and over.", 'start': 857.808, 'duration': 3.963}, {'end': 868.997, 'text': "So, for example, a test that would have caught this, I'm going to copy and assert equals statement here.", 'start': 862.111, 'duration': 6.886}], 'summary': 'All tests passing, updated test to catch previous bug.', 'duration': 32.247, 'max_score': 836.75, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI836750.jpg'}, {'end': 1063.232, 'src': 'embed', 'start': 1033.815, 'weight': 3, 'content': [{'end': 1037.176, 'text': "Now, I've never preferred this method of testing exceptions,", 'start': 1033.815, 'duration': 3.361}, {'end': 1045.461, 'text': "because I just like to call the function that I want to test normally instead of passing in all of the arguments separately, like we're doing here.", 'start': 1037.176, 'duration': 8.285}, {'end': 1050.464, 'text': 'And we can do this if we test the exceptions using a context manager.', 'start': 1045.922, 'duration': 4.542}, {'end': 1059.089, 'text': 'Now that will allow us to handle and check the exception properly and also call our function normally.', 'start': 1050.844, 'duration': 8.245}, {'end': 1063.232, 'text': "So to do this, I'm actually going to get rid of everything here.", 'start': 1059.509, 'duration': 3.723}], 'summary': 'The speaker prefers testing exceptions using a context manager for better exception handling and normal function calls.', 'duration': 29.417, 'max_score': 1033.815, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1033815.jpg'}], 'start': 750.385, 'title': 'Debugging and testing code changes', 'summary': 'Discusses debugging a typo in the multiply function, leading to the failure of one test case out of four, and the identification of the incorrect value as the source of the problem. it also explores the importance of updating tests after making code changes and demonstrates testing for error handling, including a comparison of two methods of testing exceptions in python.', 'chapters': [{'end': 795.649, 'start': 750.385, 'title': 'Debugging multiplication function', 'summary': 'Discusses debugging a typo in the multiply function, leading to the failure of one test case out of four, and the identification of the incorrect value as the source of the problem.', 'duration': 45.264, 'highlights': ['Identifying the typo in the multiply function as the cause of the failed test, which should return 50 but instead gives a different value.', 'Rerunning the test reveals that three out of four tests pass, indicating the failure of one test due to the incorrect value being returned.']}, {'end': 1081.725, 'start': 795.95, 'title': 'Testing code changes and error handling', 'summary': 'Discusses the importance of updating tests after making code changes, and demonstrates testing for error handling, including a comparison of two methods of testing exceptions in python.', 'duration': 285.775, 'highlights': ['The chapter discusses the importance of updating tests after making code changes', 'Demonstrates testing for error handling and comparison of two methods of testing exceptions in Python']}], 'duration': 331.34, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI750385.jpg', 'highlights': ['Identifying the typo in the multiply function as the cause of the failed test, which should return 50 but instead gives a different value.', 'Rerunning the test reveals that three out of four tests pass, indicating the failure of one test due to the incorrect value being returned.', 'The chapter discusses the importance of updating tests after making code changes', 'Demonstrates testing for error handling and comparison of two methods of testing exceptions in Python']}, {'end': 1722.822, 'segs': [{'end': 1132.558, 'src': 'embed', 'start': 1105.258, 'weight': 1, 'content': [{'end': 1109.621, 'text': "And if you don't know exactly what this class is doing, then it's not really important.", 'start': 1105.258, 'duration': 4.363}, {'end': 1113.324, 'text': "We're just going to see how this affects some testing strategies.", 'start': 1110.122, 'duration': 3.202}, {'end': 1123.611, 'text': "So basically what this code is doing is it allows us to create employee instances where it will set the employee's first name, last name, and pay.", 'start': 1113.704, 'duration': 9.907}, {'end': 1132.558, 'text': "And then we have some methods that return the employee's email address, which is their first name and last name at email.com.", 'start': 1124.052, 'duration': 8.506}], 'summary': 'Code creates employee instances with first name, last name, and pay, and methods return email addresses.', 'duration': 27.3, 'max_score': 1105.258, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1105258.jpg'}, {'end': 1201.289, 'src': 'heatmap', 'start': 1151.211, 'weight': 0.748, 'content': [{'end': 1153.373, 'text': 'now the way that this code is set up.', 'start': 1151.211, 'duration': 2.162}, {'end': 1160.237, 'text': "if an employee's first name or last name changes, then that should automatically be reflected in the email and first name okay.", 'start': 1153.373, 'duration': 6.864}, {'end': 1162.499, 'text': "so let's say that we wanted to write some tests for this.", 'start': 1160.237, 'duration': 2.262}, {'end': 1170.965, 'text': "so first what we would do is we would create a new file and I'm going to call this test underscore employee.py.", 'start': 1162.499, 'duration': 8.466}, {'end': 1174.447, 'text': 'and to save time from you watching me type all of these tests,', 'start': 1170.965, 'duration': 3.482}, {'end': 1180.031, 'text': "I'm instead going to grab them out of my snippets file here and we'll explain exactly what we're testing.", 'start': 1174.447, 'duration': 5.584}, {'end': 1186.375, 'text': "So I'm going to copy all of these down to this point and paste these in here.", 'start': 1180.371, 'duration': 6.004}, {'end': 1195.984, 'text': "Okay, so if we scroll up to the top here, then first we're importing unit test and also importing our employee class from the employee module.", 'start': 1186.895, 'duration': 9.089}, {'end': 1201.289, 'text': "And then we're creating our test case that inherits from unit test dot test case.", 'start': 1196.324, 'duration': 4.965}], 'summary': 'Code is set up to automatically reflect employee name changes in email and first name. writing tests for this functionality.', 'duration': 50.078, 'max_score': 1151.211, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1151211.jpg'}, {'end': 1314.939, 'src': 'embed', 'start': 1285.239, 'weight': 3, 'content': [{'end': 1288.92, 'text': 'So if we run this, then we can see that all of those tests pass.', 'start': 1285.239, 'duration': 3.681}, {'end': 1297.402, 'text': 'Now, one thing that you might notice is that at the beginning of every one of these tests, we are creating two employees.', 'start': 1289.34, 'duration': 8.062}, {'end': 1300.565, 'text': 'now, anytime you see the same code over and over.', 'start': 1297.782, 'duration': 2.783}, {'end': 1308.232, 'text': 'that should be something that pops out to you that there might be a better way of doing this, because usually programmers try to make their code dry,', 'start': 1300.565, 'duration': 7.667}, {'end': 1308.913, 'text': 'which stands for.', 'start': 1308.232, 'duration': 0.681}, {'end': 1310.134, 'text': "don't repeat yourself now.", 'start': 1308.913, 'duration': 1.221}, {'end': 1314.939, 'text': 'the reason for that is because if anything ever changes with these two setup employees here,', 'start': 1310.134, 'duration': 4.805}], 'summary': 'Running the code reveals all tests passing, highlighting repetitive code creation for two employees.', 'duration': 29.7, 'max_score': 1285.239, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1285239.jpg'}, {'end': 1418.829, 'src': 'embed', 'start': 1373.094, 'weight': 0, 'content': [{'end': 1381.398, 'text': 'So the setup method will run its code before every single test, and the teardown method will run its code after every single test.', 'start': 1373.094, 'duration': 8.304}, {'end': 1387.539, 'text': 'So for example, we wanted to create these two employees before every single test.', 'start': 1381.798, 'duration': 5.741}, {'end': 1391.72, 'text': "So we can come down here and grab where we're creating these employees.", 'start': 1387.939, 'duration': 3.781}, {'end': 1395.561, 'text': "And I'm just going to copy that and paste it here within the setup.", 'start': 1392.14, 'duration': 3.421}, {'end': 1399.122, 'text': 'Now, in order to access these from within our other test,', 'start': 1395.881, 'duration': 3.241}, {'end': 1406.443, 'text': "we're actually going to have to set these as instance attributes by putting self.employ1 and self.employ2..", 'start': 1399.122, 'duration': 7.321}, {'end': 1412.486, 'text': "Now, if you don't understand how these instance attributes work,", 'start': 1409.344, 'duration': 3.142}, {'end': 1418.829, 'text': 'then I do have a video in my object oriented series where I go over exactly how those work.', 'start': 1412.486, 'duration': 6.343}], 'summary': 'Setup and teardown methods run before and after each test, creating instance attributes for access within tests.', 'duration': 45.735, 'max_score': 1373.094, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1373094.jpg'}, {'end': 1618.565, 'src': 'heatmap', 'start': 1546.592, 'weight': 4, 'content': [{'end': 1553.878, 'text': "So I'm going to grab from here down and replace this employee test here.", 'start': 1546.592, 'duration': 7.286}, {'end': 1560.562, 'text': 'Now this code is exactly what we just had, but now we have print statements throughout our code.', 'start': 1554.318, 'duration': 6.244}, {'end': 1567.827, 'text': 'So we have a print statement in the setup and in the teardown and also within every single test case.', 'start': 1560.582, 'duration': 7.245}, {'end': 1578.114, 'text': 'So now if I go ahead and run this and scroll up here to the top, then we can see that we have the setup and then the test and then the teardown.', 'start': 1568.307, 'duration': 9.807}, {'end': 1580.656, 'text': 'And it does this for every single test.', 'start': 1578.474, 'duration': 2.182}, {'end': 1582.537, 'text': 'Setup, the test, and teardown.', 'start': 1580.876, 'duration': 1.661}, {'end': 1584.078, 'text': 'Setup, test, teardown.', 'start': 1582.737, 'duration': 1.341}, {'end': 1588.342, 'text': "Now another thing to notice here is that the tests don't necessarily run in order.", 'start': 1584.378, 'duration': 3.964}, {'end': 1592.725, 'text': 'So you should never assume that the tests run straight down through the script.', 'start': 1588.742, 'duration': 3.983}, {'end': 1596.288, 'text': "Now that's why we need to keep all of our tests isolated from one another.", 'start': 1593.046, 'duration': 3.242}, {'end': 1607.178, 'text': "Now. sometimes it's also useful to have some code run at the very beginning of the test file and then have some cleanup code that runs after all of the tests have been run.", 'start': 1596.649, 'duration': 10.529}, {'end': 1612.681, 'text': 'So, unlike the setup and teardown that runs before and after every single test,', 'start': 1607.578, 'duration': 5.103}, {'end': 1618.565, 'text': 'it would be nice if we had something that ran once before anything and then once after everything.', 'start': 1612.681, 'duration': 5.884}], 'summary': "Code has print statements in setup, teardown, and test cases. tests don't run in order. need isolated tests and code to run before/after all tests.", 'duration': 37.689, 'max_score': 1546.592, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1546592.jpg'}, {'end': 1650.198, 'src': 'heatmap', 'start': 1618.925, 'weight': 0.787, 'content': [{'end': 1623.928, 'text': 'Now we can do this with two class methods called setup class and teardown class.', 'start': 1618.925, 'duration': 5.003}, {'end': 1630.232, 'text': 'Now I have these in my snippets also, so let me grab these so we can see what these look like.', 'start': 1624.328, 'duration': 5.904}, {'end': 1638.375, 'text': "and I'll paste these here at the top of our test and let me fix the indentation there.", 'start': 1630.692, 'duration': 7.683}, {'end': 1642.916, 'text': "okay, so we can see that these are class methods, and if you don't know what that means,", 'start': 1638.375, 'duration': 4.541}, {'end': 1650.198, 'text': "basically it means that we're working with the class rather than the instance of the class, like we were with self.", 'start': 1642.916, 'duration': 7.282}], 'summary': 'Using setup and teardown class methods for working with classes.', 'duration': 31.273, 'max_score': 1618.925, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1618925.jpg'}, {'end': 1680.758, 'src': 'embed', 'start': 1657.762, 'weight': 7, 'content': [{'end': 1665.507, 'text': 'But once we have these class methods in place, with these naming conventions of setup class and teardown class, with that camel case,', 'start': 1657.762, 'duration': 7.745}, {'end': 1674.153, 'text': 'if we run this code, then if we scroll up here to the top, then we can see that it runs setup class first and then the setups,', 'start': 1665.507, 'duration': 8.646}, {'end': 1680.758, 'text': 'tests and teardowns for each test And then at the very end, here it runs that teardown class.', 'start': 1674.153, 'duration': 6.605}], 'summary': 'Class methods with naming conventions implemented, running setup and teardown procedures for each test.', 'duration': 22.996, 'max_score': 1657.762, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1657762.jpg'}, {'end': 1732.846, 'src': 'embed', 'start': 1703.294, 'weight': 2, 'content': [{'end': 1706.315, 'text': "Now, as long as you're just reading from the database,", 'start': 1703.294, 'duration': 3.021}, {'end': 1713.798, 'text': 'then it might be appropriate to just set this up once in the setup class method and then you can tear it down in the teardown class method.', 'start': 1706.315, 'duration': 7.483}, {'end': 1717.2, 'text': 'Okay, now I know that this video is getting a bit long,', 'start': 1714.178, 'duration': 3.022}, {'end': 1722.822, 'text': "but there's one more thing that I wanted to show you about unit testing that I think is important for most people to know.", 'start': 1717.2, 'duration': 5.622}, {'end': 1726.864, 'text': 'So sometimes our code relies on certain things that we have no control over.', 'start': 1723.162, 'duration': 3.702}, {'end': 1732.846, 'text': "So for example, let's say that you have a function that goes to a website and pulls down some information.", 'start': 1727.224, 'duration': 5.622}], 'summary': 'Unit testing setup and teardown methods, importance of handling external dependencies in code.', 'duration': 29.552, 'max_score': 1703.294, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1703294.jpg'}], 'start': 1082.026, 'title': 'Unit testing strategies and setup methods', 'summary': 'Covers testing strategies for an employee class, including writing tests for email, full name, and applying a raise, and introduces setup and teardown methods for code reuse. it also explains how to use setup and teardown methods to create instance attributes for unit tests, reducing duplication and ensuring successful test execution, resulting in a passing status for all three tests. additionally, it discusses the usage of setup and teardown methods in unit testing for creating a clean testing environment and the distinction between setup/teardown and setup class/teardown class methods, with practical applications illustrated through examples and explanations.', 'chapters': [{'end': 1372.714, 'start': 1082.026, 'title': 'Testing strategies and context managers', 'summary': 'Discusses testing strategies for a simple employee class, including writing tests for email, full name, and applying a raise, and introduces the concept of setup and teardown methods for reusing code and maintaining it efficiently.', 'duration': 290.688, 'highlights': ['The chapter discusses testing strategies for a simple employee class, including writing tests for email, full name, and applying a raise.', 'The chapter introduces the concept of setup and teardown methods for reusing code and maintaining it efficiently.', "The chapter explains the need to avoid repeating code and introduces the concept of 'dry' (don't repeat yourself) to ensure code reusability and maintainability."]}, {'end': 1506.618, 'start': 1373.094, 'title': 'Unit test setup and teardown', 'summary': 'Explains how to use setup and teardown methods to create instance attributes for unit tests, reducing duplication and ensuring the successful execution of tests, resulting in a passing status for all three tests.', 'duration': 133.524, 'highlights': ['The setup method runs its code before every single test, creating instance attributes for the two employees, reducing duplication and ensuring successful test execution.', 'The teardown method runs its code after every single test, ensuring the cleanup of resources and maintaining a clean test environment.', "The instance attributes 'self.employ1' and 'self.employ2' are used to access the created employees within other tests, contributing to the reduction of duplicate code and ensuring consistent test behavior."]}, {'end': 1722.822, 'start': 1506.958, 'title': 'Unit testing and teardown methods', 'summary': 'Discusses the usage of setup and teardown methods in unit testing for creating a clean testing environment, the distinction between setup/teardown and setup class/teardown class methods, and their potential applications, illustrated through examples and explanations.', 'duration': 215.864, 'highlights': ['The chapter discusses the usage of setup and teardown methods in unit testing for creating a clean testing environment.', 'The distinction between setup/teardown and setup class/teardown class methods is explained, along with their potential applications.', 'The potential applications of setup class and teardown class methods are demonstrated through examples and explanations, such as populating a database for multiple tests.']}], 'duration': 640.796, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1082026.jpg', 'highlights': ['The setup method runs its code before every single test, creating instance attributes for the two employees, reducing duplication and ensuring successful test execution.', 'The chapter discusses testing strategies for a simple employee class, including writing tests for email, full name, and applying a raise.', 'The chapter introduces the concept of setup and teardown methods for reusing code and maintaining it efficiently.', "The chapter explains the need to avoid repeating code and introduces the concept of 'dry' (don't repeat yourself) to ensure code reusability and maintainability.", 'The teardown method runs its code after every single test, ensuring the cleanup of resources and maintaining a clean test environment.', "The instance attributes 'self.employ1' and 'self.employ2' are used to access the created employees within other tests, contributing to the reduction of duplicate code and ensuring consistent test behavior.", 'The chapter discusses the usage of setup and teardown methods in unit testing for creating a clean testing environment.', 'The distinction between setup/teardown and setup class/teardown class methods is explained, along with their potential applications.', 'The potential applications of setup class and teardown class methods are demonstrated through examples and explanations, such as populating a database for multiple tests.']}, {'end': 2339.649, 'segs': [{'end': 1749.803, 'src': 'embed', 'start': 1723.162, 'weight': 0, 'content': [{'end': 1726.864, 'text': 'So sometimes our code relies on certain things that we have no control over.', 'start': 1723.162, 'duration': 3.702}, {'end': 1732.846, 'text': "So for example, let's say that you have a function that goes to a website and pulls down some information.", 'start': 1727.224, 'duration': 5.622}, {'end': 1738.892, 'text': 'Now, if that website is down, then your function is going to fail, which will also make your test fail.', 'start': 1733.246, 'duration': 5.646}, {'end': 1745.759, 'text': "But this isn't what we want because we only want our test to fail if something is wrong with our code.", 'start': 1739.292, 'duration': 6.467}, {'end': 1749.803, 'text': "So if a website is down, then there's nothing that we can actually do about that.", 'start': 1746.059, 'duration': 3.744}], 'summary': 'Code reliant on external factors can cause test failures, e.g., website downtime.', 'duration': 26.641, 'max_score': 1723.162, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1723162.jpg'}, {'end': 1934.98, 'src': 'heatmap', 'start': 1831.869, 'weight': 0.831, 'content': [{'end': 1838.992, 'text': 'We only care that the get method was called with the correct URL and that our code behaves correctly,', 'start': 1831.869, 'duration': 7.123}, {'end': 1843.073, 'text': 'whether the response is okay and whether the response is not okay.', 'start': 1838.992, 'duration': 4.081}, {'end': 1849.176, 'text': "So to do this, let's import something from mock called patch.", 'start': 1843.553, 'duration': 5.623}, {'end': 1859.401, 'text': 'So up here at the top of our test employee module, I will say from unit test dot mock import patch.', 'start': 1849.616, 'duration': 9.785}, {'end': 1861.843, 'text': 'now there are a couple different ways that we can use patch.', 'start': 1859.401, 'duration': 2.442}, {'end': 1874.43, 'text': 'so we can use patch either as a decorator or as a context manager and it will allow us to mock an object during a test and then that object is automatically restored after the test is run.', 'start': 1861.843, 'duration': 12.587}, {'end': 1888.76, 'text': "so let's create a new test down here at the bottom for that monthly schedule method and we'll just call this test underscore monthly Oops and I wanted to call that monthly schedule,", 'start': 1874.43, 'duration': 14.33}, {'end': 1889.981, 'text': 'not monthly method.', 'start': 1888.76, 'duration': 1.221}, {'end': 1891.924, 'text': "And then we'll pass in self.", 'start': 1890.542, 'duration': 1.382}, {'end': 1895.568, 'text': "And so in this example, we'll use patch as a context manager.", 'start': 1892.384, 'duration': 3.184}, {'end': 1911.24, 'text': "So we'll just say, So what we said here was with patch and then within patch we pass what we want to mock.", 'start': 1896.269, 'duration': 14.971}, {'end': 1916.804, 'text': 'And we want to mock request.get of the employee module.', 'start': 1911.56, 'duration': 5.244}, {'end': 1920.167, 'text': "And then we're setting that equal to mocked get.", 'start': 1917.185, 'duration': 2.982}, {'end': 1928.455, 'text': "Now you may wonder why we didn't just import request into our test and just mock that instead of the employee request.", 'start': 1920.548, 'duration': 7.907}, {'end': 1932.418, 'text': "But we want to mock these objects where they're actually used.", 'start': 1929.255, 'duration': 3.163}, {'end': 1934.98, 'text': "So it's actually used in this employee module.", 'start': 1932.578, 'duration': 2.402}], 'summary': 'Using patch from mock to test employee module with context manager', 'duration': 103.111, 'max_score': 1831.869, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1831869.jpg'}, {'end': 2211.104, 'src': 'embed', 'start': 2182.154, 'weight': 1, 'content': [{'end': 2186.837, 'text': 'So now if we run this, then we can see that all of our tests are still passing.', 'start': 2182.154, 'duration': 4.683}, {'end': 2190.579, 'text': 'So I know that this mocking can be a little confusing when you first see it.', 'start': 2187.217, 'duration': 3.362}, {'end': 2194.264, 'text': 'And, like I said, it could probably be a video all on its own,', 'start': 2191.059, 'duration': 3.205}, {'end': 2202.094, 'text': "but you don't use it a whole lot unless you're accessing things like URLs and things that are basically out of your control.", 'start': 2194.264, 'duration': 7.83}, {'end': 2207.021, 'text': "So you don't use it a lot, but whenever you do need it, it is definitely nice to know.", 'start': 2202.395, 'duration': 4.626}, {'end': 2211.104, 'text': "okay, so i think that's going to about do it for this video.", 'start': 2207.461, 'duration': 3.643}], 'summary': 'Mocking is useful for accessing things like urls, but not used frequently.', 'duration': 28.95, 'max_score': 2182.154, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI2182154.jpg'}, {'end': 2267.733, 'src': 'embed', 'start': 2241.112, 'weight': 4, 'content': [{'end': 2244.735, 'text': 'Now, you may have heard something called test-driven development,', 'start': 2241.112, 'duration': 3.623}, {'end': 2250.18, 'text': 'and basically what test-driven development means is that you write the test before you write the code.', 'start': 2244.735, 'duration': 5.445}, {'end': 2254.643, 'text': "And I know that that might sound a little strange, But sometimes I've found it useful.", 'start': 2250.56, 'duration': 4.083}, {'end': 2259.167, 'text': "I don't strictly follow test driven development to where it's something that I always do.", 'start': 2255.104, 'duration': 4.063}, {'end': 2267.733, 'text': 'But basically the concept is that you should think about what you want your code to do and then write a test implementing that behavior.', 'start': 2259.587, 'duration': 8.146}], 'summary': 'Test-driven development involves writing tests before code; emphasizes thinking about desired code behavior.', 'duration': 26.621, 'max_score': 2241.112, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI2241112.jpg'}], 'start': 1723.162, 'title': 'Mocking for reliable testing', 'summary': 'Discusses the use of mocking to ensure reliable testing by addressing the issue of code dependency on external factors, such as website availability, and the importance of isolating code failures from external dependencies. it also covers unit testing with mocking, demonstrating how to use mock objects to isolate tests, assert method calls, and return values, with examples of successful and failed responses, and emphasizes the importance of writing tests before writing the code.', 'chapters': [{'end': 1761.635, 'start': 1723.162, 'title': 'Mocking for reliable testing', 'summary': 'Discusses the use of mocking to ensure reliable testing by addressing the issue of code dependency on external factors, such as website availability, and highlights the importance of isolating code failures from external dependencies.', 'duration': 38.473, 'highlights': ['Mocking is used to isolate code failures from external dependencies, such as website availability, to ensure that tests fail only if there is an issue with the code.', 'Code relying on external factors, like website availability, can lead to test failures, impacting the reliability of the testing process.', 'Addressing code dependency on external factors, like website availability, is crucial for reliable testing to ensure that test failures are indicative of code issues rather than external factors.']}, {'end': 2339.649, 'start': 1762.015, 'title': 'Unit testing with mocking', 'summary': 'Discusses unit testing with mocking, demonstrating how to use mock objects to isolate tests, assert method calls, and return values, with examples of successful and failed responses, emphasizing the importance of writing tests before writing the code.', 'duration': 577.634, 'highlights': ['Demonstrating how to use mock objects to isolate tests, assert method calls, and return values', 'Examples of successful and failed responses using mock objects', 'Emphasizing the importance of writing tests before writing the code']}], 'duration': 616.487, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/6tNS--WetLI/pics/6tNS--WetLI1723162.jpg', 'highlights': ['Mocking isolates code failures from external dependencies, ensuring tests fail only due to code issues.', 'Unit testing with mocking demonstrates isolating tests, asserting method calls, and return values.', 'Addressing code dependency on external factors is crucial for reliable testing.', 'Code relying on external factors can lead to test failures, impacting testing reliability.', 'Emphasizing the importance of writing tests before writing the code.']}], 'highlights': ['Unit testing saves time and ensures code functionality', 'Mocking isolates code failures from external dependencies, ensuring tests fail only due to code issues', 'The setup method runs its code before every single test, creating instance attributes for the two employees, reducing duplication and ensuring successful test execution', 'The chapter emphasizes writing good tests over quantity, demonstrated by adding and testing multiple functions in a single test method', 'The chapter discusses the importance of updating tests after making code changes', 'Running four tests for calculator functions with assert equal statements and all passed', 'The chapter introduces the concept of setup and teardown methods for reusing code and maintaining it efficiently', "The chapter stresses the creation of test cases by inheriting from the unit test module's test case and the importance of naming test methods with 'test_' prefix", 'The chapter discusses testing strategies for a simple employee class, including writing tests for email, full name, and applying a raise', "The chapter explains the need to avoid repeating code and introduces the concept of 'dry' (don't repeat yourself) to ensure code reusability and maintainability", 'The distinction between setup/teardown and setup class/teardown class methods is explained, along with their potential applications', 'The potential applications of setup class and teardown class methods are demonstrated through examples and explanations, such as populating a database for multiple tests', "The chapter emphasizes the naming convention for test modules, requiring the file to start with 'test_' and followed by what is being tested, such as 'test_calc'", 'The chapter covers the usage of assert equals to test the add function', 'The importance of learning unit testing for job prospects', 'The chapter discusses the usage of setup and teardown methods in unit testing for creating a clean testing environment', 'The importance of naming test cases properly', 'The chapter discusses the use of mocking to ensure reliable testing by isolating code failures from external dependencies', "The chapter explains the process of importing the unit test module and the module to be tested, highlighting the standard library's accessibility of the unit test module", "The instance attributes 'self.employ1' and 'self.employ2' are used to access the created employees within other tests, contributing to the reduction of duplicate code and ensuring consistent test behavior", 'The chapter discusses testing for error handling and comparison of two methods of testing exceptions in Python', 'The significance of rerunning tests to ensure everything still works after making changes in the program', 'Unit testing with mocking demonstrates isolating tests, asserting method calls, and return values', 'The importance of ensuring test quality to catch mistakes is highlighted', 'Emphasizing not just writing as many tests as possible, but making sure that the tests are good enough to catch mistakes', 'Testing edge cases such as negative and positive numbers', 'Addressing code dependency on external factors is crucial for reliable testing', 'Code relying on external factors can lead to test failures, impacting testing reliability', 'Emphasizing the importance of writing tests before writing the code', 'Identifying the typo in the multiply function as the cause of the failed test, which should return 50 but instead gives a different value', 'Rerunning the test reveals that three out of four tests pass, indicating the failure of one test due to the incorrect value being returned']}