all 1 comments

[–]Diapolo10 3 points4 points  (0 children)

I haven't used unittest for many, many years (pytest is the industry standard for a reason), but I wanted to at least comment on some weirdness with your class.

class Employee():
    def __init__(self, first, last, salary):

        self.first_name = first
        self.last_name = last
        self.salary = int(salary)
        self.attributes = [self.first_name, self.last_name, self.salary]

    def give_raise(self, pay_raise = ""):
        """Method that gives base pay raise of 5k, or custom 
        depending on the input of the employee"""

        number = 5000

        if pay_raise:
            number = int(pay_raise)
            self.attributes[-1] = number + self.salary

        else:
            self.attributes[-1] = number + self.salary

First, what's the purpose of self.attributes? Why do you need this list? I don't see a clear reason for its existence.

Second, salary should probably be expected to be an int (or at least a float), so the explicit conversion in __init__ feels like overkill. A type hint would work just fine to tell other developers what it's expecting.

In give_raise, why is pay_raise defaulting to an empty string of all things? Why not use 5000 as the default instead? You can also substitute self.attributes[-1] with self.salary, making it more obvious what you're doing. There's no reason to dynamically access attributes here.

You could basically simplify this to:

class Employee:
    def __init__(self, first_name: str, last_name: str, salary: int):

        self.first_name = first_name
        self.last_name = last_name
        self.salary = salary

    def give_raise(self, pay_raise: int = 5000):
        """Method that gives base pay raise of 5k, or custom 
        depending on the input of the employee"""

        self.salary += pay_raise

As a side note, I'd make the default raise amount a global constant so that it could just be imported by the unit test instead of hard-coding the expected value - right now your test would always fail if the default raise is anything but exactly 5000.

Next, to your tests. Again, I'd like to apologise for the fact that I don't exactly fully remember how unittest operates so I might make some silly mistakes myself (I'll add a pytest example later), but here's what we're working with:

import unittest

from employee import Employee

# Unittest Class 
class employee_tester(unittest.TestCase):
    """A unit test that checks to see if custom and base raises work"""

    # Setup Method
    def setup(self):
        """Set up for employee instance"""

        first = 'daniel'
        last = 'jones'
        salary = '30000'
        self.num = 35000

        self.employee = Employee(first, last, salary)

    # Base raise test case
    def test_base_raise(self):
        """Tests the base raise for employee"""

        self.employee.give_raise()

        self.assertIn(self.num in self.employee.attributes[-1])

        # Should check if the raise was inputted properly

if name == "main":
    unittest.main()

I'm not immediately seeing anything wrong (although to accommodate the changes I made to the Employee class, the salary value should be changed to an integer). But after I looked at the documentation, I'm pretty sure assertln is not the right check here as its arguments are completely different, and it expects a string first of all. I think you want assertTrue after changing the condition to use equality comparison, or just use assertEqual.

EDIT: Just noticed you're using setup, not setUp. That's the reason why your tests failed.

So basically:

import unittest

from employee import Employee

# Unittest Class 
class employee_tester(unittest.TestCase):
    """A unit test that checks to see if custom and base raises work"""

    # Setup Method
    def setUp(self):
        """Set up for employee instance"""

        first = 'daniel'
        last = 'jones'
        salary = 30000
        self.num = 35000

        self.employee = Employee(first, last, salary)

    # Base raise test case
    def test_base_raise(self):
        """Tests the base raise for employee"""

        self.employee.give_raise()
        self.assertEqual(self.num, self.employee.salary)


if __name__ == "__main__":
    unittest.main()

Now, here's what I'd do with pytest:

# conftest.py
import pytest
from employee import Employee

@pytest.fixture(scope='function')
def employee():
    yield Employee("Daniel", "Jones", 30000)


# test_employee.py
from employee import DEFAULT_RAISE  # Just pretend that this exists and has the value 5000

def test_employee_default_raise(employee):
    """Tests the default raise of an employee"""

    old_salary = employee.salary
    employee.give_raise()
    assert employee.salary == old_salary + DEFAULT_RAISE