Implementing Table-Driven Tests in Go
Testing is a crucial part of software development, and Go provides excellent tools for it. Table-driven tests are a powerful and idiomatic pattern in Go for testing multiple scenarios of a function efficiently and readably. This challenge will guide you in implementing this pattern.
Problem Description
You are tasked with writing unit tests for a simple CalculateDiscount function in Go. This function takes a price (float64) and a customerType (string) and returns the calculated discount amount (float64).
Your goal is to implement a comprehensive set of tests for this function using the table-driven testing approach. This involves defining a slice of structs, where each struct represents a test case with its input values and expected output. You will then iterate over this slice, running each test case within a subtest.
Requirements:
- Create a
CalculateDiscountfunction that takesprice(float64) andcustomerType(string) and returnsfloat64. - Implement the following discount logic:
- If
customerTypeis "premium", the discount is 10% of the price. - If
customerTypeis "standard", the discount is 5% of the price. - For any other
customerType, there is no discount (0.0).
- If
- Write unit tests for the
CalculateDiscountfunction using the table-driven testing pattern. - Each test case should include:
- A descriptive name for the test case.
- The input
price. - The input
customerType. - The expected discount
float64.
- Use
t.Run()to create subtests for each test case, making it easy to identify which specific scenario failed. - Handle floating-point comparisons carefully, considering potential precision issues.
Examples
Example 1: Premium Customer
Input:
price: 100.0
customerType: "premium"
Output:
10.0
Explanation: A premium customer gets a 10% discount. 10% of 100.0 is 10.0.
Example 2: Standard Customer
Input:
price: 50.0
customerType: "standard"
Output:
2.5
Explanation: A standard customer gets a 5% discount. 5% of 50.0 is 2.5.
Example 3: Unknown Customer Type
Input:
price: 200.0
customerType: "guest"
Output:
0.0
Explanation: An unknown customer type receives no discount.
Example 4: Zero Price
Input:
price: 0.0
customerType: "premium"
Output:
0.0
Explanation: Even for a premium customer, a price of 0.0 results in a 0.0 discount.
Constraints
- The
pricewill be a non-negative float64. - The
customerTypewill be a string. - The discount percentages are fixed (10% for premium, 5% for standard).
- Tests should cover various price points, including zero, and different customer types (including valid and invalid ones).
Notes
- When comparing floating-point numbers for equality in tests, it's generally best to check if the difference between the actual and expected values is within a small tolerance (epsilon) rather than using direct equality (
==). This accounts for potential minor precision differences. - Think about how to structure your test cases for maximum clarity and maintainability.
- The
testingpackage in Go is your primary tool here. Familiarize yourself witht.Run().