Welcome to the WeChat public number "Python Kitchen, learn new Python knowledge with me every day", and add blogger Vx:yf03064131 for easy communication and learning.
Or station B searches for a new one
Original video address link: click here
Code address: click here
This is a general translation and operational practice.
Test-Driven Development Concepts
Test-driven development, also known as red-green refactoring, or Test-Driven Development, or TDD, is a new development method that is different from the traditional software development process. It requires that you write test code before you write code for a function, then write only the function code that makes the test pass, and then use the test to drive the whole development process.
Five steps for test-driven development
- step1
Write tests, and before you write functional code, start by writing tests that pass only when the functional specifications are met - step2
Run the test and make sure it fails, which means your test is valid (expected to be fail) - step3
Write the simplest code so that tests can pass, but don't have to be perfect at this step - step4
Ensure that all tests pass, including older ones, that the new functionality meets the specifications, and that nothing else is damaged - step5
Refactoring and improving code
Code Instance Explanation
Let's follow these five steps and explain them one by one
step1: To achieve a function of paying employees'wages, first do not implement this function, write out the general structure:
For the usage of dataclass, see my article: Daily Python Tips - dataclass
""" Very advanced Employee management system. """ from dataclasses import dataclass @dataclass class Employee: """Basic representation of an employee.""" name: str employee_id: int pay_rate: float = 100.0 hours_worked: float = 0.0 employer_cost: float = 1000.0 has_commission: bool = True commission: float = 100.0 contracts_landed: int = 0 def compute_payout(self) -> float: """Compute how much the employee should be paid.""" raise NotImplementedError()
step2: Write tests and run them, all of which should fail because the functionality is not implemented:
""" Employee class tests. """ import unittest from employee import Employee NAME: str = "Arjan" EMPLOYEE_ID: int = 12345 class TestEmployeeComputePayout(unittest.TestCase): """Test the compute_payout method of the Employee class.""" def setUp(self): """Set up test fixtures.""" self.arjan = Employee(name=NAME, employee_id=EMPLOYEE_ID) def test_employee_payout_returns_a_float(self): """Whether payout returns a float.""" self.assertIsInstance(self.arjan.compute_payout(), float) def test_employee_payout_no_commission_no_hours(self): """Whether payout is correctly computed in case of no commission and no hours worked.""" self.assertAlmostEqual(self.arjan.compute_payout(), 1000.0) def test_employee_payout_no_commission(self): """Whether payout is correctly computed in case of no commission and 10 hours worked.""" self.arjan.hours_worked = 10.0 self.assertAlmostEqual(self.arjan.compute_payout(), 2000.0) def test_employee_payout_with_commission(self): """ Whether payout is correctly computed in case of 10 contracts landed and 10 hours worked. """ self.arjan.hours_worked = 10.0 self.arjan.contracts_landed = 10 self.assertAlmostEqual(self.arjan.compute_payout(), 3000.0) def test_employee_payout_commission_disabled(self): """ Whether payout is correctly computed in case of 10 contracts landed and 10 hours worked, but commission is disabled. """ self.arjan.hours_worked = 10.0 self.arjan.contracts_landed = 10 self.arjan.has_commission = False self.assertAlmostEqual(self.arjan.compute_payout(), 2000.0) if __name__ == "__main__": unittest.main()
step3: to achieve the most basic functions, some case s can pass the test:
""" Very advanced Employee management system. """ from dataclasses import dataclass @dataclass class Employee: """Basic representation of an employee.""" name: str employee_id: int pay_rate: float = 100.0 hours_worked: float = 0.0 employer_cost: float = 1000.0 has_commission: bool = True commission: float = 100.0 contracts_landed: int = 0 def compute_payout(self) -> float: # pass 1 fail 4 """Compute how much the employee should be paid.""" payout = self.pay_rate * self.hours_worked return payout
step4: gradually improve:
def compute_payout(self) -> float: # pass 4 fail 1 """Compute how much the employee should be paid.""" payout = self.pay_rate * self.hours_worked return payout def compute_payout(self) -> float: # pass 5 fail 0 """Compute how much the employee should be paid.""" payout = self.pay_rate * self.hours_worked return payout
step5: refactoring the code, at this time I change some conditions, modify the corresponding calculation formula, then all test case s can be directly reused, efficient and accurate:
Note the difference: the employer_cost cost has been changed to three more detailed items, but the test result is still pass
""" Very advanced Employee management system. """ from dataclasses import dataclass @dataclass class Employee: """Basic representation of an employee.""" name: str employee_id: int pay_rate: float = 100.0 hours_worked: float = 0.0 # employer_cost: float = 1000.0 employer_office_costs: float = 200.0 employer_401k_costs: float = 400.0 employer_suppoer_costs: float = 400.0 has_commission: bool = True commission: float = 100.0 contracts_landed: int = 0 def compute_payout(self) -> float: """Compute how much the employee should be paid.""" employer_cost = self.employer_office_costs + self.employer_401k_costs + self.employer_suppoer_costs payout = self.pay_rate * self.hours_worked + employer_cost if self.has_commission: payout += self.commission * self.contracts_landed return payout