Hi Ulrich,

On 10/19/2015 03:03 AM, Ulrich Laube wrote:
> It boils down to this:
> 
> I have a selenium test in a django project against the admin page. All
> green.
> If I duplicate the test class via copy and paste + renaming, then one is
> green and one is red, despite containing the same code. I expected both
> to be green.
[snip]
> from django.contrib.auth.models import User
> from django.contrib.staticfiles.testing import StaticLiveServerTestCase
> 
> from blog.models import Post
> 
> from selenium import webdriver
> 
> class AdminTest(StaticLiveServerTestCase):
>     def login_to_django_admin(self):
>         self.credentials = {
>             'username': 'admin',
>             'email': 'admin@localhost',
>             'password': 'admin'
>         }
>         User.objects.create_superuser(**self.credentials)
>         # go to the admin site
>         self.browser.get(self.live_server_url + '/admin/')
>         # we are not logged in, it redirects us to the login page
>         self.assertEquals(self.browser.current_url, self.live_server_url
> + '/admin/login/?next=/admin/')
> 
>         # login in
>         inputbox = self.browser.find_element_by_id('id_username')
>         inputbox.send_keys('admin')
>         inputbox = self.browser.find_element_by_id('id_password')
>         inputbox.send_keys('admin')
>         submit = 'input[type="submit"]'
>         submit = self.browser.find_element_by_css_selector(submit)
>         submit.click()
>         self.browser.find_element_by_class_name('app-blog')
> 
>     def test_insert_Post_via_django_admin(self):
>         self.browser = webdriver.Firefox()
>         self.login_to_django_admin()
> 
>         # now that we are logged in, look at the Post model add page to
> get a csrftoken
>         self.browser.get(self.live_server_url + '/admin/blog/post/add/')
>         inputbox = self.browser.find_element_by_id('id_text')
>         inputbox.send_keys('barfoo')
>         submit = 'input[type="submit"][name="_save"]'
>         submit = self.browser.find_element_by_css_selector(submit)
>         submit.click()
> 
>         # we should see it on the other side via python db access
>         saved_beiträge = Post.objects.all()
>         self.assertEquals(saved_beiträge.count(), 1)
>         self.assertEquals(saved_beiträge[0].text, 'barfoo')
> 
>         # try to look at it
>         self.browser.get(self.live_server_url + '/admin/blog/post/1/')

This line is the problem. It hardcodes the ID 1 in the URL. The
database-isolation method used by Django tests does not restore ID
sequences to a fixed value, so you cannot ever rely on fixed ID values.
In your case, when you only have the one test, it always creates the
first Post in the database, with ID 1; when you copy-paste the test, the
second test creates a Post with ID 2 instead, breaking this line. You
should use the actual ID value (you query the object just above, so you
have it here) instead of hardcoding `1`.

>         # modify it
>         inputbox = self.browser.find_element_by_id('id_text')
>         inputbox.send_keys('text')
>         submit = 'input[type="submit"][name="_save"]'
>         submit = self.browser.find_element_by_css_selector(submit)
>         submit.click()
> 
>         # we should see the change at the other end
>         saved_posts = Post.objects.all()
>         self.assertEquals(saved_posts.count(), 1)
>         self.assertEquals(saved_posts[0].text, 'barfootext')
> 
> Now run it via:
> 
>> manage test
> 
> Selenium opens Firefox and walks through the admin page as it should.
> Test green.
> Now duplicate the whole class and rename it and run the tests again.
> 
>> manage test
> 
> One is green the other is not. In fact Selenium opens a second Firefox
> instance as it should. But this time
> 
>  self.browser.get(self.live_server_url + '/admin/blog/post/1/')
> 
> results in a 404 not found.

Right, because in this test there is no Post with ID 1, just one with ID 2.

> Now delete the whole class that is passing and run the test again.
> 
>> manage test
> 
> Now the failing one is green as well.

Yes, because now you're back down to just one test, so it is again
creating a Post with ID 1.

> I can't wrap my head around this. What am I missing?
> Is it a Django issue or a Selenium issue?
> Is it a known problem?

Not really a problem - you just need to be aware that you can't rely on
consistent database IDs in tests.

Carl

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/5626BDA7.2050803%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to