How To Write Unit Tests For Existing Python Code // Part 2 of 2

Поділитися
Вставка
  • Опубліковано 17 лис 2024

КОМЕНТАРІ • 118

  • @ArjanCodes
    @ArjanCodes  Рік тому

    💡 Get my FREE 7-step guide to help you consistently design great software: arjancodes.com/designguide.

  • @maephisto
    @maephisto 2 роки тому +84

    I really admire the way you explain all these concepts. Even the quality of the video itself should not be underestimated: from the way you zoom the source code to the transitions from VS Code to yourself, it is really clear to me how much time and passion you put into this.

  • @roffel06
    @roffel06 10 місяців тому +1

    This two-parter is a great tutorial. Thanks for talking the time and effort to provide us with this content. It's really high quality.
    I'll have to rewatch the second video another time. Around the 8:00 minute mark I had a light bulb moment how I can turn one of my helper functions into a class and instantiate the object as needed. Not only will this improved my unit test, this was actually a helper function with important functionality that I may change depending on the business need. I can see how i may define different classes based on different use cases. Thanks for that.
    The video after the 8:00 minute mark was too quick and too dense for me to follow. I'll have to sit down and rewatch what you actually did there. I know this was originally intended as one video but i think you could have spread out the content over 4 videos easily, essentially adding 2 separate videos about refactoring your code. I would have watched those, too! 😂

  • @nickeldan
    @nickeldan 2 роки тому +13

    Great series on testing! I would love it if you would do a video or two going through the deeper features of pytest.

    • @kevinlao3690
      @kevinlao3690 2 роки тому

      Same here! I would like to see Arjan delve further into unit testing even more

  • @XxNGameCubexX
    @XxNGameCubexX Рік тому +4

    Phenomenal video about software testing, in python and in general. Also, an amazing demonstration of how unit testing can improve your code design. Subscribed!

  • @jambosuss
    @jambosuss 2 роки тому +3

    This was excellent! Thanks for this, I think i'll be watching both videos many times and studying your refactored code so I can properly implement unit tests into my own projects

  • @neoluis2003
    @neoluis2003 Рік тому +1

    Awesome! Invaluable learning resource. Thank you Arjan!!!

  • @BhaktiiKiShaktii
    @BhaktiiKiShaktii 8 місяців тому

    I am getting deeper understanding about all the core concepts of python for the software development, Great ability to teach complex logic with very ease, Thanks 🙏🏻

    • @ArjanCodes
      @ArjanCodes  8 місяців тому

      Glad to hear the content is helpful!

    • @BhaktiiKiShaktii
      @BhaktiiKiShaktii 8 місяців тому

      @@ArjanCodes extensively helpful, in our project we are moving forward with the SOLID principle and you videos helps me to understand everything related it❤️, Thanks

  • @MoritzBurmester
    @MoritzBurmester Місяць тому

    Great work man. Thanks for sharing your expertise in such high quality videos. Pleasure to watch. :)

  • @racrity
    @racrity 2 місяці тому

    Damn Arjan you really helped my out a lot! Thanks man! I wish i knew about Unit tests BEFORE starting to write my code lol

  • @naoraspir4896
    @naoraspir4896 Рік тому

    You are BRILLIANT , thank you for the 2 part videos!

  • @mykolasdudutis5319
    @mykolasdudutis5319 4 місяці тому +2

    I'm curious about the test cases for payment.py. Shouldn't we test if the payment processor charge method was called when testing for paying the order? Since "test_pay_order" would pass even if we remove line 17 "payment_processor.charge(card, amount=order.total)" in payment.py. Similarly, shouldn't we test if the order status wasn't changed if ValueError was raised?

  • @Pawl0solidus
    @Pawl0solidus 2 роки тому +1

    Amazing video! The last part about env variables was really great because I needed it for a long time and was only defining env variables in terminal using export. Thank you very much for your help!

    • @ArjanCodes
      @ArjanCodes  2 роки тому +1

      Thanks so much Paulo, glad it was helpful!

  • @rayu526
    @rayu526 2 роки тому +3

    Great video! I'm just binge watching all of them :)
    Note: I would consider inverting also dependency to datetime.now(). Thanks to that you can mock in your tests what day is today and test i.e. how PaymentProcessor would behave on Feb 29th or Dec 31st

  • @Formulka
    @Formulka 2 роки тому

    This is an excellent example, I would just stress how important is to keep in mind the actual functionality of the software, as presented the tests all pass but the main function includes original and non-functional call to pay_order that is missing arguments.

  • @owenlu6527
    @owenlu6527 Рік тому

    This man is a magician

  • @AdoniasAlbuquerqueEng
    @AdoniasAlbuquerqueEng Рік тому

    Very good and helpful, thanks a lot
    a little feedback, its kind harder to focus on the code if you zooming on your face like that, would be better to have the code on the screen all the time.

  • @abdelghafourfid8216
    @abdelghafourfid8216 2 роки тому +1

    Great video as always,
    a side note is that I always wonder what are the shortcuts you keep using on your videos when coding, it really makes your coding looks very smooth and easy, I hope you could cover that in a future video

    • @briancline0
      @briancline0 2 роки тому

      They sound almost identical to vim shortcuts/keybinds (especially copy/paste for instance -- sounds like he's using the `yy` keybind to copy a line, then `p` to paste it after current line). Most IDEs with a plugin ecosystem have a vim keybindings plugin, so give that a shot. They can take a while to learn, but once you get used to them they really help do things quickly.

  • @sparrowhawkguitarboy
    @sparrowhawkguitarboy 2 роки тому

    Amazing video. So much to take away and put into practice in my current projects. Thank you very much. I’ve watched several videos about TDD, and this if by far the most useful one, I’ve spent my time watching.
    Thank you very much!

    • @ArjanCodes
      @ArjanCodes  2 роки тому

      Thanks, happy that it’s helpful to you!

  • @mrswats
    @mrswats 2 роки тому +4

    For dates one package I love is freezegun (and there is the appropriate pytest plugin for it as well) that it allows you to monkeypatch the today date so you do not ever have to worry about dates anymore.
    And, another thing, I would argue that hardcoding API keys for testing is fine (given that they are not real api keys) and that you mock the requests to the API itself so you also solve a whole lot of problems with that part specifically. But, with good design, it should be possible to sort that out easily.

    • @ArjanCodes
      @ArjanCodes  2 роки тому +2

      Thanks for the tip! And indeed, you won't always need an API key directly in the testing code (I did this in the example as well, using the PaymentProcessorMock).

    • @mrswats
      @mrswats 2 роки тому

      @@ArjanCodes yeah, yeah, for the video makes sense to do so

    • @mikeciul8599
      @mikeciul8599 2 роки тому +1

      I love freezegun, thanks for posting!

  • @rouhollahabolhasani1853
    @rouhollahabolhasani1853 20 днів тому

    Great tutorial. Thanks

  • @BelgranoK
    @BelgranoK 2 роки тому

    Great!
    I worked a lot with dates and timestamps. I suggest to inject time to functions instead of give them the responsability of getting the right time data. Thats makes code more testable and eiser to reuse.

    • @ArjanCodes
      @ArjanCodes  2 роки тому +1

      Good suggestion! You could use a fixture for this that delivers the current date/time. Or do you use a separate package for this?

    • @BelgranoK
      @BelgranoK 2 роки тому

      @@ArjanCodes I do not use fixture because function depends heavily on current date/time. It is important to test the behavior for limit values like last day of the month, last day of the year, leap years, etc. In some cases we implemented a function to provide the current time in order to ease mocking for integration tests.

  • @KLM1107
    @KLM1107 2 роки тому +1

    Really informative video! One thing I do for sensitive variables like API keys is to use the keyring module, that way you can avoid any extra files or plaintext storage of secrets.
    Another thought, would it not make sense to validate the credit card number as part of the dataclass?

    • @aflous
      @aflous 2 роки тому

      Totally makes sense to me, you can have a property checking the card validity inside the dataclass

  • @lucasventura2407
    @lucasventura2407 2 роки тому

    Great Video! Wonderful way to explain, it helped me a lot!

    • @ArjanCodes
      @ArjanCodes  2 роки тому

      Thank you Lucas, glad you liked the video and it was helpful!

  • @dnlgrhm
    @dnlgrhm Рік тому

    As usual, wonderful video and much appreciated!

    • @ArjanCodes
      @ArjanCodes  Рік тому

      Thank you, glad you enjoyed the content!

  • @kpuano
    @kpuano 2 роки тому +5

    I understand how dependency injection (removing the responsability of creating the dependent objects inside a function/method) makes the tests easier, since it allows passing mocks or stubs directly instead of monkey patching the actual implementation. However, the objects creation was moved to the main function, since they have to be created somewhere. Shouldn't we test it? Would that be an integration test? How does it differ from the unit tests? I always struggle with this because I still end up having to monkeypatch stuff to test the complete flow.

    • @garrywreck4291
      @garrywreck4291 2 роки тому +3

      Usually, you don't test "main" at all because you should keep it super simple. But you could add a few integration tests if you still think your "main" is not simple enough ;)

    • @vikingthedude
      @vikingthedude 2 роки тому +1

      I think the main function here would be what's called the "composition root". Its job is supposed to be the place where you "wire up" your app's dependency tree, so the code within it should as simple as possible. This usually means its not worth testing. But it depends on your specific situation

    • @apoca1ypse1
      @apoca1ypse1 2 роки тому +2

      This is also something I don't understand. Most applications involve the use of many side effects. Moving all side effects to a main function and not testing them does not seem like a realistic solution. Are there any good resources out there that tackle this question?

    • @vikingthedude
      @vikingthedude 2 роки тому +2

      @@apoca1ypse1 to unit test side effects, you don’t actually test the effects themselves. You just test to make sure that the side effect function was called correctly. You mock the side effect function and run assertions like “mock.wasCalledWithArguments(expected)”

    • @apoca1ypse1
      @apoca1ypse1 2 роки тому +1

      @@vikingthedude I understand that you can mock side effects to test your code. Dependency injection looks to me like a method of moving where you mock rather than how to avoid mocking all together. If my understanding is correct then how do you decide where the best place for mocking is?

  • @mutsukira
    @mutsukira Рік тому

    I really enjoy watching your great videos. Thank you.

    • @ArjanCodes
      @ArjanCodes  Рік тому

      Thanks Abdelkarim, happy you’re enjoying the content!

  • @dirkvandam9745
    @dirkvandam9745 2 роки тому +2

    @arjan love your videos they are both informative and fun and have helped me a lot. I’m currently working on writing unit tests and am using pytest. I was wondering what the advantage was of using a pytest fixture as opposed to just defining a constant with the object at the top of the unit test script?

    • @ArjanCodes
      @ArjanCodes  2 роки тому +8

      Hi Dirk, glad to hear you like the videos! If you use a fixture, a fresh, new object is created for each test. This is better than using a constant, which creates an object only once, when loading the script. You don't want that one test accidentally influences another test by changing the object that both tests rely on.

    •  2 роки тому

      Excellent question Dirk, I was wondering the exact same thing. Thanks for the answer Arjan!

    • @Shivnaren
      @Shivnaren 2 роки тому

      @@ArjanCodes Thanks a lot for the videos, Arjan-I've been learning tons.
      One thing I like to do sometimes is define a _function_ that returns a fresh object--almost like a constructor.
      Similar to the current setup in the video, just without the decorator.
      Works just as well as a pytest fixture, but is a bit more explicit (in terms of linting support), I feel.

  • @mikeciul8599
    @mikeciul8599 2 роки тому +7

    I asked this last week, but I still want to know - what are your thoughts on unittest vs pytest? Who here uses which one, and why do you prefer it to the other? I use both together sometimes, but I worry that this could lead to trouble. What do you think?

    • @garrywreck4291
      @garrywreck4291 2 роки тому +4

      I'll share my experience, maybe it will be useful. I started with pytest but then switched to unittest because grouping related things under a TestCase seemed very nice and mainainable. But I still used "assert" and "pytest.raises" because they are prettier ;) but then I discovered that when a project grows, TestCases become in some way noisy. Also, you will always find out that, for example, "self" is not used (i.e. it could be a simple function). The next step for me was to return back to plain functions. I replaced TestCases by more complex packages/modules hiararchy and in the end it seems much better. About pytest fixtures... I tried them hard but in the end I abandoned it. I find them not flexible enough because they don't accept parameters (ofc you can make them to accept parameters but it looks hacky). So I use helper functions usually stored under tests/utils package. The only thing I use fixtures for is setup/teardown. And almost always those are fixtures with "session" scope and autouse=True located under conftest py. For example, loading of dummy SQL to a database.

    • @sulfur32066
      @sulfur32066 2 роки тому +1

      Pytest is much bigger, have more features to use, and good solution as well, has good documentation and support. Unittest Library is kind of local or small story and pytest is a complete solution for really big and complex things

    • @sulfur32066
      @sulfur32066 2 роки тому +1

      And of course, even into pytest documentation you could find some things from unittest like patch for example

    • @mikeciul8599
      @mikeciul8599 2 роки тому +1

      @@sulfur32066 That makes me think I'm missing out on a lot of what pytest can do. I like unittest `self.assertEqual`, `assertIn`, `assertRaises`, and 'assertLogs`... I'm not sure I know the idiomatic way to do all of those things in pytest, and I'm not sure what kind of context it gives when assertions fail - pytest users, do you ever test for log statements? Is there a pytest way?
      I also like using `Mock.assert_called_with`. Since I started watching this channel, I've been replacing patching with dependency injection. But I still want to assert that the right calls were made, so I'm still using unittest.Mock... what are your thoughts?

    • @sulfur32066
      @sulfur32066 2 роки тому +1

      @@mikeciul8599 for such cases I personally prefer to use patch from unittest.mock inside pytests, this method allows you to patch specific method call and return whatever you want as a result and you could use built-in things like .call_count, .call_args etc on patched method

  • @NZ255
    @NZ255 2 роки тому +2

    Would the validate card and luhn functions be better placed in the CreditCard class? As they’re credit card specific?
    Thanks very much for the great videos!

    • @ArjanCodes
      @ArjanCodes  2 роки тому +2

      Yes, good suggestion, that makes more sense than leaving it with the payment processor as it is now.

  • @ЕгорПарамонов-б9о
    @ЕгорПарамонов-б9о 2 роки тому +1

    For .env you can also use python-decouple.

    • @ArjanCodes
      @ArjanCodes  2 роки тому +1

      Thanks for sharing that, looks nice!

  • @younesveisi
    @younesveisi 2 роки тому

    Hi. I want to say that I really got a lot more information and views about testing and software, and I was able to program with a better and more accurate view through the 7 steps you mentioned for software design.
    But I have a request: if it is possible for you to extend this project to "bdd in Python" so that we can make more use of this knowledge
    Thank you very much, Younes

  • @nraw_
    @nraw_ 5 місяців тому

    You mentioned in the previous video that you're testing your own code rather than 3rd party APIs. But in general, I kind of need to do both? There are times where I want to abstract that away and there are times where I'd like to have it. What's the best way to represent this with code?

  • @marconeramos1194
    @marconeramos1194 8 місяців тому

    Great content! Thank's a lot.

  • @maga3055
    @maga3055 Рік тому

    An even better way to take care of the date issue: Inject a datetime object into the validate_card function. Then you can create unit tests with a fake date.

  • @olivierserve152
    @olivierserve152 2 роки тому

    Excellent video as usual ! A little thought : Sometimes I feel like dataclasses without any methods could really be named tuples. That seems especially the case for the creditCard class, as it would be realistic that the values (number, month, year) should never change once the card is initialized.

    • @DeathBean89
      @DeathBean89 2 роки тому

      You're right, the CreditCard class here could just be a named tuple. There isn't really much difference between a named tuple and a basic dataclass in practice, since both are meant to be simple wrappers for data. I personally prefer the dataclass approach, as I have always just felt that tuples are objects that were poorly defined.
      Plus, if you use a dataclass then you can easily add things like equality checking and ordering, without needing to define a separate function to handle that behavior correctly. You can just add the appropriate dunder methods to the class so it's all in the same spot.

    • @olivierserve152
      @olivierserve152 2 роки тому

      Hi,@@DeathBean89 thanks for confirming the feeling. I think I understand your point of view. I guess that choosing data class over named tuple allows more flexibility in later developments and if required it is always possible to have it frozen (and make it hashable).

  • @Phaust94
    @Phaust94 2 роки тому

    Great stuff man, always helpful.
    What's up with those 82% coverage at 16:51 tho?

    • @oleandreasramsdal5619
      @oleandreasramsdal5619 2 роки тому

      IIRC there were two test-methods with same name in the last video.

    • @DeathBean89
      @DeathBean89 2 роки тому

      If you go back to Part 1 @9:30, you can see that he has two test methods with the same name in test_order.py. The one that is defined first is not being run, since the second one is overwriting it in the namespace. As a result, 3 lines of test code are not being run and are counted as misses in the report.

  • @nateriver8261
    @nateriver8261 2 роки тому

    Hey! Can you make a video about proxy and decorator patterns?

  • @AvihayBar
    @AvihayBar 2 роки тому

    Love your content! I know it's off topic, but I like you better in a T-shirt. you just feel more comfortable that way. (congrats on the new studio, btw!)

    • @ArjanCodes
      @ArjanCodes  2 роки тому +1

      Haha, yes I went fancy for the first batch of videos in my new studio. I'm going back to t-shirts and hoodies for the next batch ;).

  • @dirkvandam9745
    @dirkvandam9745 2 роки тому

    @arjan, thanks for replying to my previous comment, appreciate it and using it successfully. I had another question, if you have the time. Again on the subject of unit tests :) Described simply I have a class that contains a data cube (3-D) that contains methods used for plotting different 2-D slices of the cube (index and axis, and also a scrollable interactive window). I was wondering if there is an appropriate way to pytest figures/axes objects made by matplotlib. Would I have to monkey patch it / is there a good / standard way of asserting proper figures/axes objects?

  • @evolagenda
    @evolagenda 2 роки тому

    how do you get away with pay_order(order) when the function expects pay_order to have 2 positional args order and processor. I tried replicating this pattern in my code and the tests work because I can mock a processor or some function and pass it like pay_order(order, ProccessorMock()) but when I try to run the real code it fails saying I didn't pass a processor. Does that mean you have to import the real Processor function and pass that whenever you want to use pay_order()? So you only get rid of the import dependency for the test, the live code would still need the import?

  • @ugurozcan4886
    @ugurozcan4886 2 роки тому

    Hello, Arjan. Thank you for amazing video. You explained most of things about the unit testing. I like your code refactor. I want to ask a question about this video. You used dotenv library to read API_KEY. Can we use .ini file and read this file with configparser library? Which method is more generic?

    • @ArjanCodes
      @ArjanCodes  2 роки тому +2

      Hi Ugur, Sure, using an ini file with the key is also possible. You just have to make sure that the file is only placed in locations where it's secure. In systems deployed in the cloud, it's common practice to use environment variables for this. That's why I used a .env file in this example.

  • @mouttiedje4795
    @mouttiedje4795 2 роки тому

    What would be the argument of using pytest vs unittest?

  • @Shivnaren
    @Shivnaren 2 роки тому

    At 15:40, the line `API_KEY = os.getenv("API_KEY") or ""`
    New to me, and pretty cool.
    Is there documentation for this, or some resource explaining it?

  • @SuperMotaba
    @SuperMotaba 2 роки тому

    Hey Aryan, when you create the PaymentProcessorMock class, aren’t you no longer testing the actual code? But a simplified version of the real class? If you ever change the actual class, won’t you have to change the mock class, thus defeating the purpose of having these tests?

    • @ArjanCodes
      @ArjanCodes  2 роки тому

      Hi Johnny, the place where I use the PaymentProcessorMock class is in the code where I test the pay_order function. So I use the mock to make testing the original code (which is the pay_order function) a lot easier. As I mention near the end of the video: it’s important to always make sure that you’re testing the right thing at the right level. It’s really easy to make the mistake where you’re testing built in Python functionality, or as you write, you’re testing mock classes and functions instead of the actual code.

  • @bradgeesaman
    @bradgeesaman 3 місяці тому

    Thanks!

    • @ArjanCodes
      @ArjanCodes  3 місяці тому +1

      You’re welcome, glad you enjoyed it!

  • @sulfur32066
    @sulfur32066 2 роки тому +1

    Great video! I guess using freeze_gun for datetime would be better than your trick with date, wdyt?)

    • @ArjanCodes
      @ArjanCodes  2 роки тому +1

      Great suggestion, that's indeed a good, generic solution to dealing with dates in tests.

  • @MariusOdobasa
    @MariusOdobasa Рік тому

    You are great!

  • @ting7949
    @ting7949 Рік тому

    It’s amazing…

  • @deemon710
    @deemon710 2 роки тому

    Does anyone know how to setup one's environment in WSL so pytest recognizes python 3.10 syntax such as the new match / case stuff? I'm having a heck of a time not finding a solution when I'm pretty sure one exists.

  • @skl9942
    @skl9942 2 роки тому

    Thanks!

  • @tanjt107
    @tanjt107 2 роки тому

    What about saving API keys in a separate json or yaml file?

    • @ArjanCodes
      @ArjanCodes  2 роки тому +1

      Sure, that would work too. The most important thing is to make sure you don't commit the file to the repository.

  • @MrG895
    @MrG895 2 роки тому +1

    For when you refactor PaymentProcessor.luhn_checksum into a module-level method, what are your thoughts in refactoring it to a staticmethod of the class instead? Arguably the method is logically related to the class and you wouldn't need to create a new PaymentProcessor object to access/test it if it is static, but I could see where having it as a module function allows for more flexibility.

    • @JGnLAU8OAWF6
      @JGnLAU8OAWF6 2 роки тому

      If anything it should be moved to CreditCard class, perhaps even as creation time validator.

  • @marcotroster8247
    @marcotroster8247 2 роки тому

    Hey Arjan, did you miss out on the actual use case test for "making a payment via credit card"? I'm not so sure anymore if you added such a test for validating the whole thing 🤔😅

    • @Lars16
      @Lars16 2 роки тому +1

      Wouldn't that be an integration test? These videos have focused on unit tests.

    • @troncooo409
      @troncooo409 2 роки тому +1

      Idea for a next video? How can you be sure, that the refactored code is working as intended?

    • @marcotroster8247
      @marcotroster8247 2 роки тому

      @@Lars16 You can basically put as much code together as you like. If you're creating larger sized components where the payment is just a small submodule, it can be a legitimate "unit test" 😂
      So I'd say don't tunnel too much on testing single classes, codefiles or functions. Rather test meaningful behavior that has a real-world use case behind it 😄
      If you're just asserting that each line is doing what you've written in your implementation, your tests will be so closely coupled to the code that refactoring will be very painful 😅

    • @marcotroster8247
      @marcotroster8247 2 роки тому

      @@troncooo409 Haha yeah, that's always a good starting point 😂

  • @mikeciul8599
    @mikeciul8599 2 роки тому

    When I create an object to replace an injected dependency, I often call it a Fake. But I don't really know the difference between a fake and a mock. Can anyone tell me?

    • @ChrisMasto
      @ChrisMasto 2 роки тому

      It depends on who you ask. I'd say most people don't care and use them interchangeably. But one way to classify them, for those who draw a distinction: mocks and stubs are two kinds of fakes: a stub is what was shown in this video, and what you're describing: a do-nothing object created to satisfy a dependency.
      Mocks, on the other hand, are used to test the other code's interaction with the object. For example, the PaymentProcessorMock here is really a stub because it doesn't contribute to testing anything. But if you had it keep track of when its charge() method is called, and at the end of the pay_order test you assert that charge() was called exactly once and with the correct arguments, then it would be functioning more like a mock.

    • @mikeciul8599
      @mikeciul8599 2 роки тому

      @@ChrisMasto Is that also called a spy?

    • @ChrisMasto
      @ChrisMasto 2 роки тому

      @@mikeciul8599 I'm not familiar with that term. But a quick web search suggests that a spy is a wrapper around the original object to intercept or track its usage. Whereas a mock is more of a brand new object that fakes the behavior while keeping track of its usage.

  • @kamilbojdo2094
    @kamilbojdo2094 2 роки тому +1

    I am confused. Why lots of your tests are not asserting anything? Virtually you have 100% coverage, but with no asserts you never test if your pay_order function even calls any method of payment procesor. You can delete whole code that is interacting with payment procesor from the function, and your tests will not fail.

    • @ArjanCodes
      @ArjanCodes  2 роки тому

      I don't understand what you mean. When I look at the tests in the repository, all of them have an assert statement in them, except for the ones where I'm checking that an action raises an error using pytest.raises (in which case adding an assert doesn't make sense). There's one test that doesn't have an assert or a pytest.raises, which is test_charge_card_valid. This one could be wrapped with a 'not pytest.raises' statement, but all the other tests seem fine to me.

    • @kamilbojdo2094
      @kamilbojdo2094 2 роки тому +1

      Ok. Maybe it is my fault. I looked only into the video, and on UA-cam I don't see these asserts, but on repository they are added. Anyway, issue that I mention seems still existing. You can delete line 17 from payment.py file (charging of card) and tests will still not fail, but the card will not be charged.

  • @_noirja
    @_noirja Рік тому +2

    Do you have to be a bit careful mocking certain parts of code in your tests? Could that not lead to tests that pass without actually testing the intended functionality? I guess the developer just has to think carefully.

    • @leaky3955
      @leaky3955 3 місяці тому +1

      Great points and I agree with your conclusion. To expand on thinking carefully; thinking specifically about what is being tested. Mocking should allow the test to be laser focused on validating that thing by abstracting the other parts that serve as dependencies for the thing to happen. I.E. When “this happens”, my code should react “this way”. I’m mocking to ensure “this happens” and leaving my test to focus on validating the reaction is “this way” as expected. This point also draws the distinction between unit tests and integration tests. A unit test’s purpose is to validate some code reacts as expected when faced with various scenarios, so I control the environment to mock the scenarios. Integration tests focus on the interaction between two components, to ensure if one has changed, you become aware how you have inadvertently broken the other so you’re prompted to fix things and probably also update unit tests. My newbie understanding, anyway.

    • @alvaroe2704
      @alvaroe2704 Місяць тому +1

      ​@@leaky3955 Good approach I think. From a newbie, also

  • @curtking70
    @curtking70 2 роки тому

    Thanks!

    • @ArjanCodes
      @ArjanCodes  2 роки тому

      Thanks so much Curt, glad you liked it!