This document compares Python's unittest and Nose test runners, showing how to run tests, interpret reports, and use coverage tools for better code quality.
This document explains how to run Python unit tests using both unittest and Nose, highlights the differences in their reports, and demonstrates how Nose can improve test output and code coverage analysis.
Automated testing is essential for reliable software. Python offers several tools for running unit tests, including the built-in unittest module and the third-party Nose framework. This module explores how to use both tools and interpret their test reports.
11-tdd-bdd is set up with a dedicated folder for Python tests. It is present in the content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab directory.python -m venv venv. It creates a directory named .venv with necessary packagessource venv/bin/activate.node environment is kept separate. The source is a linux command to run a script in the current shell session, allowing you to use the virtual environment’s Python interpreter and installed packages.conda-bash which is an alias to run a profile to isolate the environment. 1~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
2ag-sayyed@p-3660 [Node: v24.4.0] [Git: feat/tdd-bdd]
3$ echo $SHELL
4/bin/bash
5
6~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
7ag-sayyed@p-3660 [Node: v24.4.0] [Git: feat/tdd-bdd]
8$ which python
9# No answer means python is not installed in the current shell
10# So we need to run the profile to activate the virtual environment
11~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
12ag-sayyed@p-3660 [Node: v24.4.0] [Git: feat/tdd-bdd]
13$ conda-bash
14Initializing conda, If this shell session is exited, Conda will no longer be available unless re-initialized. No need to deactivate conda manually.
15[Git: feat/tdd-bdd] [Python: 3.13.2] (base) ) ag-sayyed@p-3660:~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
16$ which python
17/home/ag-sayyed/miniconda3/bin/python
18[Git: feat/tdd-bdd] [Python: 3.13.2] (base) ) ag-sayyed@p-3660:~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
19[Git: feat/tdd-bdd] [Python: 3.13.2] (base) ) ag-sayyed@p-3660:~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
20# Activate the newly created virtual environment
21$ source .venv/bin/activate
22(.venv) [Git: feat/tdd-bdd] [Python: 3.13.2] (base) ) ag-sayyed@p-3660:~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
23$ which python
24/home/ag-sayyed/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab/.venv/bin/python
25# Now python is used from `.venv/bin/python` which is the virtual environment
26(.venv) [Git: feat/tdd-bdd] [Python: 3.13.2] (base) ) ag-sayyed@p-3660:~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
27# you are ready to run the test.
fish shell, use conda-fish. 1~/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab
2ag-sayyed@p-3660 [Node: v24.4.0] [Git: feat/tdd-bdd]
3$ fish
4Loading custom fish configuration...
5Welcome to fish, the friendly interactive shell
6Type help for instructions on how to use fish
7⋊> ~/D/p/h/g/c/d/i/1/course-lab on feat/tdd-bdd ⨯ conda-fish 16:13:21
8in ~/.config/fish/conda-profile.fish
9
10ag-sayyed@p-3660 ~/D/p/h/g/c/d/i/1/course-lab (feat/tdd-bdd) ✗
11↪ which python
12/home/ag-sayyed/miniconda3/bin/python
13# Now activate the virtual environment using the script ending with `.fish`
14ag-sayyed@p-3660 ~/D/p/h/g/c/d/i/1/course-lab (feat/tdd-bdd) ✗
15↪ source .venv/bin/activate.fish
16(.venv)
17ag-sayyed@p-3660 ~/D/p/h/g/c/d/i/1/course-lab (feat/tdd-bdd) ✗
18↪ which python
19/home/ag-sayyed/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab/.venv/bin/python
20(.venv)
21ag-sayyed@p-3660 ~/D/p/h/g/c/d/i/1/course-lab (feat/tdd-bdd) ✗
22↪ # Now you are in the right shell and can run the tests
Unit tests are the foundation of software testing, focusing on individual components or functions. Python’s unittest module provides a framework for writing and running these tests.
unittest module is Python’s built-in test framework. To run tests, you can use the command line:unittest module (also known as PyUnit) is Python’s default test runner. You can run all tests in a folder using the command line:1python -m unittest discover
cd into the exercise folder: 1cd content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab/module-02/testing-with-nose/labs/01_running_tests_with_nose
2# Then run the test
3ag-sayyed@p-3660 ~/D/p/h/g/c/d/i/1/c/m/t/l/01_running_tests_with_nose (main) ✓
4↪ python -m unittest 15:55:02
5...........
6----------------------------------------------------------------------
7Ran 11 tests in 0.000s
8
9OK
10(.venv)
.), and failures are shown as F.While unittest is simple and effective, its reports may lack detail and visual cues.
Nose is a popular alternative to unittest, offering more detailed and colourful output. To run tests with Nose:
1nosetests
You can configure Nose to use plugins and options via a configuration file, reducing the need to specify them on the command line each time.
| Feature | unittest | Nose (with plugins) |
|---|---|---|
| Output Style | Dots and letters | Colorized, descriptive |
| Detail Level | Basic | Detailed, with docstrings |
| Code Coverage Support | Limited | Integrated with plugins |
| Missing Test Lines | Not shown | Listed in coverage report |
Nose provides a more informative and visually helpful report, making it easier to identify issues and improve code quality.
Warning
Nose is not included in the Python standard library, and does not work with Python 3.10 and later versions. It is recommended to use
pytestfor newer projects, as it offers similar features with better support and community adoption.
Nose can be configured to run code coverage analysis after tests complete. The coverage report shows:
Maintaining high code coverage is important for ensuring that new and existing code is well-tested and trustworthy.
1pip install pytest
2↪ pip list 23:01:01
3Package Version
4--------- -------
5iniconfig 2.1.0
6packaging 25.0
7pip 25.1.1
8pluggy 1.6.0
9Pygments 2.19.2
10pytest 8.4.1
11(.venv)
pytest: 1pytest test_triangle.py 23:04:05
2================================================================================= test session starts =================================================================================
3platform linux -- Python 3.13.2, pytest-8.4.1, pluggy-1.6.0
4rootdir: /home/ag-sayyed/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab/module-02/testing-with-nose/labs/01_running_tests_with_nose
5collected 11 items
6
7test_triangle.py ........... [100%]
8
9================================================================================= 11 passed in 0.01s ==================================================================================
10(.venv)
Note
Test written for nose in a file needs to adjust the import statements to work with pytest. For example, replace
import nosewithimport pytestand usepytest.approx()for floating-point comparisons.
test_float_values function to include an incorrect assertion: 1def test_float_values():
2 """Test areas when values are floats"""
3 assert pytest.approx(area_of_a_triangle(3.4556, 8.3567), rel=1e-8) == 14.43870626
4 assert area_of_a_triangle(2.3, -1) == 6.555
5↪ pytest test_triangle.py 23:09:55
6================================================================================= test session starts =================================================================================
7platform linux -- Python 3.13.2, pytest-8.4.1, pluggy-1.6.0
8rootdir: /home/ag-sayyed/Documents/projects/hbstack/ghafoors-blog/content/docs/ibm-devops-software-eng-pcert/11-tdd-bdd/course-lab/module-02/testing-with-nose/labs/01_running_tests_with_nose
9collected 11 items
10
11test_triangle.py F.......... [100%]
12
13====================================================================================== FAILURES =======================================================================================
14__________________________________________________________________________________ test_float_values __________________________________________________________________________________
15
16 def test_float_values():
17 """Test areas when values are floats"""
18 assert pytest.approx(area_of_a_triangle(3.4556, 8.3567), rel=1e-8) == 14.43870626
19> assert area_of_a_triangle(2.3, -1) == 6.555
20 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
21
22test_triangle.py:7:
23_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
24
25base = 2.3, height = -1
26
27 def area_of_a_triangle(base: float, height: float) -> float:
28 """Calculates the area of a triangle"""
29
30 # Check if we have the correct parameter types
31 if type(base) not in [int, float]:
32 raise TypeError("Base must be a number")
33 if type(height) not in [int, float]:
34 raise TypeError("Height must be a number")
35
36 # Check if we have the correct parameter values
37 if base < 0:
38 raise ValueError("Base must be a positive number")
39 if height < 0:
40> raise ValueError("Height must be a positive number")
41E ValueError: Height must be a positive number
42
43triangle.py:14: ValueError
44=============================================================================== short test summary info ===============================================================================
45FAILED test_triangle.py::test_float_values - ValueError: Height must be a positive number
46============================================================================ 1 failed, 10 passed in 0.04s =============================================================================
47(.venv)
Both unittest and Nose can run Python unit tests effectively, but Nose offers more detailed and visually appealing reports, but it would only work with python3.10. Pytest is a modern alternative that combines the best features of both frameworks, making it a popular choice for new projects.
python -m unittest discover runs all tests in the specified folder using unittest.(1) unittest provides basic output, while Nose offers colorized, descriptive reports and coverage integration.
| Feature | Description |
|---|---|
| A. Colorized Output | 1. Shows which lines of code are not covered by tests |
| B. Coverage Report | 2. Highlights passing and failing tests visually |
| C. Test Descriptions | 3. Displays docstrings for each test in the output |
A-2, B-1, C-3.
Nose can be configured to show which lines of code are missing test coverage.
True. Nose, with coverage plugins, can report missing test lines, helping developers improve code coverage.