1

Ok I'm writing tests for my Django app. I'm trying to figure out a way to iterate over the testing for a ajax register call for the appropriate responses. It's working but I know it can be done in a more efficient way.

def test_ajax_register(self):
    c = Client()
    # Check register success
    response = c.post('/register/', {
        'register-username': 'testuser',
        'register-email': 'testuser@email.com',
        'register-password': 'password'
    })
    self.assertEqual(json.loads(response.content)['status'], 'success')
    self.assertEqual(response.status_code, 200)

    # Check register failed  username taken
    response = c.post('/register/', {
        'register-username': 'testuser',
        'register-email': 'testuser@email.com',
        'register-password': 'password'
    })
    self.assertEqual(json.loads(response.content)['status'], 'fail')
    self.assertEqual(json.loads(response.content)['error_msg'], 'username already in use')

    # Check register failed email in use
    response = c.post('/register/', {
        'register-username': 'testuser1',
        'register-email': 'testuser@email.com',
        'register-password': 'password'
    })
    self.assertEqual(json.loads(response.content)['status'], 'fail')
    self.assertEqual(json.loads(response.content)['error_msg'], 'email already in use')

    # Check register failed  password length
    response = c.post('/register/', {
        'register-username': 'testuser2',
        'register-email': 'testuser2@email.com',
        'register-password': 'pass'
    })
    self.assertEqual(json.loads(response.content)['status'], 'fail')
    self.assertEqual(json.loads(response.content)['error_msg'], 'password must be atleast 8 characters long')
doughboy
  • 61
  • 7

2 Answers2

0

Just separate your tests into separate methods. Each of them will be triggered as long as they have prefix test_, and each test can also run as a stand alone test. Use setUp and tearDown methods, if need to preset anything.

def test_ajax_register(self):
    # Test registration 
    c = Client()
    # Check register success
    response = c.post('/register/', {
        'register-username': 'testuser',
        'register-email': 'testuser@email.com',
        'register-password': 'password'
    })
    self.assertEqual(json.loads(response.content)['status'], 'success')
    self.assertEqual(response.status_code, 200)


def test_failed_registration(self):
    # Check register failed  username taken
    response = c.post('/register/', {
        'register-username': 'testuser',
        'register-email': 'testuser@email.com',
        'register-password': 'password'
    })
    self.assertEqual(json.loads(response.content)['status'], 'fail')
    self.assertEqual(json.loads(response.content)['error_msg'], 'username already in use')


def test_email_in_use(self):
    # Check register failed email in use
    response = c.post('/register/', {
        'register-username': 'testuser1',
        'register-email': 'testuser@email.com',
        'register-password': 'password'
    })
    self.assertEqual(json.loads(response.content)['status'], 'fail')
    self.assertEqual(json.loads(response.content)['error_msg'], 'email already in use')


def test_password_length(self):
    # Check register failed  password length
    response = c.post('/register/', {
        'register-username': 'testuser2',
        'register-email': 'testuser2@email.com',
        'register-password': 'pass'
    })
    self.assertEqual(json.loads(response.content)['status'], 'fail')
    self.assertEqual(json.loads(response.content)['error_msg'], 'password must be atleast 8 characters long')
dmitryro
  • 3,463
  • 2
  • 20
  • 28
  • ok thanks that's what i was thinking but wasn't sure if would be to iterate over the testing responses – doughboy Dec 16 '17 at 17:10
0

In general, you should split the big test logically and follow the UnitOfWork_StateUnderTest_ExpectedBehavior test method naming practice.

The concept of data-driven tests is also a relevant idea, I've personally used ddt package in the past and then switched to pytest parameterized tests - that is a great way to test the same specific "symptom" of a function under test using different input data - this would help to prevent code duplication (DRY principle) and make your tests more organized and readable.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195