Python - Testing
In Python testing, a test fixture refers to the preparation needed to run one or more tests. It includes the setup and cleanup tasks that need to be performed before and after the tests. The unittest
module provides a way to define and manage test fixtures using special methods within a test class.
Here's a detailed explanation along with an example program:
1. Import the unittest
module:
import unittest
2. Define a test class that inherits from unittest.TestCase
and includes setup and teardown methods:
def add(a, b):
return a + b
class TestAddition(unittest.TestCase):
def setUp(self):
# Setup tasks before each test method
print("Setting up test...")
def tearDown(self):
# Cleanup tasks after each test method
print("Tearing down test...")
def test_add_positive_numbers(self):
self.assertEqual(add(2, 3), 5, "Should be 5")
def test_add_negative_numbers(self):
self.assertEqual(add(-2, -3), -5, "Should be -5")
def test_add_mixed_numbers(self):
self.assertEqual(add(2, -3), -1, "Should be -1")
3. Run the tests using unittest.main()
:
if __name__ == '__main__':
unittest.main()
Outputs:
.Setting up test... . Tearing down test... .Setting up test... . Tearing down test... .Setting up test... . Tearing down test... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
Explanation:
- The setUp
method is called before each test method, and tearDown
is called after each test method.
- These methods can be used for tasks like initializing resources, setting up configurations, or cleaning up after a test.
- In the output, you can see that the setup and teardown tasks are executed before and after each test method.
In unittest
, you can run specific test cases by specifying the test class or method names as command-line arguments when running the test script. This allows you to selectively execute only the desired tests rather than running the entire test suite.
Here's an example along with detailed explanation:
1. Import the unittest
module:
import unittest
2. Define a test class with multiple test methods:
def add(a, b):
return a + b
class TestAddition(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(2, 3), 5, "Should be 5")
def test_add_negative_numbers(self):
self.assertEqual(add(-2, -3), -5, "Should be -5")
def test_add_mixed_numbers(self):
self.assertEqual(add(2, -3), -1, "Should be -1")
3. Run specific test cases using the command line:
# Run all tests
# python test_script.py
# Run specific test class
# python test_script.py TestAddition
# Run specific test method
# python test_script.py TestAddition.test_add_positive_numbers
Outputs:
... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Explanation:
- The example demonstrates a test class TestAddition
with three test methods.
- By running the entire test script, all tests will be executed (output not shown).
- To run specific tests, you can specify the test class or test method names as command-line arguments.
- In the output, you can see that only the specified tests were run, and the summary shows the number of tests executed and whether they passed.
In the context of unittest
, the setUp
method is a special method that is called before each test method within a test class. It is used for setting up the preconditions or any resources required for the execution of individual test methods. The setUp
method allows you to initialize variables, open connections, or perform any necessary setup steps to ensure a consistent and controlled environment for each test.
Here's an example with detailed explanation:
1. Import the unittest
module:
import unittest
2. Define a test class with a setUp
method:
def add(a, b):
return a + b
class TestAddition(unittest.TestCase):
def setUp(self):
# Setup tasks before each test method
self.num1 = 2
self.num2 = 3
def test_add_positive_numbers(self):
result = add(self.num1, self.num2)
self.assertEqual(result, 5, "Should be 5")
def test_add_negative_numbers(self):
result = add(-2, -3)
self.assertEqual(result, -5, "Should be -5")
def test_add_mixed_numbers(self):
result = add(self.num1, -3)
self.assertEqual(result, -1, "Should be -1")
3. Run the tests using unittest.main()
:
if __name__ == '__main__':
unittest.main()
Outputs:
... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Explanation:
- The setUp
method initializes the num1
and num2
variables before each test method in the class.
- Each test method can then use these initialized variables to perform tests, ensuring a consistent starting point for each test.
- In the output, you can see that the setup tasks are executed before each test method, and all tests pass successfully.
In the context of unittest
, the tearDown
method is a special method that is called after each test method within a test class. It is used for cleaning up resources, releasing acquired connections, or performing any necessary cleanup steps to ensure a controlled and consistent environment after the execution of individual test methods. The tearDown
method is particularly useful for tasks that need to be executed regardless of whether the test passes or fails.
Here's an example with detailed explanation:
1. Import the unittest
module:
import unittest
2. Define a test class with setUp
and tearDown
methods:
def add(a, b):
return a + b
class TestAddition(unittest.TestCase):
def setUp(self):
# Setup tasks before each test method
self.num1 = 2
self.num2 = 3
def tearDown(self):
# Cleanup tasks after each test method
print("Tearing down test...")
def test_add_positive_numbers(self):
result = add(self.num1, self.num2)
self.assertEqual(result, 5, "Should be 5")
def test_add_negative_numbers(self):
result = add(-2, -3)
self.assertEqual(result, -5, "Should be -5")
def test_add_mixed_numbers(self):
result = add(self.num1, -3)
self.assertEqual(result, -1, "Should be -1")
3. Run the tests using unittest.main()
:
if __name__ == '__main__':
unittest.main()
Outputs:
... Tearing down test... . Tearing down test... . Tearing down test... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
Explanation:
- The tearDown
method is called after each test method, performing cleanup tasks like printing a "Tearing down test..." message in this example.
- The cleanup tasks will be executed even if the test fails, ensuring proper cleanup regardless of the test outcome.
- In the output, you can observe that the tearDown
method is executed after each test method.