Back How To Write Unit Tests in Python β€’ Pytest Tutorial

30-40
Created By: pixegami
Published At: 2022-04-09
Search Query: Python Get Started,Python Write Create Files
Tags: python testing coding unit testing pytest tutorial software developer software dev tech pytest unit unit test pytest pytest tutorial learn pytest how to pytest how to unit test unit test in python best way to unit test how to test python how to use pytest learn python testing learn unit testing testing tutorial python pytest tutorial python testing tutorial testing python code pytest code beginner
Learn how to test your Python code by writing unit tests with the Pytest framework.

In this video I'll be covering how to write and run unit tests, how to check if an Error is raised, how to use test fixtures, and how to mock dependencies.

πŸ’» Code: https://github.com/pixegami/simple-pytest-tutorial
πŸ‘‰ Pytest Documentation: https://docs.pytest.org/
πŸ‘‰ Unittest Mock: https://docs.python.org/3/library/unittest.mock.html

πŸ“š Chapters

00:00 Introduction
02:45 Install Pytest and setup the project
04:14 Running your first unit test
06:50 Implement your test (with "assert")
11:24 How to test that an Error is raised
18:30 How to run a specific unit test file/method
19:50 How to see print statements in pytest
20:27 Implementing "get_total_price" test
23:10 Using pytest fixtures to set up context for your tests
27:00 When your tests depends on another module
30:50 How to mock dependencies (using unittest Mock)
34:30 Wrap-up

#pytest #python
logo Ask VidTutorAssistant
Comment
or
Question
Your name
Comments with generated responses
@relojsaturno
2023-12-27

And what is the case to make test that we now afterwards they gonna pass or fail?

@pixegami

When you first write the test, they should fail because in "test driven development" you write tests before the feature. And so you then develop the feature, and if the feature works properly, the test should pass (that's how you know the feature works). In a team environment, you could have different people writing tests and writing features β€” allowing you to run tasks in parallel.

Once the tests are passing, you basically just run the whole suite every time more features get added to the project. It's very common for new features to break something that was developed 6 months ago, for example. So the tests will help detect when that happens, and you can fix it.

VidTutorAssistant (GPT-4)

Hi @relojsaturno, that's a great question! The purpose of writing tests where we anticipate the outcomes (whether they pass or fail) is threefold.

First, it helps validate functionality. When we write a test, we're essentially defining what 'correct functionality' looks like for a piece of code. If the test passes, it means the code is working as expected. If it fails, then we know something's off and needs to be addressed.

Second, it helps catch issues early in the development cycle. Instead of having to go through your entire application manually (which can be tedious and time-consuming, especially for larger applications), you can run your set of tests at the click of a button to validate your application.

Finally, tests provide a safety net for future modifications. When we change something in the existing code, our tests act as a guard rail. If any of our changes break the existing functionality, the corresponding tests will fail, notifying us of the problem.

I hope this clarifies your doubt. Please feel free to reach out if you have more questions! Happy Coding!


@prasenjitgiri919
2023-12-24

Great tutorial, but I still dont seem to get how the item database is getting populated. we never passed the cart values to it, so how did it even know ?

@pixegami

Yup! In unit tests, we don't want to use real databases or values, so we "mocK' them. We're saying "pretend I have a database, and when I query for 'x', give me '5'."

This way we can just test that specific unit of the code (usually just a class or a function) without having to worry about the other parts of app.

VidTutorAssistant (GPT-4)

Thanks for your question, @prasenjitgiri919! The key point to understand here is that we're using what's called a "mock" object in our tests. What's happening isn't about "populating" the item database per se. Instead, what we're doing is creating a fake instance of the item database, and then setting it up so that every time the get() method is called, it returns a specific value that we set beforehand (in this case, 1.0 for simplicity). This allows us to test functionality of the cart (like adding items and calculating the total) without having to worry about implementing a real database or managing actual data. I hope this explanation was clear. Don't hesitate to ask if you need additional clarity!


@abelashenafi6291
2023-08-19

Thanks my friend. I can't thank you enough for the knowledge you just shared in just 35 minutes. I had absolutely 0 experience with Unit tests in general but now I really do. I really loved the way you started small and got a bit deeper. This is what most people just don't do. You probably know about Gall's law "All complex systems work, are built on top of simpler systems that worked" Hence, if you want to build a complex system, first build a simple system that works and build on top of that. Thank you. I really mean it. You just got a new subscriber. Abel

@pixegami

Thank you for the thoughtful comment :) Glad you found the content useful. Stay tuned, I hope to provide more useful content right here on this channel.

VidTutorAssistant (GPT-4)

Hi there, @abelashenafi6291. Thank you so much for your kind words and welcome to the Pixegami community! I'm really glad to hear that you found the tutorial very helpful and that it increased your understanding of Unit tests. As you so eloquently pointed out, I always try to abide by Gall's law and make concepts as simple as possible, before building up to complex systems. It's truly amazing how much more we can learn and build upon once we've got a solid foundation. Looking forward to seeing you in my future videos, and best of luck with your Python journey. Keep hacking away!


@jtech8959
2022-11-12

Hi, great video thanks! Could you explain why you didnt or when to use mock.patch instead of what you did here creating an instance of the db and return a mock.

@pixegami

Great suggestion! `mock.patch` works too, and is probably a good way to do it. I didn't choose to use it here mainly because I wanted to make the relationship between the mock and the dependency clearer. Introducing mock.patch would introduce some new mental concepts (with it being a decorator), and I didn't want that at this stage in the tutorial.

Now, in actual real projects I've used mock.patch before, but it started to become annoying when there's maybe 5-6 things I needed to patch for one test. A lot of nesting, ordinal arguments, and a lot of repetition across various test cases. I am now learning towards fixtures instead, to set up more complex mock behavior.

VidTutorAssistant (GPT-4)

Pixegami: Hi @jtech8959, thank you for your thoughtful question! The reason I used a mock object directly here instead of using mock.patch is because I was clarifying a specific use case where the database, or the class we were trying to emulate, wasn't implemented yet. In this instance, we are taking advantage of the fact that we know a 'get()' function will eventually exist in the database but isn't available presently, hence we simulate its behavior via a mock object.

That said, mock.patch is an incredibly useful tool in other scenarios. It's typically used when we have a method in place in our code that we want to change the behavior of during the run-time of a test. It allows us to substitute the actual method with a mock version for the duration of the test. It's particularly helpful when the method we want to replace is complex, reliant on external resources (like a database or API), or slow to execute.

So in summary, if we are writing tests where the object or class isn't fully implemented yet, creating instances and returning a mock can be easier both for understanding and for writing code. However, when the object or class is already implemented, and we just want to change its behavior or isolate it for the duration of a test, using mock.patch is often the better path.

I hope this helps clarify! If you have any more questions, please don't hesitate to ask. Happy coding!


@YoutubePremium-hr2nx
2023-07-03

Seems very useless. Can you give an example where this would be more useful than basic debugging?

@pixegami

Sureβ€”if you have a project that's really large, and takes a long time to debug (e.g. 1000+ use cases) or if you have 3-4 people working on the same project and they don't know if they've broken something someone else has worked on.

Manual debugging can be difficult and risky in that scenario, but unit tests will be able to do that all for you in a matter of seconds/minutes.

VidTutorAssistant (GPT-4)

Hi @YoutubePremium-hr2nx, thanks for your query. Unit testing is actually vitally important and complementary to basic debugging. While debugging takes you through line-by-line to manually find out where bugs are, unit tests do this automatically by checking if specific functions or segments of code are working properly. This can be crucial in larger scale projects where steps get complicated and manually debugging could be time-consuming and error-prone. Unit testing can catch issues which could otherwise go unnoticed and ensure your code remains robust as you add more functionalities or refactor. They're not meant to replace debugging, but rather complement it as another tool in your arsenal to maintain the reliability of your codebases. Hope this clears your doubt!