3

I'm building an authentication system for a website, I don't have prior test experience with Django. I have written some basic tests.

the model,

class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=25, unique=True, error_messages={
        'unique': 'The username is taken'
    })
    first_name = models.CharField(max_length=60, blank=True, null=True)
    last_name = models.CharField(max_length=60, blank=True, null=True)
    email = models.EmailField(unique=True, db_index=True, error_messages={
        'unique': 'This email id is already registered!'
    })

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    date_joined = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username',]


    objects = UserManager()

    def get_full_name(self):
        return ' '.join([self.first_name, self.last_name])

    def get_short_name(self):
        return self.email

    def __unicode__(self):
        return self.username

and model manager,

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **kwargs):
        if not email:
            raise ValueError('Enter Email address')

        if not kwargs.get('username'):
            raise ValueError('Enter Username')

        account = self.model(
            email=self.normalize_email(email), username=kwargs.get('username')
        )

        account.set_password(password)
        account.save()

        return account

    def create_superuser(self, email, password, **kwargs):
        account = self.create_user(email, password, **kwargs)

        account.is_superuser = True
        account.save()

        return account

and my tests,

class SettingsTest(TestCase):    
    def test_account_is_configured(self):
        self.assertTrue('accounts' in INSTALLED_APPS)
        self.assertTrue('accounts.User' == AUTH_USER_MODEL)


class UserTest(TestCase):
    def setUp(self):
        self.username = "testuser"
        self.email = "[email protected]"
        self.first_name = "Test"
        self.last_name = "User"
        self.password = "z"

        self.test_user = User.objects.create_user(
            username=self.username,
            email=self.email,
            first_name=self.first_name,
            last_name=self.last_name
        )


    def tearDown(self):
        del self.username
        del self.email
        del self.first_name
        del self.last_name
        del self.password

    def test_create_user(self):
        self.assertIsInstance(self.test_user, User)

    def test_default_user_is_active(self):
        self.assertTrue(self.test_user.is_active)

    def test_default_user_is_staff(self):
        self.assertFalse(self.test_user.is_staff)

    def test_default_user_is_superuser(self):
        self.assertFalse(self.test_user.is_superuser)

    def test_get_full_name(self):
        self.assertEqual('Test User', self.test_user.get_full_name())

    def test_get_short_name(self):
        self.assertEqual(self.email, self.test_user.get_short_name())

    def test_unicode(self):
        self.assertEqual(self.username, self.test_user.__unicode__())

fortunately all the passes, and my question is, are these tests overdone or underdone or normal? What should be tested in a model? is there any procedure missing? anything wrong with this tests?? how do I effectively write tests??

thank you for any insights.

3
  • In tearDown(self) probably do self.test_user.delete(), because if you'd run the test with --keepdb flag, it would try to create the user again with the same email and fail. Commented Feb 19, 2016 at 22:51
  • Definitely not the end-game, but it's usually worth using coverage to try and get 100% statements hit in your tests. It's usually not too difficult in relatively small Django projects to do. I find it's less about finding any bugs hiding on hidden lines, but more about inspiration for new test cases. coverage.readthedocs.org/en/coverage-4.0.3 Commented Feb 20, 2016 at 6:57
  • I'm just going to link to this SO answer, as it appears the tests code is the same as here. It is public domain, but worth crediting stackoverflow.com/a/36567915/943773 Commented Oct 10, 2018 at 12:11

1 Answer 1

5

That's quite enough. Just a couple of notes:

  1. No need to delete properties in tearDown
  2. You forgot to tests UserManager in lines raise ValueError using assertRaises.
  3. You may also test that user created by create_user(from UserManager) can authenticate(from django.contrib.auth) by given password and email.
  4. Use coverage package to detect which lines/classes/packages/statements were missed to test.
Sign up to request clarification or add additional context in comments.

Comments

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.