Skip to content

Commit 529f059

Browse files
committed
gh-131178: Add tests for profile module command-line interface
Add a new `ProfileCLITest` class to `Lib/test/test_profile.py` with tests covering the full CLI surface of the `profile` module: - No arguments prints usage and exits with code 2 - `-h`/`--help` prints usage and exits with code 0 - Profiling a script file directly - `-m` flag to profile a library module - `-m` flag with a non-existent module (failure case) - `-o`/`--outfile` writes a valid pstats file - `-s`/`--sort` accepts a sort key without error - `-m` alone without a module name (failure case) Co-authored-by: Nityahapani <nityah@users.noreply.github.com>
1 parent b98c065 commit 529f059

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

‎Lib/test/test_profile.py‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,85 @@ def test_output_file_when_changing_directory(self):
135135
self.assertTrue(os.path.exists('out.pstats'))
136136

137137

138+
class ProfileCLITest(unittest.TestCase):
139+
"""Tests for the profile module command-line interface."""
140+
141+
def _module_name(self):
142+
return 'profile'
143+
144+
def test_no_args_prints_usage(self):
145+
# Running with no arguments should print usage and exit with code 2
146+
rc, out, err = assert_python_failure('-m', self._module_name())
147+
self.assertEqual(rc, 2)
148+
149+
def test_help(self):
150+
# -h / --help should print usage and exit with code 0
151+
rc, out, err = assert_python_ok('-m', self._module_name(), '-h')
152+
output = out.decode()
153+
self.assertIn('profile', output.lower())
154+
155+
def test_profile_script(self):
156+
# Profile a simple inline script via a temp file
157+
with temp_dir() as tmpdir:
158+
script = os.path.join(tmpdir, 'hello.py')
159+
with open(script, 'w', encoding='utf-8') as f:
160+
f.write('x = 1 + 1\n')
161+
rc, out, err = assert_python_ok(
162+
'-m', self._module_name(), script
163+
)
164+
self.assertEqual(rc, 0)
165+
166+
def test_profile_module(self):
167+
# -m flag should profile a library module
168+
rc, out, err = assert_python_ok(
169+
'-m', self._module_name(), '-m', 'timeit', '-n', '1'
170+
)
171+
self.assertEqual(rc, 0)
172+
173+
def test_profile_module_missing(self):
174+
# -m with a non-existent module should fail
175+
rc, out, err = assert_python_failure(
176+
'-m', self._module_name(), '-m', 'nonexistent_module_xyz'
177+
)
178+
self.assertNotEqual(rc, 0)
179+
180+
def test_output_file(self):
181+
# -o should write stats to a file
182+
with temp_dir() as tmpdir:
183+
outfile = os.path.join(tmpdir, 'stats.pstats')
184+
script = os.path.join(tmpdir, 'hello.py')
185+
with open(script, 'w', encoding='utf-8') as f:
186+
f.write('x = 1 + 1\n')
187+
rc, out, err = assert_python_ok(
188+
'-m', self._module_name(),
189+
'-o', outfile,
190+
script,
191+
)
192+
self.assertEqual(rc, 0)
193+
self.assertTrue(os.path.exists(outfile))
194+
# The output file should be a valid pstats file
195+
stats = pstats.Stats(outfile)
196+
self.assertIsNotNone(stats)
197+
198+
def test_sort_option(self):
199+
# -s / --sort should accept a valid sort key without error
200+
with temp_dir() as tmpdir:
201+
script = os.path.join(tmpdir, 'hello.py')
202+
with open(script, 'w', encoding='utf-8') as f:
203+
f.write('x = 1 + 1\n')
204+
rc, out, err = assert_python_ok(
205+
'-m', self._module_name(), '-s', 'cumulative', script
206+
)
207+
self.assertEqual(rc, 0)
208+
209+
def test_m_flag_requires_argument(self):
210+
# -m alone (with no module name) should fail
211+
rc, out, err = assert_python_failure(
212+
'-m', self._module_name(), '-m'
213+
)
214+
self.assertNotEqual(rc, 0)
215+
216+
138217
def regenerate_expected_output(filename, cls):
139218
filename = filename.rstrip('co')
140219
print('Regenerating %s...' % filename)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add tests for the :mod:`profile` module's command-line interface, covering
2+
``--help``, ``-s``/``--sort``, ``-o``/``--outfile``, ``-m`` (module mode),
3+
no-argument usage, and profiling a script file directly.

0 commit comments

Comments
 (0)