forked from cisagov/skeleton-python-library
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_example.py
More file actions
144 lines (118 loc) · 4.57 KB
/
test_example.py
File metadata and controls
144 lines (118 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env pytest -vs
"""Tests for example."""
# Standard Python Libraries
import logging
import os
import sys
from unittest.mock import patch
# Third-Party Libraries
import pytest
# cisagov Libraries
import example
div_params = [
(1, 1, 1),
(2, 2, 1),
(0, 1, 0),
(8, 2, 4),
]
log_levels = (
"debug",
"info",
"warning",
"error",
"critical",
)
# define sources of version strings
RELEASE_TAG = os.getenv("RELEASE_TAG")
PROJECT_VERSION = example.__version__
def test_stdout_version(capsys):
"""Verify that version string sent to stdout agrees with the module version."""
with pytest.raises(SystemExit):
with patch.object(sys, "argv", ["bogus", "--version"]):
example.example.main()
captured = capsys.readouterr()
assert (
captured.out == f"{PROJECT_VERSION}\n"
), "standard output by '--version' should agree with module.__version__"
def test_running_as_module(capsys):
"""Verify that the __main__.py file loads correctly."""
with pytest.raises(SystemExit):
with patch.object(sys, "argv", ["bogus", "--version"]):
# F401 is a "Module imported but unused" warning. This import
# emulates how this project would be run as a module. The only thing
# being done by __main__ is importing the main entrypoint of the
# package and running it, so there is nothing to use from this
# import. As a result, we can safely ignore this warning.
# cisagov Libraries
import example.__main__ # noqa: F401
captured = capsys.readouterr()
assert (
captured.out == f"{PROJECT_VERSION}\n"
), "standard output by '--version' should agree with module.__version__"
@pytest.mark.skipif(
RELEASE_TAG in [None, ""], reason="this is not a release (RELEASE_TAG not set)"
)
def test_release_version():
"""Verify that release tag version agrees with the module version."""
assert (
RELEASE_TAG == f"v{PROJECT_VERSION}"
), "RELEASE_TAG does not match the project version"
@pytest.mark.parametrize("level", log_levels)
def test_log_levels(level):
"""Validate commandline log-level arguments."""
with patch.object(sys, "argv", ["bogus", f"--log-level={level}", "1", "1"]):
with patch.object(logging.root, "handlers", []):
assert (
logging.root.hasHandlers() is False
), "root logger should not have handlers yet"
return_code = None
try:
example.example.main()
except SystemExit as sys_exit:
return_code = sys_exit.code
assert return_code is None, "main() should return success"
assert (
logging.root.hasHandlers() is True
), "root logger should now have a handler"
assert (
logging.getLevelName(logging.root.getEffectiveLevel()) == level.upper()
), f"root logger level should be set to {level.upper()}"
assert return_code is None, "main() should return success"
def test_bad_log_level():
"""Validate bad log-level argument returns error."""
with patch.object(sys, "argv", ["bogus", "--log-level=emergency", "1", "1"]):
return_code = None
try:
example.example.main()
except SystemExit as sys_exit:
return_code = sys_exit.code
assert return_code == 1, "main() should exit with error"
@pytest.mark.parametrize("dividend, divisor, quotient", div_params)
def test_division(dividend, divisor, quotient):
"""Verify division results."""
result = example.example_div(dividend, divisor)
assert result == quotient, "result should equal quotient"
@pytest.mark.slow
def test_slow_division():
"""Example of using a custom marker.
This test will only be run if --runslow is passed to pytest.
Look in conftest.py to see how this is implemented.
"""
# Standard Python Libraries
import time
result = example.example_div(256, 16)
time.sleep(4)
assert result == 16, "result should equal be 16"
def test_zero_division():
"""Verify that division by zero throws the correct exception."""
with pytest.raises(ZeroDivisionError):
example.example_div(1, 0)
def test_zero_divisor_argument():
"""Verify that a divisor of zero is handled as expected."""
with patch.object(sys, "argv", ["bogus", "1", "0"]):
return_code = None
try:
example.example.main()
except SystemExit as sys_exit:
return_code = sys_exit.code
assert return_code == 1, "main() should exit with error"