Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a unit test for HTTPRequest #95224

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

pafuent
Copy link
Contributor

@pafuent pafuent commented Aug 7, 2024

This PR aims to help "fix" #43440
It's adding cpp_mock header only mocking library to making unit test that requires mocks easier to implement.

I just implemented some really simple HTTPRequest unit tests that makes use of cpp_mock as an example of how to use it. My plan is to use this PR as a validation of cpp_mock and my approach to mock an HTTPClient instance that will be used by HTTPRequest on future unit tests.

@pafuent pafuent requested review from a team as code owners August 7, 2024 02:50
@dalexeev dalexeev added this to the 4.4 milestone Aug 7, 2024
@AThousandShips AThousandShips changed the title Adding a unit test for HTTPRequest Add a unit test for HTTPRequest Aug 7, 2024
@Faless
Copy link
Collaborator

Faless commented Aug 7, 2024

I'm not really sure what this unit test is actually covering... seems to me it's just testing a couple of setters and getters, which is honestly not a really useful unit test....

EDIT: I also not sure why you need FakeIt to mock the HTTPClient, what is that you can't do with just extending the class?

@pafuent
Copy link
Contributor Author

pafuent commented Aug 7, 2024

I know the test is really silly and not add too much value, but as I mentioned the idea was to trigger the discussion around FakeIt and HTTPRequest constructor change. My plan is to add more useful tests after that discussion is settled.

@pafuent
Copy link
Contributor Author

pafuent commented Aug 7, 2024

Regarding extending the class to mock it, I did that in the past and it ended up being me writing more code on the mock than in actual tests. Using a mocking library not also prevent that work, it also makes more clear to understand what is happening on the test, because all the "When" and "Verify" are in the same file, and not in the mock class file.

@Faless
Copy link
Collaborator

Faless commented Aug 7, 2024

, it also makes more clear to understand what is happening on the test, because all the "When" and "Verify" are in the same file, and not in the mock class file.

Tbh, to me, the code is very cryptic, much worse than the CHECK_MESSAGE(x == y, "Message") we use in all other tests.

EDIT: See tests/core/test_crypto.h for an example where we use a mock class and all the checks are in the test cases (and not in the mock class as you mention).

I know the test is really silly and not add too much value, but as I mentioned the idea was to trigger the discussion around FakeIt and HTTPRequest constructor change.

I see, I don't think those changes are good for the reasons mentioned above.

My plan is to add more useful tests after that discussion is settled.

I think we need to have an idea of what we want to test, and I agree we don't need to add all of them in a single PR, but if the goal is validating that we can unit test those classes, the example test must be useful (showing there are things that we want unit tested there).

@pafuent pafuent force-pushed the adding_fakeit_and_ut_for_http_request branch 2 times, most recently from 9053682 to 5018086 Compare August 8, 2024 01:55
@pafuent
Copy link
Contributor Author

pafuent commented Aug 8, 2024

EDIT: See tests/core/test_crypto.h for an example where we use a mock class and all the checks are in the test cases (and not in the mock class as you mention).
I agree that for cases like the shown there it makes sense to just subclass to implement the mock. My idea is to test as much as I can from HTTPRequest and from my own experience mocking with just a subclass ends up with a lot of code written on the mock. Of course I could be wrong and maybe in order to fully test all HTTPRequest just a small mock could be needed, so I'll implement more test to validate which approach is better in this case.

Besides of that there are Good News: I was able to use the static create methods instead of changing HTTPRequest constructor

@pafuent pafuent force-pushed the adding_fakeit_and_ut_for_http_request branch from 30a6d23 to dd147fc Compare August 13, 2024 03:59
@pafuent
Copy link
Contributor Author

pafuent commented Aug 13, 2024

Well, this time I decided to change to a simpler Mocking library and I added some new tests that uses it. Of course those tests are quite simple, but it's better to start small and then chasing more complex ones.

tests/scene/test_http_request.h Outdated Show resolved Hide resolved
tests/scene/test_http_request.h Outdated Show resolved Hide resolved
tests/scene/test_http_request.h Outdated Show resolved Hide resolved
tests/scene/test_http_request.h Outdated Show resolved Hide resolved
@pafuent pafuent force-pushed the adding_fakeit_and_ut_for_http_request branch from dd147fc to 9c5515b Compare August 13, 2024 10:55
@pafuent pafuent force-pushed the adding_fakeit_and_ut_for_http_request branch 8 times, most recently from f9c347b to 3aff9f6 Compare August 13, 2024 20:28
Adding cpp_mock header only mocking library to
making unit test that requires mocks easier to
implement.
Adding some HTTPRequest unit tests that makes
use of cpp_mock to assess how useful could be to
testing Godot.
@pafuent pafuent force-pushed the adding_fakeit_and_ut_for_http_request branch from 3aff9f6 to e206173 Compare August 13, 2024 20:53
Adding a GET tests that returns HTTP Headers and a Body.
Adding a POST test that sends an HTTP Header and a Body.
@pafuent
Copy link
Contributor Author

pafuent commented Aug 15, 2024

I manged to add some more tests and get green on all checks. Can I get a new review?
As I mentioned, after I got this merge l will add more tests on a new PR.

@Faless
Copy link
Collaborator

Faless commented Aug 16, 2024 via email

@akien-mga
Copy link
Member

I'll be AFK for a couple of weeks, but my previous comment against adding another testing library still stands.
There's IMO no point in making HTTPRequest tests completely different from all other tests.
It would be nice to have a second option from another maintainer.

I haven't reviewed the changes yet, but a priori, as thirdparty code maintainer, I would also prefer not to add another thirdparty testing framework. If we can achieve the same with doctest, we should, even if it's slightly less convenient.

If it's not possible / very inconvenient to do with cpp_mock, I'm happy to reconsider, but this would need to be demonstrated.

@pafuent
Copy link
Contributor Author

pafuent commented Aug 17, 2024

Sadly doctest doesn't support mocking.
As was mentioned in other comments the other option is to subclass and implement all the mocking code by hand in a child class. As I said before, I did that in the past and the final result is one that I'm not proud of. Those mocks ended up being more complex than it should. Every time I needed to write a new test that calls the functions of those mocks in a different way, I needed to implement that on the mock. So I ended up with code intended to test my production code that was complex enough to make me think the test could fail, or even worse pass, due to errors on those mocks.
I'll try to demonstrate that a mocking library is better, but to be honest that probably will require writing all the test of HTTPRequest using both approach which sadly is doing the double of work.

@pafuent
Copy link
Contributor Author

pafuent commented Aug 20, 2024

@akien-mga or @AThousandShips Sadly I don't have a Windows machine to properly debug why my threading unit tests are failing on that platform. Do you know if there is an easy way to do it for free? Something like Godot Foundation VMs that I can just use for a limited amount of time.
If there is no other easy/free way of doing it that running the CI over an over, Can I get an approval to get my CI jobs run without anyone doing it manually? I don't want to abuse of the generosity of who is approving that every time that I submit a new commit (unless is a machine with a timer that approves the CI runs 😉)
If there is no other option I can go into the old way of debugging things: stdout (and abusing of CI runs)

Sorry, I don't have a Windows machine, so this is the only option I have.
@pafuent
Copy link
Contributor Author

pafuent commented Aug 21, 2024

I think I added enough code to provide enough context/information to take a decision on use cpp_mock or not. I'm hopping this could help everyone to get a taste on the two different options discussed in this PR.

Before leaving you to take a decision I would like to share some thoughts:

  1. The manual mock start growing over time even when it's code was not so complex. Implementing both kinds of mocks showed to me that after writing the first implementation of the one using cpp_mock I didn't needed to touch it anymore. But in the case of the manual mock, every time a new test required a new method, I needed to update the mock code before implementing the actual test.
  2. I see as an advantage having the mocking code in the same place than the unit tests code, making it easier to read existing test and understanding what is happening during debug sessions.
  3. For some people, testing is a daunting task or boring, so even a little friction makes things hard and could lead to write less unit tests or not unit test at all. Including mocking library could be beneficial for other contributors as a mean to improve the quality of Godot.
  4. This is more personal, but for me, a mocking library is quality of life. It let me focus more on the test that I'm intending to write than in the tools that I need to implement the test.

@AThousandShips AThousandShips removed the request for review from a team August 28, 2024 17:17
@pafuent
Copy link
Contributor Author

pafuent commented Sep 19, 2024

Friendly remainder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants