Testing Tool - zamaniamin/python GitHub Wiki

Package parameterized

Based on your code, one package that can help reduce the code in your test scenarios is parameterized (also known as @parameterized.expand). It allows you to define test cases using parameterization, which can help eliminate repetitive code and generate multiple scenarios from a single test method.

Here's an example of how you can use parameterized to reduce code duplication in your test cases:

from django.contrib.auth import get_user_model
from rest_framework.test import APITestCase
from rest_framework import status
from .serializers import SignupSerializer
from parameterized import parameterized


class SigninViewTestCase(APITestCase):
    email = '[email protected]'
    password = 'testPassword'
    signin_url = '/users/signin/'

    @classmethod
    def setUpTestData(cls):
        # Create a new user with valid credentials.
        cls.user = get_user_model().objects.create_user(
            email=cls.email,
            password=cls.password
        )

    @parameterized.expand([
        # Valid credentials
        ('valid_credentials', {'email': email, 'password': password}, status.HTTP_200_OK, {'token'}),

        # Invalid credentials
        ('blank_email_and_password', {'email': '', 'password': ''}, status.HTTP_400_BAD_REQUEST, {'email': ['This field may not be blank.'], 'password': ['This field may not be blank.']}),
        ('invalid_email_and_blank_password', {'email': 'test', 'password': ''}, status.HTTP_400_BAD_REQUEST, {'email': ['Enter a valid email address.'], 'password': ['This field may not be blank.']}),
        ('blank_email_and_invalid_password', {'email': '', 'password': 'test'}, status.HTTP_400_BAD_REQUEST, {'email': ['This field may not be blank.']}),
        ('invalid_email_and_invalid_password', {'email': 'user', 'password': 'test'}, status.HTTP_400_BAD_REQUEST, {'email': ['Enter a valid email address.']}),
        ('valid_email_and_password_user_not_exist', {'email': '[email protected]', 'password': 'user'}, status.HTTP_400_BAD_REQUEST, {'non_field_errors': ['Unable to log in with provided credentials.']}),
    ])
    def test_signin(self, _, data, expected_status, expected_data):
        """
        Test sign in with different scenarios.
        """
        response = self.client.post(self.signin_url, data)
        self.assertEqual(response.status_code, expected_status)
        self.assertEqual(response.data, expected_data)

    @parameterized.expand([
        # Missing email and password
        ('missing_email', {'email': '[email protected]'}, status.HTTP_400_BAD_REQUEST, {'password': ['This field is required.']}),
        ('empty_data', {}, status.HTTP_400_BAD_REQUEST, {'email': ['This field is required.'], 'password': ['This field is required.']}),
        ('blank_email_and_none_password', {'email': ''}, status.HTTP_400_BAD_REQUEST, {'email': ['This field may not be blank.'], 'password': ['This field is required.']}),
        ('none_email_and_blank_password', {'password': ''}, status.HTTP_400_BAD_REQUEST, {'email': ['This field is required.'], 'password': ['This field may not be blank.']}),
        ('invalid_email_and_none_password', {'email': 'test'}, status.HTTP_400_BAD_REQUEST, {'email': ['Enter a valid email address.'], 'password': ['This field is required.']}),
        ('none_email_and_invalid_password', {'password': 'test'}, status.HTTP_400_BAD_REQUEST, {'email': ['This field is required.']}),
    ])
    def test_signin_with_missing_fields

(self, _, data, expected_status, expected_data):
        """
        Test sign in with missing fields.
        """
        response = self.client.post(self.signin_url, data)
        self.assertEqual(response.status_code, expected_status)
        self.assertEqual(response.data, expected_data)

In the above example, the @parameterized.expand decorator is used to define multiple test cases with different inputs and expected outputs. The test method test_signin is called for each scenario defined in the parameterized decorator, reducing the code duplication and making it easier to manage and update the test cases.

You can install the parameterized package using pip:

pip install parameterized

Note: Make sure to adjust the import statements in your code accordingly.