vila: please take a look at http://bazaar.launchpad.net/~elopio/selenium-simple-test/print_elements/revision/375 elopio: hehe, even shorter ! So you don't need the mock ones anymore right ? vila: I disagree with you there :) elopio: I'm all ears vila: this tests are nice to have, but they don't test a unit of code, they are retesting things that are already tested in selenium, they depend on firefox to run, they are slower, and the set up for the test is done on an external file (index.html), thus are not as readable as the other ones. elopio: ha, then don't write them this way vila: now I'm all ears ;) vila: the way to solve all those problems is with a unit test and mock. I agree there are some code paths not tested on the original for example, _get_text elopio: your implementation could be more testable but it would mean to not rely as much on actions.py then to be able to test it with a simple hmtl snippet elopio: didn't you implemented some helpers to get there without involving firefox ? vila: no, firefox is always needed. I tried with htmlunit, but it sucks. we could do something with phantomjs. that would make it faster than firefox, but still slower than the mocked unit test. the mocked one is faster because it does less, but you don't get a clear idea of what 'less' means by just reading the tests, you need to know the implementation to write them which is... bad vila: I wrote them before implementing them. elopio: knowing how the implementation will work as opposed to knowing only the API elopio: you test actions._element_to_string but mock element.get_attribute elopio: how do you know they are related ? knowing what the function does, not how it is implemented. it is a really low level function, so it's implementation is straight-forward. but the implementation could change, what the tests describe is what it does. When there's no id attribute, then get the text. lets say we have a way to test an html snipped without a huge delay then element = mock.Mock() element.get_attribute.return_value = None element.text = 'Test text' would be the same as element = '

Test text

' the latter is shorter and clearer, I agree. elopio: no, the later is shor.. see ? elopio: moreover, even after reading the mock tests thrice, I still don't get what they do, if I really want to understand, I need to look at the implementation elopio: and I still don't understand why there is a if in test_element_with_id.mock.get_attribute but a single call... vila: maybe I can make them clearer, for example making a function called get_element_without_id, and that creates and return the mock. elopio: you'll end up duplicating the implementation which is even worse ;) no, let me try. vila: here: http://bazaar.launchpad.net/~elopio/selenium-simple-test/print_elements/revision/376#src/sst/tests/test_actions.py once we have a beautifulsoup selenium driver, or something like that, we can change the _get_element functions to their shorter versions. but for the moment, we either test a lot more of things, like the test I added before, or use mocks. elopio: test_element_with_id is testing that actions._element_to_string is calling element.get_attribute elopio: but it doesn't test element.get_attribute vila: no. It's testing that when you call an element with an id, the id is returned. and I don't have to test get_attribute because it is tested in selenium. we chose selenium in part because it has a nice test suite, so we don't have to duplicate all the tests that are there. elopio: no it isn't "testing that when you call an element with an id, the id is returned", that's the trap, it does *because* that's what you put in the mock elopio: keep the test and change the implementation and it will still succeed elopio: not for *any* kind of change, but for some vila: for me, it would be just as doing it will succeed as long as get_attribute('id') is called. that's why the if is set on the test setup. "as long" is the key that's part of the implementation vila: it's the same. With the html string it will succeed as long as get_attribute('id) is called. elopio: but with the string you're not faking the implementation elopio: which is why I dislike mocked test without a double using the real code to cover vila: you are either testing the whole selenium+browser combination, or find a way to fake them to make them a lot faster. elopio: debugging bogus tests is way longer than any gain in running them we already have tests for selenium+browser, so it would be a waste of resources to do that again. and we don't have a full-featured test double, but we can mock parts of that easily. elopio: ECONTEXT what are those those already existing tests you're talking about ? vila: they are in our SST'´s acceptance suite, and in selenium. elopio: do they cover the change you're proposing ? vila: the change I'm proposing has nothing to do with selenium+browser combination. It only affects webelement. meh, webelement is part of selenium right ? vila: right. so it *has* to do with selenium vila: we know that webelement is properly tested. I know that whenever I call get_attribute('something'), that attribute is going to be returned. why would I have to test it again? elopio: let me return the question: why are you testing it again ? elopio: why don't you just acquire that element once and do all the tests you want on it ? vila: that's what I'm doing. I'm just faking the element acquisition, because I know it's tested, and that's not part of my change. elopio: no, you're modifying that element, that's what I'm objecting about I'm not modifying any element. On the test setup, I'm returning an element that has the id attribute set to 'Test id'. If I do it with an html string, that would be more readable. I fully agree. but the element I return would be the same, in the duck sense. let me try to formulate a question. lets say I have the quick and test double selenium driver that doesn't requires firefox. lets say I implement it using beautiful soup and a string. So I extend the selenium's get function to receive an HTML string instead of a page URL. And I implement all the get_attribute and find methods in that test double. So, on the test I would be able to change _get_element_with_id to something that opens on my test doube, and I would be able to return fake_browser.get_attribute('id') In that case, I'm not testing selenium's get_attribute. I'm using the method from the double. I just found a more readable way to set up my test. hum, that wasn't a question :) vila: would you agree with that kind of test double? <-- elopio (