0

I am writing test cases for a project, and want to test my login functionality. I am using LiveServerTestCase class, selenium and following this documentation in Django website [link] (https://docs.djangoproject.com/en/1.8/topics/testing/tools/). If you see the code below :

from django.test import LiveServerTestCase
from selenium.webdriver.firefox.webdriver import WebDriver

class MySeleniumTests(LiveServerTestCase):
    fixtures = ['user-data.json']

    @classmethod
    def setUpClass(cls):
        super(MySeleniumTests, cls).setUpClass()
        cls.selenium = WebDriver()

    @classmethod
    def tearDownClass(cls):
        cls.selenium.quit()
        super(MySeleniumTests, cls).tearDownClass()

    def test_login(self):
        self.selenium.get('%s%s' % (self.live_server_url, '/login/'))
        username_input = self.selenium.find_element_by_name("username")
        username_input.send_keys('rakesh')
        password_input = self.selenium.find_element_by_name("password")
        password_input.send_keys('ranjan')
        self.selenium.find_element_by_xpath('//input[@value="Log in"]').click()

My username is rakesh and password is ranjan, and I am wondering why the following code fails here? I am sending my parameters correctly, but still it is not accepting.

Since on every test case a new database is created, is there a way to create new user and password in the above code as well? I am particularly new to writing test cases and will appreciate any help.

Error: loaddata.py:225: UserWarning: No fixture named 'user-data' found.
  warnings.warn("No fixture named '%s' found." % fixture_name)

I am also not able to understand what do you mean by fixtures = ['user-data.json']

2 Answers 2

1

I strongly advise you to use a factory instead of a JSON fixture. It's a lot more readable and easy to maintain.

In the example you've sent, I wonder if the password is correctly encrypted or not.

Example:

factories.py:

from django.contrib.auth.hashers import make_password
from factory import DjangoModelFactory, Sequence


class UserFactory(DjangoModelFactory):
    class Meta:
        model = User

    # this is just an example; you need the required fields on your actual User Model
    email = Sequence(lambda n: 'john-doe-{0}@a.com'.format(n))
    username = Sequence(lambda n: 'john_doe_{0}'.format(n))
    password = make_password("password")

in your test:

def test_login(self):
    rakesh = UserFactory.create(
        username="rakesh", 
        password=make_password("ranjan")
    )
    self.selenium.get('%s%s' % (self.live_server_url, '/login/'))
    ...

Obviously, if the following still won't pass:

    body = self.selenium.find_element_by_tag_name('body')
    self.assertIn(u'Welcome rakesh, you have successfully logged in.', body.text)

make sure to print body to find out what the error is.

Sign up to request clarification or add additional context in comments.

7 Comments

Any idea where I am going wrong in this code: just check login_user function link
What? What's the error? That sample is not taking my answer into account !
I am just wondering why the login_user function not working in my code. Both username and password are correct. I should be redirected to a different page but that's not happening.
print body please :)
Hey I am trying to implement your method and I am getting import error from factory import DjangoModelFactory, Sequence
|
1

Fixture is initial dataset for specific model. Your test case will create test database, tables, and inserts data according to fixture file.

You can create fixture by hand or export using dumpdata management command. Since passwords are hashed, its easier to create user within your app, then export table data as fixture:

$ python manage.py dumpdata auth.User --indent 4 > user-data.json

user-data.json will contain something like this:

# app_name/fixtures/user-data.json
[
{
  "fields": {
    "username": "rakesh",
    "password": "pbkdf2_sha256$15000$sDvLgitB2ieq$tGnZ4Vw+BVOnluucn0GyLzi1tV1dZEg=",
  },
  "model": "auth.user",
  "pk": 1
}
]

To test your login process with selenium check, if body.text after submitting login form contains specific text:

def test_login(self):
    self.selenium.get('%s%s' % (self.live_server_url, '/login/'))
    username_input = self.selenium.find_element_by_name("username")
    username_input.send_keys('rakesh')
    password_input = self.selenium.find_element_by_name("password")
    password_input.send_keys('ranjan')
    #self.selenium.find_element_by_xpath('//input[@value="Log in"]').click()
    # or submit with return key
    from selenium.webdriver.common.keys import Keys
    password_input.send_keys(Keys.RETURN)

    body = self.selenium.find_element_by_tag_name('body')
    self.assertIn(u'Welcome rakesh, you have successfully logged in.', body.text)

5 Comments

How do you test whether the user data is valid or not ? If it is not validated raise an error
Fixture contains initial data for your test case. But your question is about test case, let me update my answer.
I have added fixtures now, my username and password is correct but still it is not showing anything. You can view my code here <gist.github.com/rakeshsukla53/4f3abceac47c5ca7ca41>, any pointers where I might be wrong
How can I check response I will get from password_field.send_keys(Keys.RETURN). I mean when you hit enter, either you will redirected or status code will be 403 right? Unfortunately response of password_field.send_keys(Keys.RETURN) is None :/
I am not sure if you can get response status code form selenium's webdriver. Selenium acts as headless web browser. send_keys(Keys.RETURN) will submit form. body = self.selenium.find_element_by_tag_name('body') right after submiting will get you a new body content. Log body.text to see if it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.