Merge lp:~elopio/u1-test-utils/log_in_from_redirect into lp:u1-test-utils
- log_in_from_redirect
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Julien Funk |
Approved revision: | 60 |
Merged at revision: | 60 |
Proposed branch: | lp:~elopio/u1-test-utils/log_in_from_redirect |
Merge into: | lp:u1-test-utils |
Diff against target: |
90 lines (+27/-10) 2 files modified
u1testutils/sso/sst/__init__.py (+4/-8) u1testutils/sso/sst/pages.py (+23/-2) |
To merge this branch: | bzr merge lp:~elopio/u1-test-utils/log_in_from_redirect |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Vincent Ladeuil (community) | Abstain | ||
Leo Arias (community) | Approve | ||
Review via email: mp+160537@code.launchpad.net |
Commit message
Updated the SSO SST helpers for pay on staging.
Description of the change
Leo Arias (elopio) wrote : | # |
<elopio> vila: about log_in_
<elopio> we decided against making unit tests for the actual page objects, as that would mean an additional place to change in case of a code change.
<vila> elopio: "an additional place to change in case of a code change" ? That's exactly why we want tests to cover code. The idea is that if you're modifying the code and introduce a regression, a test will tell you
<elopio> vila: a test will tell you, in pay.
<elopio> if you change the way pay goes from home page to log in, all the acceptance test will fail.
<vila> elopio: no, I disagree about splitting tests and code and people replied: don't worry, that's only for helpers
<vila> elopio: helpers need tests
<vila> elopio: otherwise we're adding even more test-debt
<vila> elopio: we just can't afford that
<elopio> vila: do you remember about the tests I added when we were on online-
<elopio> I'm not sure how happy you were with that decission, I suppose not much :)
<vila> elopio: no I don't, sorry :-/
<vila> I mean: I don't remember, not I'm not happy ;)
<elopio> vila: let's say you need to change some detail on the devices page. Currently, that will mean a change in the real code, a change in the unit code, and a change in the acceptance tests helper.
<elopio> if it changes the user flow, also a change in the acceptance test.
<vila> elopio: yes
<elopio> that's potentially 4 changes.
<vila> elopio: hold on a sec
<vila> elopio: the flip side is:
<elopio> if we had a test for the acceptance test helper of the devices page, that would be an additional change with not a lot of value.
<vila> if you don't have to do this 4 changes, it means your code is not tested
<vila> untested code is broken code
<vila> or said more gently:
<elopio> as the acceptance test is already excercising that code path, will fail in case of an error, and we have alternate ways to check things like doing complementary tests, i.e., the things you add should have tests for removal too.
<vila> until you have a test showing that your code is working the way you think it is, you may be wrong and bug can (and will !) occur
<elopio> vila: I agree. The 4 tests for a change that affects the user are required. The fifth change (the test for the test helper) is the one that doesn't add value.
<vila> elopio: let's talk about removing tests when we have too much of them, for now, we haven't
<vila> elopio: as a reviewer of your mp, there is no way for me to run the tests that cover the changes you're proposing
<elopio> vila: we have lots of tests. On SSO, this code is used by 100 tests.
<vila> elopio: as a reviewer of your mp.. wait I already said that
<elopio> no, we are on pay. On pay, this code is used by 49 tests.
<elopio> vila: as a reviewer, you would start on the pay branch that requires this change.
<vila> elopio: then it should be easy to add a single one in u1-test-utils right ?
<elopio> if you want, you can run the tests. That's not easy though, and will take a lot of time.
<elopio> vila: it's easy t...
Ubuntu One Auto Pilot (otto-pilot) wrote : | # |
Voting does not meet specified criteria. Required: Approve >= 1, Disapprove == 0, Needs Fixing == 0, Needs Information == 0, Resubmit == 0, Pending == 0. Got: 1 Approve, 1 Needs Information.
Vincent Ladeuil (vila) : | # |
Leo Arias (elopio) wrote : | # |
<elopio> vila, jfunk: http://
<elopio> that's a test that fails without my change, and that doesn't use the browser so doesn't need a real or faked SSO.
<elopio> probably, it would look nicer starting a patcher for all the mocks. I was just trying to do it in 20 minutes :)
<elopio> does it suffice for you?
<vila> elopio: urhg, mocks all over the place :-/ And you'll tell me that it will be tested against real code somewhere else ?
<elopio> vila: on pay. With a real browser and a real server.
<vila> that's a clear demonstration that mocked tests allows one to write complicated tests (it's really hard to read and requires an almost complete knowledge of the implementation to understand)
<elopio> that's what I told you in the meeting.
<vila> so instead of helping sharing the knowledge, it *requires* the knowledge
<elopio> the only way to avoid the fakes was to mock everything.
<vila> I probably missed when you said 'mock' then
<vila> elopio: every time someone tells me "that's the only way", I know they're wrong. In software there is never a single way to do something
<elopio> this one is cleaner: http://
<elopio> vila: if you don't mock those actions, you need a real or faked browser. Or mock the actions on sst.
<elopio> mock the actions on sst would require even a deeper knowledge of the implementation.
<vila> elopio: I think I was clear about wanting a fake...
<vila> the fake *describes* the knowledge
<vila> and the requirements for the test in this case
<vila> that's the exact opposite of what you're doing here
<elopio> just as the test_register_
<elopio> that's why I don't want to maintain another test or a fake.
<vila> elopio: looks like you don't get what I call knowledge here :-(
<vila> elopio: either your helper can be defined without links to external apps and you should be able to test it, or it can't and it needs to designed differently
<vila> s/to designed/to be designed/
<vila> that's what I was advocating during the meeting
<-> nessita is now known as nessita-teaching
<elopio> vila: maybe you can start proposing alternative designs.
<elopio> I'm currently writing the test you want.
<elopio> that will take a bit longer.
<elopio> but the problem it's not writing it. The problem is writing it for all the helpers.
<vila> elopio: the first test is the hardest to write, focus on that one, we'll see for the others later (I didn't realize they were missing :-/)
<elopio> vila: it would be just as hard everytime you have to fake a page.
<elopio> They are not hard to write, it's easy, take a look at the test_page.py
<elopio> the problem is maintaining them. With little values in my opinion, as I consider them duplicated.
<vila> elopio: I'm afraid you won't be able to get to the point where each project tests what it should if you start with the idea that you will end up with duplication
<vila> elopio: instead, try to find how to reach the point where each project only has to check what it cares about
<vila> elopio: and what matters about test failures (excluding the flaky ones) is not that you have to fix them but that they are trivial to fix w...
Leo Arias (elopio) wrote : | # |
Vila, Julien,
So, after a loooong discussion, we came up with the possible solutions.
I implemented two, so you can take a look and compare them on a better
way. Let me make a summary
1. Do nothing:
This is not the same as leaving untested code. This means that all the
code paths for the create_new_account helper in u1testutils are
exercised by the test_register_
something is wrong on the helper or if the code in pay changes, we will
notice immediately because we will be having a test failing. To fix
something in this helper means making this test pass.
Of course, I'm still in favor of this solution.
The problem is that the test is in a different project than the code.
2. Add a test without a server:
This was what you proposed at the end of the meeting. The only way (I
can find) of testing the fix without a fake or real server is mocking
the actions and just checking they were called.
http://
The test that's there will fail until we merge the fix I prepared on the
original MP.
The problem is that it's mocking almost everything, thus the value of
the test is small.
3. Add a test with a fake server:
I think this is what Vincent likes. I tried to implement it with fake
html pages:
http://
There are still some rough details as it's just a prototype, but the
idea is there.
It took me like one hour to make the test, so the reason I don't like
this solution is not because it's hard or I'm lazy.
I don't like it because if a dev wants to change the heding1 that says:
are you new?, now he has to change the original html, the page object
and the fake we have in this test.
It's even worse if he wants to change the flow or registration (as they
are doing with the new theme). Then a change would be required in the
html templates, in the tests for those templates, in the pay acceptance
test_register_
page object and in the faked page added by this test.
I would appreciated having one less change to do.
Also I don't like it because this is pretty simple to do; but we also
have helpers for the log in, for complete a payment and for changing the
payment preferences. Then we will end with many more than two faked
htmlstringpages.
4. Add a test with a real server:
The test would be copying test_register_
u1testutils. It will look a lot like the test in (3), but instead of
opening an string page, we would open either a local SSO or staging SSO.
Currently starting a local SSO takes a lot of time, so I don't like that
way.
And I liked the idea of staging SSO, I started using that for the API
helpers, but failed repeatedly as staging SSO was changed or being
updated. So now I don't like it.
=======
I think that the penalty for doing (1) it's not big, and I consider
(2-4) to be duplicating the same thing we are testing on
test_register_
small added value.
That's my opinion, I rest my case. I'm showing here I can implement any
one of the solutions, and as what I want now is just to make pay tests
to go green a...
Preview Diff
1 | === modified file 'u1testutils/sso/sst/__init__.py' |
2 | --- u1testutils/sso/sst/__init__.py 2013-04-16 06:31:16 +0000 |
3 | +++ u1testutils/sso/sst/__init__.py 2013-04-24 04:24:27 +0000 |
4 | @@ -32,15 +32,11 @@ |
5 | information will be send to it. Default is True. |
6 | |
7 | """ |
8 | - log_in = pages.LogIn() |
9 | + log_in = pages.LogInFromRedirect() |
10 | create_account = log_in.go_to_create_new_account() |
11 | create_account.create_ubuntu_sso_account(user) |
12 | |
13 | - if is_site_recognized: |
14 | - log_in.log_in_to_site_recognized(user) |
15 | - else: |
16 | - # User is already signed in so SSO will just show the site not |
17 | - # recognized page. |
18 | + if not is_site_recognized: |
19 | site_not_recognized = pages.SiteNotRecognized() |
20 | site_not_recognized.make_all_information_available_to_website() |
21 | site_not_recognized.yes_sign_me_in() |
22 | @@ -85,7 +81,7 @@ |
23 | """ |
24 | if is_site_recognized: |
25 | if user is not None: |
26 | - log_in = pages.LogIn() |
27 | + log_in = pages.LogInFromRedirect() |
28 | log_in.log_in_to_site_recognized(user) |
29 | else: |
30 | # User is already signed in so SSO will just redirect back to the |
31 | @@ -93,7 +89,7 @@ |
32 | pass |
33 | else: |
34 | if user is not None: |
35 | - log_in = pages.LogIn() |
36 | + log_in = pages.LogInFromRedirect() |
37 | site_not_recognized = log_in.log_in_to_site_not_recognized(user) |
38 | else: |
39 | # User is already signed in so SSO will just show the site not |
40 | |
41 | === modified file 'u1testutils/sso/sst/pages.py' |
42 | --- u1testutils/sso/sst/pages.py 2013-04-18 01:11:28 +0000 |
43 | +++ u1testutils/sso/sst/pages.py 2013-04-24 04:24:27 +0000 |
44 | @@ -46,7 +46,6 @@ |
45 | |
46 | """ |
47 | self._log_in(user) |
48 | - return YourAccount(user.full_name) |
49 | |
50 | @log_action(logging.info) |
51 | def log_in_to_site_not_recognized(self, user=None): |
52 | @@ -88,9 +87,25 @@ |
53 | @log_action(logging.info) |
54 | def go_to_create_new_account(self): |
55 | """Go to the Create new account page.""" |
56 | + self._click_create_new_account() |
57 | + return CreateAccount() |
58 | + |
59 | + def _click_create_new_account(self): |
60 | new_account_link = sst.actions.get_element(id='new-account-link') |
61 | sst.actions.click_link(new_account_link) |
62 | - return CreateAccount() |
63 | + |
64 | + |
65 | +class LogInFromRedirect(LogIn): |
66 | + |
67 | + url_path = '/.*/\+decide' |
68 | + is_url_path_regex = True |
69 | + headings2 = ['Log in', 'Are you new?'] |
70 | + |
71 | + @log_action(logging.info) |
72 | + def go_to_create_new_account(self): |
73 | + """Go to the Create new account page.""" |
74 | + self._click_create_new_account() |
75 | + return CreateAccountFromRedirect() |
76 | |
77 | |
78 | class PageWithAnonymousSubheader(u1testutils.sst.Page): |
79 | @@ -149,6 +164,12 @@ |
80 | sst.actions.click_button(continue_button) |
81 | |
82 | |
83 | +class CreateAccountFromRedirect(CreateAccount): |
84 | + |
85 | + url_path = '/.*/\+new_account' |
86 | + is_url_path_regex = True |
87 | + |
88 | + |
89 | class AccountCreationMailSent(PageWithAnonymousSubheader): |
90 | """AccountCreation mail sent page of the Ubuntu Single Sign On website. |
91 |
Where are the corresponding tests ?