-
Notifications
You must be signed in to change notification settings - Fork 82
Refactor pytest fixtures - Part 1 #969
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not an expert on those matters. But if it really speeds up testing, i am all for it;
8846507
to
7281171
Compare
Thank you @cesco-fran! It's great to have a What did I do to check tests duration? I used
$ avg_time_alt 100 pytest
real: 11.62690
user: 10.53990
sys : 1.10350
$ avg_time_alt 100 pytest
real: 12.45240
user: 11.44300
sys : 1.19660
Which increases the time by more than 8% ( 100*(0.9935 /11.6434) where 0.9935 = 12.6396 - 11.6434 ). As the tests duration is already a pain point I would start by looking for the part that costs us this increase. 🤔 |
Thanks you @sandcha for your review and feedbacks!.... I think the speed from the old code come at expense of reliability ... some objects were imported and used throughout different tests ... making the tests less predictable and so prone to bugs ... I think once we agree the new refactor the PR propose does not introduce any inconsistency/bugs ... the way are fixtures layout will allow to work on optimization ...via scope or parallelization.... I think the point is that if we want an object live the time of all test sessions we need to be explicit about that via scope ... considering the following tradeoff: more the test is isolated more would be slow (since we have to rebuild from scratch fixture) but more will be reliable... |
485cc94
to
29b848f
Compare
Hello ! I agree with both points :
My guess is that we're losing performance with the most expensive operations like the time benefit system. |
Slower tests for master:
Slower tests for refactor-pytest-fixtures:
There's a general overhead. |
Profile for master:
Profile for refactor-pytest-fixtures:
Number of function calls increased by 28% = 100 * (6185028 - 4807454) / 4807454 |
Collection is actually cheaper:
vs
|
As your stats confirm the slowness seam to come from the number of calls... that as you mention make the difference when heavy object like tbs have to rebuild more often... I think this slowness is a price to pay if we want make tests more reliable and improve on developer time vs testings time ... once the logic is clear we could start to see what improvement we can make by playing with fixture scoping... |
I think the drop in performance to be an acceptable payoff if we can move to clearer, møre independent, and atomic tests. This only impacts but core tests which are still reasonably fast IMHO. I guess we can recover this performance penalty by transforming unnecessary integration tests into unit ones ?
…________________________________
De: cesco-fran <[email protected]>
Enviado: Monday, March 8, 2021 9:13:25 AM
Para: openfisca/openfisca-core <[email protected]>
Cc: Mauko Quiroga <[email protected]>; Review requested <[email protected]>
Asunto: Re: [openfisca/openfisca-core] Refactor pytest fixtures - Part 1 (#969)
As your stats confirm the problem is in the number of calls... and as you mention this make things slower when heavy object like tbs have to rebuild more often... I think this slowness is a price to pay if we want make tests more reliable and improve on developer time vs testings time ... once the logic is clear we could start to see what improvement we can make by playing with fixture scoping...
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub<#969 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AACQMFDXZ6OE3KVC7M67F43TCSBKLANCNFSM4WJURP5Q>.
|
Yes, go to "clearer, more independent, and atomic tests" is exactly one the aim of the PR .. to cope with slowness I agree with other strategies should be consider ... to understand what are the tests that are more critical and what not as you suggested is one important one. And the less critical do not need to be deleted but just marked so that are run just in some special occasion. |
After taking a look closely, the more expensive tests are CLI's — I'm personally OK with this PR as it'll make refactoring easier IMHO. Any thought on this @sandcha ? |
While I was reviewing #984 I realize could make sense have some tbs object with different scope ... In my PR I make tbs functionally scoped so that since tbs are mutable that make more safe ... #984 make the opposite choice and make it globally scoped ... so I thought a solution could be we have different tbs each explicitly refereeing with is scope .. so that when people use it they are aware of what kind of tbs they are dealing with, and if is global that do not mess with it ... this way we should be able to improve performance while maintaining testing reliable and easy to extend and understand. |
Thanks @cesco-fran - I agree this is a safe option which is easy to understand and extend. I am happy to follow this convention in #984 too. 😄 👍 |
Sounds great @cesco-fran :) |
29b848f
to
a162adb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in comments, I think that preserving the actual scope of the Tax-Benefit System within the fixtures (general rule module scoped, exceptionally function scoped) will resolve the performance issues blocking this pull request from being merged 😃
@fixture | ||
def tax_benefit_system(): | ||
return CountryTaxBenefitSystem() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fixture | |
def tax_benefit_system(): | |
return CountryTaxBenefitSystem() | |
@fixture | |
def tax_benefit_system(scope = "module"): | |
return CountryTaxBenefitSystem() | |
@fixture | |
def isolated_tax_benefit_system(): | |
return CountryTaxBenefitSystem() |
Technical changes
Refactor the fixtures so that: