dimanche 4 août 2019

How to write correct test with pytest?

I can write some unittests but have no idea how to write test about createAccount() which connect other functions together.

createAccount() contains some steps in order:

  1. Handle Email

  2. Handle Password

  3. Handle Security Keyword

  4. Instantiate new account object

Every step has some test cases. So, my questions are: 1. How to write createAccount() test case ? Should I list all possible combination test cases then test them.

For example:

TestCase0. Email is invalid

TestCase1. App stops after retrying email 3 times

TestCase2. Email is ok, password is not valid

TestCase3. Email is ok, password is valid, 2nd password doesnt match the first one

TestCase4. Email is ok, password is valid, both password match, security is valid

TestCase5. Email is ok, password is vailid, both password match, security is valid, account was create succesfully

  1. Don't I know how to test because my createAccount() sucks ? If yes, how to refactor it for easier testing ?

This is my code:

class RegisterUI:

    def getEmail(self):
        return input("Please type an your email:")

    def getPassword1(self):
        return input("Please type a password:")

    def getPassword2(self):
        return input("Please confirm your password:")

    def getSecKey(self):
        return input("Please type your security keyword:")

    def printMessage(self,message):
        print(message)


class RegisterController:
    def __init__(self, view):
        self.view = view


    def displaymessage(self, message):
        self.view.printMessage(message)

    def ValidateEmail(self, email):
        """get email from user, check email
        """
        self.email = email
        email_obj = Email(self.email)
        status = email_obj.isValidEmail() and not accounts.isDuplicate(self.email)
        if not status:
            raise EmailNotOK("Email is duplicate or incorrect format")
        else:
            return True


    def ValidatePassword(self, password):
        """
        get password from user, check pass valid
        """
        self.password = password
        status = Password.isValidPassword(self.password)
        if not status:
            raise PassNotValid("Pass isn't valid")
        else: return True

    def CheckPasswordMatch(self, password):
        """
        get password 2 from user, check pass match
        """
        password_2 = password
        status = Password.isMatch(self.password, password_2)
        if not status:
            raise PassNotMatch("Pass doesn't match")
        else: return True

    def createAccount(self):
        retry = 0
        while 1:
            try:
                email_input = self.view.getEmail()
                self.ValidateEmail(email_input) #
                break
            except EmailNotOK as e:
                retry = retry + 1
                self.displaymessage(str(e))
                if retry > 3:
                    return

        while 1:
            try:
                password1_input = self.view.getPassword1()
                self.ValidatePassword(password1_input)
                break
            except PassNotValid as e:
                self.displaymessage(str(e))

        while 1:
            try:
                password2_input = self.view.getPassword2()
                self.CheckPasswordMatch(password2_input)
                break
            except PassNotMatch as e:
                self.displaymessage(str(e))

        self.seckey = self.view.getSecKey()
        account = Account(Email(self.email), Password(self.password), self.seckey)
        message = "Account was create successfully"
        self.displaymessage(message)
        return account

class Register(Option):
    def execute(self):

        view = RegisterUI()
        controller_one = RegisterController(view)
        controller_one.createAccount()




"""========================Code End=============================="""

"""Testing"""
@pytest.fixture(scope="session")
def ctrl():
    view = RegisterUI()
    return RegisterController(view)

def test_canThrowErrorEmailNotValid(ctrl):
    email = 'dddddd'
    with pytest.raises(EmailNotOK) as e:
        ctrl.ValidateEmail(email)
    assert str(e.value) == 'Email is duplicate or incorrect format'

def test_EmailIsValid(ctrl):
    email = 'hello@gmail.com'
    assert ctrl.ValidateEmail(email) == True

def test_canThrowErrorPassNotValid(ctrl):
    password = '123'
    with pytest.raises(PassNotValid) as e:
        ctrl.ValidatePassword(password)
    assert str(e.value) == "Pass isn't valid"

def test_PasswordValid(ctrl):
    password = '1234567'
    assert ctrl.ValidatePassword(password) == True

def test_canThrowErrorPassNotMatch(ctrl):
    password1=  '1234567'
    ctrl.password = password1
    password2 = 'abcdf'
    with pytest.raises(PassNotMatch) as e:
        ctrl.CheckPasswordMatch(password2)
    assert str(e.value) == "Pass doesn't match"

def test_PasswordMatch(ctrl):
    password1=  '1234567'
    ctrl.password = password1
    password2 = '1234567'
    assert ctrl.CheckPasswordMatch(password2)

Aucun commentaire:

Enregistrer un commentaire